现在的位置: 首页 > 综合 > 正文

Windows驱动开发WDM (6)- 中断请求级别

2013年12月03日 ⁄ 综合 ⁄ 共 1466字 ⁄ 字号 评论关闭

Windows有两种中断请求(IRQ, INTERRUPT REQUEST),一种是外部中断,也就是硬件中断,另外一种是软件中断,比如常用的INT 3下个断点。

现在的x86计算机基本都是用高级可编程控制器(Advanced Programmable Interrupt Controller, 简称APIC)来控制IRQ。正在运行的线程可以随时被中断打断,进入到中断处理程序。优先级高的中断可以打断优先级低的中断处理程序,进入更高级别的中断处理函数。APIC中总共有24个IRQ。

IRQL(INTERRUPT REQUEST LEVEL)

Windows将中断的概念进行了扩展,提出一个中断请求级(IRQL)的概念。其中规定了32个中断请求级别,分别是:

0 - 2级为软件中断

3 - 31级为硬件中断(包括APIC的24个中断)

如图(图片来自于《windows驱动开发技术详解》):

                                     

Windows大部分时间都运行在软件中断级别中,即0-2级别。当有设备中断来临时,windows会将IRQL提升至硬件中断级别(DIRQL, DEVICE INTERRUPT REQUEST LEVEL),并且运行相应的硬件中断处理函数。当硬件中断结束后,恢复到原来的IRQL。

用户模式的代码是运行在最低级别的PASSIVE_LEVEL中,驱动程序的DriverEntry函数,派遣函数,AddDevice函数一般运行在PASSIVE_LEVEL中(驱动程序的StartIO和DPC函数运行在DISPATCH_LEVEL中),它们在必要的时候可以申请进入DISPATCH_LEVEL级别,使用内核函数KeGetCurrentIrql()可以知道系统的当前IRQL。

Windows负责线程调度的组件运行在DISPATCH_LEVEL级别,当前线程运行完时间片后,操作系统自动从PASSIVE_LEVEL提升至DISPATCH_LEVEL级别,从而可以使得线程调度组件可以调度其他的线程。当线程切换完成后,操作系统又从DISPATCH_LEVEL级别恢复到PASSIVE_LEVEL级别。

线程优先级

线程优先级不同于IRQL,应用程度在PASSIVE_LEVEL运行的时候,程序员可以设定线程优先级(可以使用API SetThreadPriority)。优先级高代表可以有更多机会在CPU上运行。当线程调度内核组件运行于DISPATCH_LEVEL的时候,所有应用程序的线程都停止,等着被调度。

 

IRQL和分页内存(虚拟内存)

Windows支持虚拟内存,当有需要的时候windows会将物理内存上暂时不用的数据交换到虚拟内存以腾出内存空间给其他应用使用。当应用程序需要这些数据的时候,由于这些数据不在物理内存上,那么就会产生一个页故障,页故障的异常处理函数会将虚拟内存上相关的数据交换到物理内存,这样应用程序就可以读取数据了。页故障运许出现在PASSIVE_LEVEL级别的程序中,但如果出现在DISPATCH_LEVEL或者更高级别的程序中会带来崩溃。

所以,对于高于或者等于DISPATCH_LEVEL级别的程序不能使用分页内存,必须使用非分页内存,不然就是崩溃(比如驱动程序的StartIO,DPC函数中,千万不要使用分页内存,不然就死翘翘了)。

 

控制IRQL提升和降低

通过几个内核函数可以读取,提升或者降低当前IRQL。分别是:KeGetCurrentIrql, KeRaiseIrql和KeLowerIrql。

 

 

抱歉!评论已关闭.