阅读:5648回复:15
请教IRQL_NOT_LESS_OR_EQUAL的问题
用DS写了一个PCI的驱动,可是每次进行DMA传输的时候,就会出现重启
用softice调试,显示的信息是:IRQL_NOT_LESS_OR_EQUAL 请问出现这种错误的原因一般有那些了? 我的程序基本上都是照书上例子写的,就是武安河的那本书的PCI9054的例子写的,可是运行便死机。郁闷啊,还请各位指教 |
|
|
沙发#
发布于:2005-01-27 17:24
估计是内存分配引起的,贴一些代码看看。
|
|
|
板凳#
发布于:2005-01-27 17:27
估计是内存分配引起的,贴一些代码看看。 就是运行到startmda就出问题了,这个是DMA的回调函数 VOID PCI9054Device::OnDmaReady(KDmaTransfer* pXfer, KIrp I) { // All KDmaTransfer callbacks must first check to see if there are any bytes // left to transfer. t << "Entering Pci5933Device::OnDmaReady(), " << I << EOL; if (pXfer->BytesRemaining() == 0) { // If there are no bytes left to transfer, the callback must call // Terminate(). Then it completes the IRP with STATUS_SUCCESS. pXfer->Terminate(); I.Information() = I.ReadSize(CURRENT); I.Status() = STATUS_SUCCESS; m_DriverManagedQueue.PnpNextIrp(I); m_pCurrentTransfer = NULL; delete pXfer; return; } // We must get the descriptor for the physical memory location for // the DMA transfer. PTRANSFER_DESCRIPTOR ptd; while (pXfer->SequenceTransferDescriptors(&ptd)) { // program the h/w using ppTD t << " Physical address 0x" << ptd->td_PhysAddr.LowPart << ". Length is 0x" << ptd->td_Length << "." << EOL; } // If this is the first time through, then start the DMA going. // We only want to do this ONCE for a given Read transfer. That // way, our data will be collected smoothly, without interruptions // or dropouts. if ((ULONG) pXfer->BytesRemaining() == I.ReadSize()) { m_Lock.Lock(TRUE); StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length); m_Lock.Unlock(); } return; } |
|
|
地板#
发布于:2005-01-27 18:06
会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。
|
|
|
地下室#
发布于:2005-01-28 09:41
用DS写了一个PCI的驱动,可是每次进行DMA传输的时候,就会出现重启 出现这个错误表明你在当前IRQL上调用了不能在这个IRQL上执行的内存例程以mm开头或核心例程以Ke开头等这样的东西,即CPU当前运行的IRQL与调用例程要求的IRQL不一致 |
|
|
5楼#
发布于:2005-01-28 09:45
[quote]估计是内存分配引起的,贴一些代码看看。 就是运行到startmda就出问题了,这个是DMA的回调函数 VOID PCI9054Device::OnDmaReady(KDmaTransfer* pXfer, KIrp I) { // All KDmaTransfer callbacks must first check to see if there are any bytes // left to transfer. t << "Entering Pci5933Device::OnDmaReady(), " << I << EOL; if (pXfer->BytesRemaining() == 0) { // If there are no bytes left to transfer, the callback must call // Terminate(). Then it completes the IRP with STATUS_SUCCESS. pXfer->Terminate(); I.Information() = I.ReadSize(CURRENT); I.Status() = STATUS_SUCCESS; m_DriverManagedQueue.PnpNextIrp(I); m_pCurrentTransfer = NULL; delete pXfer; return; } // We must get the descriptor for the physical memory location for // the DMA transfer. PTRANSFER_DESCRIPTOR ptd; while (pXfer->SequenceTransferDescriptors(&ptd)) { // program the h/w using ppTD t << " Physical address 0x" << ptd->td_PhysAddr.LowPart << ". Length is 0x" << ptd->td_Length << "." << EOL; } // If this is the first time through, then start the DMA going. // We only want to do this ONCE for a given Read transfer. That // way, our data will be collected smoothly, without interruptions // or dropouts. if ((ULONG) pXfer->BytesRemaining() == I.ReadSize()) { m_Lock.Lock(TRUE); StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length); m_Lock.Unlock(); } return; } [/quote] 你的代码不详细,根据你的详细代码,一个一个地查DDK手册,看他们需要的IRQL |
|
|
6楼#
发布于:2005-01-28 15:10
1.在DISPATCH_LEVEL上调用的有IRQL限制的DDK routine,有很多只能跑在<=PASSIVE_LEVEL.
2,内存分配有问题。 |
|
|
7楼#
发布于:2005-01-28 16:52
把出问题附近的整个汇编代码贴出来......
|
|
|
8楼#
发布于:2005-01-29 16:24
会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? |
|
9楼#
发布于:2005-01-30 16:33
[quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 相应的例程在确定的IRQL上运行,如果没有提升IRQL的调用,则一直在这个IRQL上运行,如果有中断来到,系统会切换到ISR中,但被中断的例程只有在系统降低到原来的IRQL上才可能继续运行。一般只要区分Passive_level、APC_level、Dispach_level、DIRQL_level就可以了。 |
|
|
10楼#
发布于:2005-02-01 11:26
[quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 也可以在SoftIce中输入?IRQL,其实就在进程控制区PCR数据结构的偏移0x24处 |
|
|
11楼#
发布于:2005-02-01 11:40
[quote][quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 也可以在SoftIce中输入?IRQL,其实就在进程控制区PCR数据结构的偏移0x24处 [/quote] 等价于在SoftIce中输入dd fs:24 |
|
|
12楼#
发布于:2005-02-03 19:46
不知道你的问题解决没有,我做FSD的时候遇到过这个错误,原因不是IRQL有问题,而是读取或写入数据的时候使用的BUFFER必须是从NON_PAGED POOL中申请的,如果你没有注意使用了PAGED POOL申请的空间,就会有这样的错误.
第一次发贴 Harmony soul |
|
13楼#
发布于:2005-02-04 10:30
[quote][quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 也可以在SoftIce中输入?IRQL,其实就在进程控制区PCR数据结构的偏移0x24处 [/quote] KeGetCurrentIrql The KeGetCurrentIrql routine returns the current IRQL. KIRQL KeGetCurrentIrql( ); Parameters None Return Value KeGetCurrentIrql returns the current IRQL. |
|
|
14楼#
发布于:2005-02-04 10:47
[quote][quote][quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 也可以在SoftIce中输入?IRQL,其实就在进程控制区PCR数据结构的偏移0x24处 [/quote] KeGetCurrentIrql The KeGetCurrentIrql routine returns the current IRQL. KIRQL KeGetCurrentIrql( ); Parameters None Return Value KeGetCurrentIrql returns the current IRQL. [/quote] 本质上内部实现就是mov eax, fs:[24h] |
|
|
15楼#
发布于:2005-02-04 11:11
[quote][quote][quote][quote]会不会是irql的问题,确认你的callback运行在哪个irql上,Dispach_level还是Passive_level,不同的irql上会有不同的限制。 请问怎么知道当前CPU运行的IRQL? [/quote] 也可以在SoftIce中输入?IRQL,其实就在进程控制区PCR数据结构的偏移0x24处 [/quote] KeGetCurrentIrql The KeGetCurrentIrql routine returns the current IRQL. KIRQL KeGetCurrentIrql( ); Parameters None Return Value KeGetCurrentIrql returns the current IRQL. [/quote] 本质上内部实现就是mov eax, fs:[24h] [/quote] 具体代码是这样的: mov eax,[fffe0080] shr eax,04 movzx eax,byte ptr [eax+_HalpVectorToIRQL] ret 都在PCR区,以_HalpVectorToIRQL作索引找, 与fs:[24h]物理地址是一样的,只是这种方法太不正规了 |
|
|