最近在编写内核驱动时出现因缺页中断被屏蔽而导致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         §
                                            --------------

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

  1. 驱动相关的内核函数分析

    目录: 字符设备驱动程序对一些高级特性的实现 nonseekable_open; scull_p_poll Linux内核中获取当前时间 do_gettimeofday 用户空间和内核空间传递数据:g ...

  2. linux路由相关函数,Linux 路由 学习笔记 之十一 输入、输出路由查找相关的接口函数...

    对于路由功能模块的学习,也已经很长时间了.关于路由项的创建与查找.策略规则相关的创建与查找.路由缓存的创建与查找,都是分开来分析的,没有说明这些模块是如何配合使用的,以及模块之间的联系.本节就分析一下 ...

  3. Windows驱动编程基础教程 (转)

     Windows驱动编程基础教程(转) 我经常在网上遇到心如火燎的提问者.他们碰到很多工作中的技术问题,是关于驱动开发的.其实绝大部分他们碰到的"巨大困难"是被老牛们看成初级得 ...

  4. Linux设备驱动编程第三版-笔记

    第1章 设备驱动简介 1.1 驱动程序的角色 机制:提供什么能力. 策略:如何使用这些能力. 1.2. 划分内核 内核的角色可以划分:     一:进程管理 二:内存管理 三:文件系统 四:设备控制 ...

  5. 我的内核学习笔记6:PCI驱动probe的一点认知

    对于PCI的学习,在文章<初识PCI>和<再识PCI:一个PCI驱动实例>中有介绍,文中使用大量代码进行演示.但总觉得有些认知不到位.于是就再写一文. 一.PCI驱动一般框架 ...

  6. linux设备驱动读书笔记

    linux设备驱动读书笔记 设备驱动简介 机制:提供什么能力 策略:如何使用这些能力 在编写驱动时, 程序员应当编写内核代码来存取硬件, 但是不能强加特别的策略给用户, 因为不同的用户有不同的需求. ...

  7. 驱动学习笔记 IRP

    在学习内核过滤驱动的过程中,遇到了大量的涉及IRP操作的代码,这里有必要对IRP的数据结构和与之相关的API函数做一下笔记. 1. 相关阅读资料 <深入解析 windows 操作系统(第4版,中 ...

  8. linux设备驱动读书笔记(转)

    linux设备驱动读书笔记 设备驱动简介 机制:提供什么能力 策略:如何使用这些能力 在编写驱动时, 程序员应当编写内核代码来存取硬件, 但是不能强加特别的策略给用户, 因为不同的用户有不同的需求. ...

  9. [内核编程] 内核环境及其特殊性,驱动编程基础篇

    [内核编程] 内核环境及其特殊性,驱动编程基础篇  在学习汉江独钓一书后,打算总结一下内核编程应该注意的事项,以及有关的一些基础知识.第一次接触内核编程,还真是很生疏,很多东西不能一下马上消化.这里做 ...

  10. 再识PCI:一个PCI驱动实例

    之前写了第一篇关于PCI的文章,当时只是作为入门的接触笔记,后来对PCI又研究了一下,主要包括PCI设备的扫描过程及PCI驱动注册过程. 本文主要给出一个PCI实例,并在内核中做很多的打印以便跟踪其过 ...

最新文章

  1. SQL Server密码爆破工具SQLdict
  2. 【xml】利用OpenCV解析
  3. Linux——Centos7网络配置1ens33文件
  4. relu函数为分段线性函数,为什么会增加非线性元素
  5. 【实验4】——互谱法测向
  6. ios 图片裁剪框架_iOS 图片裁剪与修改
  7. 洛谷2543AHOI2005]航线规划 (树剖+线段树+割边思路)
  8. Delphi 与 DirectX 之 DelphiX(3): 初识 TDXDraw
  9. 记一次Pr安装转场插件导致AE报错问题解决
  10. 职场泥潭,这样的IT公司绝对不宜久留
  11. signature=45f2913b66c5b2ae668a6622be005d65,国开大《商务英语4》自测试题及答案
  12. 【转】精彩RSS源推荐
  13. 奇安信技术总监熬夜总结,全网最全内网渗透姿势!
  14. 黑苹果注入显示器EDID解决部分核显独显黑屏花屏颜色不对等一系列问题
  15. 第一次作业:调查市场软件
  16. 华为服务体系:ITR流程体系详解
  17. umi首屏加载速度优化
  18. java datetime转int_java日期int和String互转
  19. android gone动画_java – Android添加简单的动画,而setvisibility(view.Gone)
  20. 微信小程序里面的标签和html标签做对比

热门文章

  1. RTI DDS windows环境下的下载和安装
  2. 邮箱用户计算机名格式,电子邮箱怎么写 用什么格式
  3. 知道一个公司的网站地址,怎么快速获取邮箱。
  4. 微信小程序加载圆形图片
  5. python人物关系抽取_Python学习笔记(2) Python提取《釜山行》人物关系
  6. 在北大国家发展研究院发言
  7. 推荐几款网盘资源搜索站点,必须收藏 !
  8. 程序员常用单词词汇汇总
  9. UVA 1449 Dominating Patterns
  10. 谷歌浏览器Google Chrome如何在打开新标签页时设置指定网址