IRQL 中断请求级别

什么是IRQL?

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

我们经常遇见的有四种IRQL级别。“Passive”, “APC”, “Dispatch” and “DIRQL”. 

“DriverEntry”将会在PASSIVE_LEVEL被调用。

 

#define PASSIVE_LEVEL                             0

#define LOW_LEVEL                                 0

#define APC_LEVEL                                  1

#define DISPATCH_LEVEL                           2

#define PROFILE_LEVEL                             27

#define CLOCK1_LEVEL                             28

#define CLOCK2_LEVEL                             28

#define IPI_LEVEL                                   29

#define POWER_LEVEL                             30

#define HIGH_LEVEL                                31

 

 

 

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的最高等级。通常使用这个来判断设备的优先级。

一般的,更高级的驱动在这个级别上不处理IRQL,但是几乎所有的中断被屏蔽,这实际上是IRQL的一个范围,这是一个决定某个驱动有更高的优先级的方法。

 

1.3.1 内核代码运行级别

Windows NT为它的内核模式的代码分配了不同的级别。在同一个CPU上,级别低的过程 

可以被任何级别更大的过程中断。级别由低到高排列如下:

级别名称 运行于该级别的过程

PASSIVE_LEVEL DriverEntry, Unload, ShutDown, DispatchXxx。

APC_LEVEL 在某些特殊情况下,大存储量设备的驱动程序运行于该级别。

DISPATCH_LEVEL StartIo, AdapterControl, ControllerControl, IoTimer,Dpc。

DIRQLs 各种中断处理程序。

表16.1 驱动程序例程的缺省IRQL

IRQL(由低到高) 屏蔽掉的中断  运行在此IRQL的支持例程

PASSIVE_LEVEL    无         Dispatch、DriverEntry、AddDevice、Reinitialize、Unload例程、驱动程序创建的线程、工作者线程(work-thread)回调、文件系统驱动程序

DISPATCH_LEVEL   DISPATCH_LEVEL和APC_LEVEL中断被屏蔽掉了。设备、时钟和电源错误中断仍可发生 

StartIo、AdapterControl、AdapterListControl、ControllerControl、IoTimer、Cancel(持有撤消自旋锁时)、DpcForIsr、CustomTimerDpc、CustomDpc例程

DIRQL  驱动程序中断对象中所有IRQL<=DIRQL的中断。时钟和电源错误中断仍可发生 ISR、SyncCritSection例程

  对于高层驱动程序可能需要一个或多个IoCompletion例程,最起码完成检查I/O状态块然后调用IoCompleteRequest的工作。如果需要,还要对Device Extension数据结构和内容做些修改。有一点必须很清楚的,就是代码运行级别的问题,即IRQL,最常见的级别是PASSIVE_LEVEL、APC_LEVEL、DISPATCH_LEVEL和DIRQL。

 

  在看NT DDK HELP中的函数说明的时候,要注意函数的可运行级别,比如有的函数只能在PASSIVE_LEVEL下运行,有的函数则可以在DISPATCH_LEVEL以下级别运行,级别越高的时候,对代码的要求就越严格,比如在DISPATCH_LEVEL的时候,就不能使用分页内存。通常情况下应该尽可能让代码在低运行级别如PASSIVE_LEVEL下运行,在高级别下运行过长时间将导致系统效率降低、影响系统响应的实时性。但有时候自己无法控制运行的级别,例如在调用低层Driver时使用IoCallDriver,低层Driver响应完毕后会执行completion例程,该例程运行的级别就是由低层Driver来决定。因此在编写completion例程时,应尽量将这个函数设计成能在DISPATCH_LEVEL级别运行。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值