【原创】浅说windows下的中断请求级IRQL

一 中断分类


根据中断源不同,可以将中断分为

  • 硬件中断:硬件上产生的中断,可以来自处理器的内部和外部。处理器的外部中断可以来自各种PIN信号接口和Local APIC的LINT0和LINT1引脚,以及外部的I/O APIC发送过来的中断信息。
  • 软件中断:软件上产生的中断,使用INT指令主动发起的中断,如INT 0X40,调用0X40号的中断服务例程。

硬件中断源又可以分为

  • 可屏蔽中断:可屏蔽的中断如下
  1. 通过处理器的INTR pin接收的中断请求,典型地,INTR连接到8259A PIC上,在支持APIC的处理器上,LINT0被作为INTR连接到外部中断控制器上
  2. 通过Local APIC产生的本地中断源
  3. 来自芯片组上的I/O APIC产生的中断信息
  • 不可屏蔽中断:通过处理器NMI pin接收的中断请求是不可屏蔽的,在支持APIC的处理器上INTR1 pin被作为NMI pin使用,接收来自外部的NMI信号

二 中断控制器


  • 以前的8259A PIC(8259可编程中断控制器)

在单处理器上,处理器的INTR pin接收来自外部8259中断控制器传送过来的中断请求,其位于PCI-to-ISA bridge(南桥)芯片的LPC控制器里。

每个8259A PIC的IR口都连接着一条IRQ线。主片的IR0到IR7对应着IRQ0到IRQ7线,但是IR2连接着从片的INTR pin。从片的IR0到IR7对应着IRQ8到IRQ15线。由于从片连接到主片的IR2上,所以从片的IR1同时连接到IRQ2和IRQ9。

在8259A中,主片IR0的中断请求优先级最高,主片IR7最低,从片IR0-7所有中断请求优先级都相当于IRQ2。所以IRQ线的优先级由高到低次序为IRQ0,IRQ1,IRQ8-15,IRQ3-7。

  • 现在的中断控制器:APIC

为了适应多处理器,Intel在Pentium处理器开始引入了APIC(Advanced Programmable Interupt Controller)机制。

APIC经历了4个版本,82489DX芯片,APIC,xAPIC,x2APIC。xAPIC共有256个IRQ线,而x2APIC比xAPIC多了256个,总共512条IRQ线。

三 中断请求级IRQL



在APCI中,每个IRQ都有各自的优先级,一个正在运行的线程可能被中断打断,进入到中断处理函数,当遇到优先级更高的中断,处在低优先级的中断也会被打断,进入到更高级的中断处理函数。

windows将中断的概念进行了扩展,提出了中断请求级的概念,数字低的优先级高,其中不仅包括了APIC的所有中断,也包括了3个软件中断

用户模式的代码运行在最低优先级PASSIVE_LEVEL。驱动中的DriverEntry,派遣函数,AddDevice等函数一般运行在PASSIVE_LEVEL,在必要的时候可申请进入DISPATCH_LEVEL函数。

需要特别注意的是,windows负责线程调度的组件是运行在DISPATCH_LEVEL级别,当前的线程运行完时间片后,系统自动从PASSIVE_LEVEL级别提升到DISPATCH_LEVEL级别。当线程切换完毕后,操作系统又从DISPATCH_LEVEL降到PASSIVE_LEVEL。驱动程序的StartIO函数和DPC函数也运行在DISPATCH_LEVEL级别。在内核模式,可以通过KeGetCurrentIrpl内核函数来得到当前的IRQL级别。

四 代码中断级



PASSIVE_LEVEL比DISPATCH_LEVEL低,在实际编程中,许多具有比较复杂功能的内核API都要求在PASSIVE下运行,而只有比较简单的API能在DISPATCH级执行。

在调用任何一个内核API前,必须查看WDK文档,了解这个内核API的中断要求

中断级的简单判断方法

如何判断我们正在编写的代码的中断级呢?暂时可以使用下面规则来处理。

  • 规则1:如果在调用路径没有特殊情况(导致中断级的提高或降低),则一个函数的中断级与调用源的中断级相同;
  • 规则2:如果在调用路径上有获取自旋锁,则中断级随之升高;如果有释放自旋锁,则中断级随之降低。

如果当前代码运行在DISPATCH级,而我们又必须调用PASSIVE级的内核API,使用内核API强制降低当前的中断请求级是不被允许的,windows的代码都运行在规范的中断级上,任意降低中断级都会导致不可预料的后果。
这样的问题有很多种解决方法,比如生成一个专门的线程去执行PASSIVE级的代码。

本文链接:http://www.cnblogs.com/cposture/p/4782880.html

时间: 2024-10-05 03:16:54

【原创】浅说windows下的中断请求级IRQL的相关文章

windows下实现微秒级的延时

1.微秒级的延时肯定不能基于消息(SetTimer函数),因为一出现消息堵塞等就会影响精度,而且setTimer单位才是毫秒.实际响应时间可能要到55毫秒左右. 2.微秒级的延时也不能不能基于中断,VxD最快的时钟服务程序Set_Global_Time_Out函数才能保证1毫秒的精度.其他挂接int 8H中断处理函数等,只能保证55ms的精度.(有时还不能) 3.因此可以想到汇编下的那种基于循环执行语句的那种延时.但汇编那种代码不通用,跟cpu的频率有关. 所以可以用windows下的几个函数来

(原创)Windows下编译的Shell脚本不能再Linux中运行的解决办法

一.原理 Windows编译的文件和Linux编译的文件格式不太一样,导致在Linux运行Shell脚本的时候会提示:/bin/bash^M: bad interpreter: 没有那个文件或目录. 原因是这样的: 1.Windows编译的文件结束时(回车+换行) 2.Linux编译的文件结束时(换行)             这样导致了Windows编译的文件放在Linux中会有[noeol]和[dos]的Flag标示. 如果运行CAT命令可以更直观的看到两个不同操作系统产生的文件差异,Win

在Windows及Linux下获取毫秒级运行时间的方法

在Windows下获取毫秒级运行时间的方法 头文件:<Windows.h> 函数原型: /*获取时钟频率,保存在结构LARGE_INTEGER中***/ WINBASEAPI BOOL WINAPI QueryPerformanceFrequency( _Out_ LARGE_INTEGER * lpFrequency ); /*获取从某个时间点开始的时钟周期数,保存在结构LARGE_INTEGER中**/ WINBASEAPI BOOL WINAPI QueryPerformanceFreq

[转载]Windows下的分页模式- 页目录和页表从物理内存到虚拟映射求值

标 题: [原创]Windows下的分页模式-  页目录和页表从物理内存到虚拟映射求值 作 者: hrpirip 时 间: 2012-12-06,12:45:36 链 接: http://bbs.pediy.com/showthread.php?t=159554 昨天在网上看到一段代码令大为不解,大家都知道一个虚拟地址到物理地址的转换伪公式为:*(*(*PD[(VirtualAddress>>22)] & FFFFF000) [(VirtualAddress & 3FF000)

windows下基于(QPC)实现的微秒级延时

1.为什么会写windows下微秒级延时 在上一篇 实现memcpy()函数及过程总结 中测试memcpy的效率中,测试时间的拷贝效率在微秒级别,需要使用微秒级时间间隔计数. windows下提供QueryPerformanceCounter(查询高性能计数器),QPC是基于硬件计数器,获取高分辨率时间戳. 参考:Acquiring high-resolution time stamps 应用形式: 1 LARGE_INTEGER start, end; 2 LARGE_INTEGER Freq

[原创] Windows下Eclipse连接hadoop

1 下载hadoop-eclipse-plugin :我用的是hadoop-eclipse-plugin1.2.1 ,百度自行下载 2 配置插件:将下载的插件解压,把插件放到..\eclipse\plugins目录下 3重启eclipse,配置Hadoop installation directory 打开Windows—Preferences后,在窗口左侧会有Hadoop Map/Reduce选项,点击此选项,在窗口右侧设置Hadoop安装路径.(windows下只需把hadoop-1.2.1

【原创】Superset在windows下的安装配置

Superset是由Airbnb(知名在线房屋短租公司)开源BI数据分析与可视化平台(曾用名Caravel.Panoramix),该工具主要特点是可自助分析.自定义仪表盘.分析结果可视化(导出).用户/角色权限控制,还集成了一个SQL编辑器,可以进行SQL编辑查询等,原来是用于支持Druid的可视化分析,后面发展为支持很多种关系数据库及大数据计算框架,如:mysql, oracle, Postgres,Presto,sqlite, Redshift,Impala, SparkSQL, Green

[原创]Windows下更改特定后缀名以及特定URL前缀的默认打开程序

Windows下,特定后缀名的文件会由特定的应用程序来运行,比如双击readme.txt,通常情况下会由Windows自带的notepad.exe(记事本)打开文件.如果现在安装了记事本以外的其他文本阅读器比如Vim或者UltraEdit,并且我想以后每次双击这个readme.txt文件时都由Vim来阅读,可以参考本文档中的步骤. 同样的,在Windows下,特定前缀的URL也会由不同的应用程序来打开,比如在我的计算机上,以mailto:开头的URL会启动Outlook,并根据URL中的其他信息

在windows下安装OpenDaylight的Helium(氦)版本

前言 OpenDaylight(以下简写为ODL)的Helium(氦)版本已经成为相对稳定的版本(相对于Li版本).Helium(氦)版本下载链接地址为http://www.opendaylight.org/software/downloads/helium.官网中分别共享了版本.安装向导.用户向导.开发者向导手册,可进行下载学习.在本篇文章中,着重讲一下在Windows下的安装过程. 1 Helium安装 虽然官方要求ODL Helium(氦)版本是基于Ubuntu的,但是在实际学习过程中,U