PAGED_CODE

PAGED_CODE()是DDK提供的宏,它会检验当前程序的IRQL。

如果IRQL >= DISPATCH_LEVEL, PAGED_CODE()会导致系统断言。

IRQ 和 IRQL

中断请求(IRQ)分为硬件中断(外部中断)和软件中断(内部中断,int n指令产生的中断)。

硬件中断分为不可屏蔽中断(NMI)和可屏蔽中断(INTR),其中,可屏蔽中断是通过可编程中断控制器(PIC)8259A芯片向CPU发出请求的。

高级可编程控制器(APIC)定义的IRQ的数量有24个。

每个IRQ都有自己的IRQL(中断请求级别),正在运行的线程随时可以被中断打断,进入到中断处理程序。而当优先级高的中断来临时,处在优先级低的中断处理程序也会被打断,进入到更高级别的中断处理函数。

Windows规定了32个IRQL,
0-2 级为软件中断
3-31 级为硬件中断,其中3-26为APIC中的24个硬件中断

硬件的IRQL称为设备中断请求级(DIRQL)

当硬件中断来临的时候,操作系统提升IRQL到DIRQL级别,并且运行中断处理函数。中断处理函数结束后,操作系统把IRQL降到原来的级别。

#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
#define SYNCH_LEVEL (IPI_LEVEL-1)
注意:
  1. 用户模式的代码(Ring3)一般都运行在PASSIVE_LEVEL

  2. 驱动程序的DriverEntry、IRP派遣函数一般都运行在PASSIVE_LEVEL,可以在必要时申请进入DISPATCH_LEVEL

  3. Windows负责线程调度的组件运行在DISPATCH_LEVEL,当前线程运行完时间片后,系统自动从PASSIVE_LEVEL提升到DISPATCH_LEVEL,当线程切换完毕后,系统又从DISPATCH_LEVEL回到PASSIVE_LEVEL。

  4. IRQL和线程优先级不一样,线程优先级只针对应用程序而言,线程优先级高的线程有更多机会被内核调度。

相关函数:
// 获得当前的IRQL级别
KIRQL
KeGetCurrentIrql(VOID)
{return KeGetPcr()->Irql;
}
PKPCR
KeGetPcr(VOID)
{return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self));
}// 提高IRQL
VOID
KeRaiseIrql(IN KIRQL NewIrql, OUT PKIRQL OldIrql
);
// 恢复IRQL
VOID
KeLowerIrql(IN KIRQL NewIrql
);例如:
KIRQL OldIrql;
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeLowerIrql(OldIrql);

分页内存

再不得不提一下分页内存。

使用分页内存可能会导致页故障,因为分页内存随时可能从物理内存交换到磁盘文件。读取不在物理内存中的分页内存时,就会引发页故障,从而执行对应的异常处理函数,异常处理函数会重新将磁盘文件的内容交换到物理内存中。

页故障在IRQL >= DISPATCH_LEVEL的程序中会导致系统崩溃(蓝屏死机)。

因此,IRQL >= DISPATCH_LEVEL的程序中不允许使用分页内存

驱动开发笔记2—PAGED_CODE(),IRQL,分页内存相关推荐

  1. 驱动开发:内核R3与R0内存映射拷贝

    在上一篇博文<驱动开发:内核通过PEB得到进程参数>中我们通过使用KeStackAttachProcess附加进程的方式得到了该进程的PEB结构信息,本篇文章同样需要使用进程附加功能,但这 ...

  2. 设备文件BSP及嵌入式驱动开发笔记

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! BSP及嵌入式驱动开辟笔记 第一讲嵌入式系统基本概念 以应用为中央,以计算机 ...

  3. 嵌入式底层驱动开发笔记1

    一.开发板 1\ bootloader的工作原理及作用? Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段 bootloader程序.这段bootload ...

  4. 驱动开发:内核CR3切换读写内存

    首先CR3是什么,CR3是一个寄存器,该寄存器内保存有页目录表物理地址(PDBR地址),其实CR3内部存放的就是页目录表的内存基地址,运用CR3切换可实现对特定进程内存地址的强制读写操作,此类读写属于 ...

  5. Linux nor flash分区,Linux驱动开发笔记:NOR FLASH编写实例

    1. 背景介绍 板子上的zynq通过emc外接一块nor flash,地址分配如下: Nor flash的起始地址为0x80000000.当zynq上运行Linux后可以通过对该地址起始的区域进行擦除 ...

  6. 迅为嵌入式linux驱动开发笔记(十一)—触摸屏驱动

    总结篇 这一小节内容是对之前学习的十节课进行总复习,综合性非常强,完成触摸屏驱动需要学会如下知识: 1.驱动开发原理 第一节 2.platform平台总线模型 第三节 3.设备树 第四节 4.gpio ...

  7. 嵌入式Linux驱动开发笔记(未完待续。。。)

    零.嵌入式Linux驱动编程思想 1.面向对象(把一个事件抽象成一个结构体) 2.分层 3.分离 一.Git仓库用法 1.linu终端输入下面命令安装 git clone https://e.codi ...

  8. ip核在linux的驱动,Linux驱动开发笔记:对zynq PL部分IP核的驱动开发过程

    reg_addr = (((hopcount+1) #include * Xilinx RapidIO 3. 驱动设计 } #include Amba_pl对应PL部分的amba,devicetree ...

  9. linux驱动开发笔记 一 基本流程

    linux驱动开发, 有特定的模式, 在我看来linux驱动只做了一件事, 将设备统一转换成了统一的3类虚拟设备 分别是: 1. 字符设备 2. 块设备 3. 网络设备 linux驱动开发, 需要在U ...

  10. Linux设备驱动开发笔记

    0 Linux 操作系统知识 Linux是一个操作系统. 优点: 免费: 丰富的文档和社区支持: 跨平台移植: 源代码开放: 有许多免费开源软件. 家用电脑用Windows,服务器端用Linux. 操 ...

最新文章

  1. OPPO海外官方调试ID
  2. 深度学习在目标视觉检测中的应用进展与展望
  3. 记一次数据库事务的并发同步控制
  4. 大道至简:软件工程实践者的思想——第七、八章感想
  5. svn中出现红色感叹号
  6. 1.java局部变量 实例变量 类变量(静态变量)
  7. 浪潮服务器测试文档,ESXI6.7注入浪潮服务器raid驱动测试
  8. 后缀自动机(SAM)构造实现过程演示+习题集锦
  9. java 队列复制_复制一个文件夹里的文件到另一个目录下 (使用队列的方法实现)...
  10. android将activity打成jar包供第三方调用,把Activity打包成jar供其App使用
  11. 【VRP】基于matlab改进的模拟退火和遗传算法求解车辆路径规划问题【含Matlab源码 343期】
  12. JLink.exe JFlash.exe batch文件一键下载
  13. c语言messagebox多窗口,C语言messagebox用法
  14. Java 编程实例 - 查找数组中的重复元素
  15. 《路由器开发 - 路由器刷机指南》小米MINI刷机
  16. 千挑万选, 终于确定了
  17. 【C++ 程序】 TVJ Complex Calculator (v 2.2) 复数计算器
  18. 算术表达式求值(C语言栈)
  19. antd table 超出显示省略号无效果
  20. C++学习笔记day3

热门文章

  1. win10 虚拟机如何连网
  2. 编程:Python实现图片识别
  3. 回顾来路,不忘初心;心之所向,砥砺前行
  4. ArcMap进行标记符号制作
  5. 单片机控制舵机及步进电机
  6. 笔记本电脑触控板操作技巧
  7. win10cmd重置系统_win10命令行恢复出厂设置
  8. 分享:无版权图片素材免费下载网站
  9. 自动驾驶公司如何打造产品市场体系
  10. React Native 微博登陆