DM642的PCI驱动编程笔记:缺页中断问题阐述以及与改变中断级相关的内核函数

    最近在编写内核驱动时出现因缺页中断被屏蔽而导致CPU占用100%,不得不重启的现象。
    SoftICE中显示的信息是:Break due to Page Fault(0Eh)...Fault=0000
    现在基本搞清了这件事情。简要陈述之并介绍几个和改变中断级有关的内核函数给大家。
    缺页中断,是指若要访问的单元不在内存中时,需要临时从硬盘调入一页放入内存。这种中断由于是磁盘中断,因此运行的中断级按道理说应该是DIRQL硬件中断级,但是由于这件事情呢,是归IO管理器统一管理的,所以实际上属于软中断,是属于DISPATCH_LEVEL中断级的。因此如果访问内存的代码运行在同一中断级或更高中断级上的话,缺页中断就会遭到屏蔽。也就是说我们要读数据,数据现在在硬盘上,但是我们不让CPU去硬盘上取数据,没有数据,我们又必须等着数据,因此就成为一种死循环。
    解决问题的办法之一是想办法在我们读数据时保证数据在内存中,这也是WDM给我们提供的主要思路,就是申请非分页内存(non paged memory)。这样在我们读数据期间就不用跨页,也就不会产生缺页中断,一直有数据,也就不会出现死循环等待了。
    另一个思路是尽量在低中断级上读数据,这样即使产生缺页中断我们可以等把磁盘上的数据取出来以后继续读,但是在驱动编程的很多场合下还是要在大于或等于DISPATCH_LEVEL中断级上读数据的。所以在WDM编程中有一个不成文的规定,那就是在DISPATCH_LEVEL中断级以上必须访问非分页内存。
    结论是,尽量使用两种思路的结合,也就是说在中断级较低且不太要求读取速度的场合下最好用第二种方法,毕竟非分页内存比较少,属于稀缺资源。如果必须要在高中断级上读,那就用非分页内存。
    下面介绍三个和中断级有关的内核函数(在MSDN中能找到):

一、KeRaiseIrql 这个函数把硬件中断级提升到一个指定的IRQL值,因此来屏蔽那些对当前处理器的相等或较低中断级上的中断。
【函数原型】
VOID KeRaiseIrql(
    KIRQL  NewIrql,     //输入参数,用于指定要提升到的中断级,
    PKIRQL  OldIrql     //输出参数,用于记录原来的中断级,以便恢复
    );
二、KeLowerIrql这个函数把硬件中断级恢复到原来的IRQL值。
【函数原型】
VOID KeLowerIrql(
    IN KIRQL  NewIrql   //输入参数,应该是KeRaiseIrql函数的输出参数,用来恢复到原来的中断级,而不能是一个新的值
    );
三、KeGetCurrentIrql 这个函数用来获取当前的IRQL值
【函数原型】
KIRQL KeGetCurrentIrql();

注意:1、调用这几个函数需要包含wdm.h 或 ntddk.h文件,开发驱动的一般都会包含它们。
      2、对于前两个函数,只有当NewIrql>=CurrentIrql才能成功调用KeRaiseIrql,只有当NewIrql<=CurrentIrql才能成功调用KeLowerIrql。而且KeLowerIrql的参数必须是先前调用KeRaiseIrql是返回的输出参数,也就是说这两个内核函数一般是成对出现的。
      3、本质上,这种参数规定决定了我们只能提升中断级,而不能任意降低中断级,这也是一个合理的要求,因为大部分高中断级并不能用代码来降低,它们是由内核的规则规定了的。

 

                                            --------------
                                            §  李文凯 2008年03月30日 §
                                            §   作于WHHIT之IMLAB         §
                                            -------------- 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值