windows内核开发笔记十一:IRQL级别调用说明

windows内核开发笔记十一:IRQL级别调用说明

IRQL是Interrupt ReQuest Level,中断请求级别。处理器在一个IRQL上执行线程代码。IRQL是帮助决定线程如何被中断的。在同一处理器上,线程只能被更高级别IRQL的线程能中断。每个处理器都有自己的中断IRQL。

windows内核开发笔记十一:IRQL级别调用说明_第1张图片

常见的IRQL级别有四个:Passive、APC、 Dispatch、DIRQL。

  • PASSIVE_LEVEL

IRQL最低级别,没有被屏蔽的中断,线程执行用户模式,可以访问分页内存。

  • APC_LEVEL

只有APC级别的中断被屏蔽,可以访问分页内存。当有APC发生时,处理器提升到APC级别,这样,就屏蔽掉其它APC,为了和APC执行 一些同步,驱动程序可以手动提升到这个级别。比如,如果提升到这个级别,APC就不能调用。在这个级别,APC被禁止了,导致禁止一些I/O完成APC, 所以有一些API不能调用。

  • DISPATCH_LEVEL

DPC(延迟过程) 和更低的中断被屏蔽,不能访问分页内存,所有的被访问的内存不能分页。因为只能处理分页内存,所以在这个级别,能够访问的API大大减少。

  • DIRQL (Device IRQL)

通常处于高层次的驱动程序不会使用这个IRQL等级,在这个等级上所有的中断都会被忽略。这是IRQL的最高等级,通常使用这个来判断设备的优先级。

    在内核模式下,可以通过内核函数 KeGetCurrentIrql(),来获得当前的中断等级。可以通过调用KeLowerIrql与KeRaiseIrql来降低和升级等级。可以先提升IRQL,然后恢复(下降)到原有IRQL;不能单独调用KeLowerIrql来降低IRQL;调用了KeRaiseIrql后必须调用KeLowerIrql恢复原有IRQL。

void RasieIRQL_Test()

{

    KIRQL oldIrql;

    //确保当前IRQL等于或小于DISPATCH_LEVEL

     ASSERT(KeGetCurrentIrql()<= DISPATCH_LEVEL);

     //提升IRQL至DISPATCH_LEVEL,并将先前的IRQL保存

     KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);

     //...

     //恢复到先前的IRQL

     KeLowerIrql(oldIrql);

}

你可能感兴趣的:(系统内核,操作系统,windows内核,内核,操作系统,驱动程序,VC,C++/C)