• 【原创】浅说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

    每个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线。


    APIC

    三 中断请求级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

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    初识面向对象编程(Object Oriented Programming,OOP)
    详述WebLogic反序列化远程命令执行漏洞的处理过程,云和恩墨技术通讯精选
    分布式监控系统zipkin介绍
    Uncaught TypeError: Cannot set property 'render' of undefined
    python PIL的Image.resize()和Image.thumbnail()函数的区别
    dump 组合索引存储null值
    史上最全MySQL锁机制
    Dump 组合索引
  • 原文地址:https://www.cnblogs.com/cposture/p/interupt.html
Copyright © 2020-2023  润新知