当前位置:首页 > Windows程序 > 正文

Windows中断那些事儿

2021-03-19 Windows程序

APC、DPC、IRQL

一直以来对中断这一部分内容弄的一知半解,操作系统和CPU之间如何协同工作也是很模糊。最近花了点时间认真把这块知识进行了梳理,不当之处,还请高手指出,先行谢过了!

本文旨在解答下面这些问题:

  1.IRQ和IRQL之间是什么关系?

  2.Windows是如何在软件层面上虚拟出IRQL这套中断机制的

  3.APC和DPC都是软件中断,既然是中断那么对应的IDT表项中的处理例程在哪里呢?

0x00 Intel 80386处理器的中断

  首先,让我们忘记Windows,从最开始的80386处理器开始,看看Intel设计它的时候是如何处理中断这个东西的。

先来看看这个诞生于1985年的CPU长什么样子:

  看看那些伸出来的引脚,下面是它的引脚标注图:

  注意用红圈标注的两个引脚,这两个就是80386处理器为中断留出的两个引脚。其中INTR是可屏蔽中断输入口,NMI是不可屏蔽中断输入口。

那么中断是如何输入给处理器的呢?那么多外部设备,而这只有一个引脚(暂时只考虑可屏蔽中断),这里就需要为CPU配备一个管理中断的秘书——可编程中断控制器PIC。这个秘书需要干哪些活呢?外部设备的中断都从它来进入中央处理器,所以它负责从外设接收中断信号,并根据优先级向CPU发起中断请求。最开始的这个PIC角色是一个代号为8259A的芯片在进行扮演,这货长这样:

 

  下面是它的引脚图:

 

  其中IR0-IR7共8个引脚负责连接外部设备, 8259A PIC的每个IR口都连接着一条IRQ线,用于接收外设的中断信号。INT负责连接CPU的INTR引脚,用于向CPU发起中断请求。通常情况下,使用两片8259A芯片进行级联,一片连接CPU,称为主片,另一片连接到主PIC的IR2引脚,称为从片,这样总共就可以连接8+7=15个外设了。如下图所示:

  在8259A中,默认情况下的优先级是主片IR0的中断请求优先级最高,主片IR7最低,从片IR0-7所有中断请求优先级都相当于IR2。所以IRQ线的优先级由高到低次序为IRQ0,IRQ1,IRQ8-15,IRQ3-7。这是默认情况,可以通过编程改变。

  在8259a芯片内部有几个重要的寄存器:

  中断请求寄存器: IRR,8bit,对应IR0-IR7,当对应引脚产生中断信号时,该bit位置1。

  中断服务寄存器: ISR,8bit,对应IR0-IR7,当对应引脚的中断正在被CPU处理时,该bit位置1。

  中断屏蔽寄存器: IMR,8bit,对应IR0-IR7,当对应位为1时,表示屏蔽该引脚产生的中断信号。

  还有一个中断优先级判决器: PR,当中断引脚有信号时,结合这次产生中断的IRQ号和ISR中记录的当前正在处理的中断信息,根据优先级来决定是否把这个新的中断信号报告给CPU,以此来产生中断嵌套。

下面是这15条IRQ线分别连接的外设:

  现在我们来看看这个秘书是如何和CPU之间进行协调工作的。

  现在假设我们敲击了一个键盘按键,键盘有中断事件产生,这一事件通过IRQ1这根线告知了主PIC,主PIC经过内部一些判断处理后通过INT发送电信号到CPU侧的INTR。CPU在执行完当前的指令后,检查到INTR有信号,,说明有中断请求来了,再检查eflags中的IF不为零,表示当前允许中断,则发送信号给PIC的-INTA,告诉它把本次中断的向量号发送过来。主PIC收到-INTA管脚上的信号后,通过D0-D7引脚,输出此次中断的中断向量号到数据总线(这里简化了交互过程,实际上有两次INTA信号的发送)。CPU拿到这个号后,就可以从IDT中寻找中断服务例程(ISR)进行处理了,后面的事大家都知道了。

  那PIC中的中断向量号是怎么来的呢?各个IRQ是如何对应到IDT中的各个项呢?这里就利用了中断控制器的可编程性来决定的了。

  PIC全称为可编程中断控制器,那么它的可编程体现在哪些方面呢?参考资料2《i8259A中断控制器分析一一文有比较详细的描述,大体包括编程指定主从片的IRQ线对应的中断在IDT表中的中断向量号、8259a中断控制器的中断方式、优先级方式、中断嵌套方式,中断屏蔽方式、中断结束方式等等,这些都可以由操作系统编程指定。具体的编程格式在参考资料3《i8259A中断控制器分析二》一文中有图文介绍。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/63635.html