来自:linux内核修炼之道
中断处理基本过程:首先设备产生中断,并通过中断线将中断信号送往中断控制器。如果该中断没有被屏蔽,则会被送往 CPU 的 INTR 引脚。CPU 立即停止当前的工作,根据从中断控制器获得的中断向量号,从 IDT(Interrupt Descriptor Table中断描述符表) 中找到相应的门描述符,从而获取中断服务程序的地址并执行。
异常处理基本过程:与中断不同,异常并不需要经过中断控制器转发电信号。当异常发生时,CPU 通过其特定的中断向量号,从 IDT 中查找相应的门描述符,并获取异常服务程序的地址。
中断控制器的工作
中断控制器是外部设备和 CPU 之间中断信号传递的桥梁,如图 6.10 所示为中断控制器 8259A 在中断处理过程中所做的工作。
8259A 主要有 3 个寄存器用于对中断的响应与处理。
IRR:(中断请求寄存器,记录是否已收到中断请求)
即 Interrupt Request Register,共 8bit,对应 IR0~IR7 八个中断引脚。当某个
引脚的中断请求到来后,若该引脚没有被屏蔽,则 IRR 中对应的 bit 被置为 1,表示已经收到设
备的中断请求,但还未提交给 CPU。
ISR: (中断服务寄存器,记录是否已经转发中断给CPU)
Interrupt Service Register,8bit,共对应 IR0~IR7 八个中断引脚。 IRR 中当的某个中断请求被送往 CPU 后,ISR 中对应的 bit 被置为 1,表示中断已提交给 CPU,但 CPU还未处理完。
IMR:
即 Interrupt Mask Register,中断屏蔽寄存器,共 8bit,对应 IR0~IR7 八个中断引脚。当某个bit 置为 1 时,对应的中断引脚被屏蔽。
8259A 的各个中断引脚之间有一定的优先级,同时也有两种优先级管理方式:固定优先级与循环优先级。固定优先级指优先级固定不变,号码越小优先级越高。循环优先级指优先级在系统工作过程中可以动态改变。
8259A 支持两种中断嵌套模式:一般嵌套模式与特殊嵌套模式。一般嵌套模式是指,当一个中断正在被 CPU 处理时,优先级等于或低于该中断的中断被自动屏蔽,而更高优先级的中断则会被立即送往 CPU。特殊嵌套模式与一般嵌套模式的区别为,当一个中断正在被 CPU 处理时,同级的中断不被屏蔽。Linux 默认使用一般嵌套模式。
下面是 8259A 在中断处理过程中所要完成的工作。
(1)中断请求。
设备发起中断时,与其相连的 IR 引脚上产生电信号,若对应的中断没有被屏蔽,即 IMR中相应位为 0,则设置 IRR 中的相应位为 1,并通过 INT 引脚向 CPU 的 INTR 引脚发出中断请求信号。若已经被屏蔽,则仅仅丢弃该中断请求。
(2)中断响应。
CPU 响应中断必须满足 3 个条件:至少有一个中断请求;CPU 允许中断;当前指令执行完毕。因此,当 8259A 向 CPU 提交中断请求信号时,CPU 可能正在执行一条指令,并不会立即进行响应。
(3)此时,可能有其他 IRQ 线也产生了中断请求,如果没有被屏蔽,那么这些请求对应的 IRR位也会被设置为 1。
(4)而当 CPU 执行完一条指令时,会去检查 INTR 管脚是否有信号,即是否有新的中断请求,如果有,还要检查EFLAGS 寄存器的中断允许标志 IF 是否为 1,若 IF 为 1,则通过 INTA 引脚应答 8259A,表示收到中断请求。
(5)优先级判定。
8259A 收到 CPU 的应答后,在 IRR 中挑选优先级最高的中断,将其在 ISR 中的对应位置 1,并将 IRR 中相应位置 0,表明此中断正在接受 CPU 的处理。
(6)提交中断向量。
CPU 通过 INTA 引脚第二次发出脉冲(每次处理完中断服务都发送INTA脉冲,所以第一次发脉冲也可以看作是上一次处理完数据),8259A 收到后根据被设置的起始向量号(通过初始化命令寄存器 ICW 被初始化),计算最高优先级中断的中断向量(比如起始向量号为 16,当前中断请求为 IR3,则得到的中断向量为 16+3=19),并将它通过数据线 D0~D7 提交给 CPU。
(7)中断结束(两种清空ISR的方式)。
提交中断向量之后,8259A 会检测是否 AEOI(Auto EOI)模式,若是,则自动清除中断请求信号, ISR 中的相应位清零。
将若不是,则需要等待 CPU 发送 EOI End of Interrupt,(CPU 通知 PIC 中断处理结束的方式,由中断服务程序发起)指令。收到 EOI 后,ISR 中的相应位才会被
清零。
上述过程中,需要注意的是,如果一个中断请求被屏蔽,则它将会被丢弃,从而失去参加优先级判定的机会。
另外需要注意的是,对中断请求的优先级判定位于 8259A 中。
假如 CPU 正在处理 IRQ1 线来的中断请求,此时 ISR 中 IRQ1 的相应位为 1。如果这时有一个来自 IRQ2 的中断请求产生,8259A 会将其同 ISR 中
的值进行比较,发现比它优先级高的 IRQ1 所对应的位已经被置位,因此仅设置 IRR 中的相应位。如果这时来的是 IRQ0,与 ISR 比较后,8259A 会立即将 ISR 中 IRQ0 对应的位置 1,并向 CPU 提交中断请求。
因为 CPU 还正在处理 IRQ1,所以这时 ISR 中 ISR0 与 IRQ1 的相应位都为 1。
如果 8259A 工作于 AEOI 模式,那么 ISR 中的位总是被清零的(在 AEOI 模式下,8259A 只要向 CPU提交了中断向量就会自动将 ISR 中的相应位清零)
,这就意味着如果有新的中断请求产生,8259A 就会立即向 CPU 提交中断请求,即使 CPU 正在处理 IRQ0 的中断,CPU 只会简单地应答 8259A。因此,这种情
况下低优先级的中断就可能会中断高优先级的中断服务程序。