1.定义
中断通常定义为一个事件,该事件改变处理器执行的指令顺序。中断通常分为同步中断与异步中断。
- 同步中断:当指令执行时由CPU控制单元产生的,只有在一条指令终止执行后CPU才会发出中断。
- 异步中断:由其他硬件设备依照CPU时钟信号随机产生的。
异常是同步的,I/O中断是异步的。
2.中断与异常
中断可以分为:
- 可屏蔽中断
I/O设备发出的中断请求(IRQ)都可以被屏蔽,一个中断被屏蔽以后,控制单元就忽略他。
- 非屏蔽中断
只有硬件故障等几个危急事件才是非屏蔽中断。
异常可以分为:
- 故障
可以纠正的异常,例如缺页异常等。eip保存的是引起故障的指令地址,故障修复以后,该指令还会被执行一次。
- 陷进
例如断点。eip中保存的一个随后要执行的指令地址,异常指令不会被重复执行
- 中止
发生严重错误,不能再eip中保存确切的异常指令的位置,强制终止受影响的进程。
3.IRQ和中断
当一个CPU接收到一个中断时,如何知道是哪个硬件的中断?
根据该中断的中断向量号在中断描述表中检索对应的描述符,根据中断描述符中的段选择符以及段偏移量找到中断处理程序的起始地址,然后执行中断处理程序。
那么,中断向量是什么???中断描述符表又是什么???
中断向量的确定:
每个能发出中断请求的硬件设备控制器都有一条名为IRQ的输出线,该线与可编程中断控制器(Programmable Interrupt Controuer,PIC)的输入引脚相连。该中断控制器可以根据产生中断信号的不同的IRQ线转换成对应的中断向量,然后CPU通过数据总线读取此向量。
中断向量由256个,分布如下所示(图片节选自《深入理解LINUX内核》)
如上表所示,物理IRQ可以分配给32~238范围内的任何向量,128被用来实现系统调用。IBM PC兼容的体系结构要求一些设备必须被静态的连接到指定的IRQ线,尤其是:
- 间隔定时的设备必须连接到IRQ0线
- 从8259A PIC必须与IRQ2线相连接
- 必须把外部数字协会粗利器连接到IRQ13线
- 一般而言,一个I/O设备可以连接到有限个IRQ线
下表显示了设备和IRQ之间一种相当随意的安排。
异常的中断向量分布如下:
4.中断描述符
中断描述符表(Interrupt Descriptor Table,IDT)是一个系统表,它与中断异常向量相联系,每一个中断向量在表中有相应的中断或异常处理程序的入口地址。内核在允许中断发生前,必须适当的初始化IDT。
IDT包含三种类型的描述符,如下表所示:
描述符是:
任务门(task gate)
当中断信号发生时,必须取代当前进程的那个进程的TSS选择符存放在任务门中
中断门(interrupt gate)
包含段选择符和中断或异常处理程序的段内偏移量。当控制权传递到一个适合的段时,清IF标志,关中断。
陷进门(trap gate)
与中断门相似,只不过传递控制权以后,不清IF标志。
5.中断和异常的硬件处理
3中简要介绍了中断异常处理的流程,并在3,4中简介了中断向量与中断描述符表,现在详细介绍下中断异常的处理流程。
当CPU执行了一条指令后,cs和eip这对寄存器包含下一条将要执行的指令的逻辑地址。在处理这条指令之前,控制单元会检查在运行前一条指令时是否已经发生了一个中断或异常(控制单元是轮询是否有中断发生)。如果发生了一个中断或异常:
- 确定中断或异常的中断系向量i(0<=i<=255)
- 读由idtr寄存器指向的IDT表中的第i项(假设该项是中断门或者陷进门)
- 从gdtr寄存器过得GDT的基地址,该基地址指向中断处理程序所在段的基地址
- 确信中断是由授权的发生源发出的。将当前特权级CPL(存放在cs寄存器的低两位)与段描述符(存放在GDT中)的描述符特权级CPL比较
- 检查是否发生了特权级的变化
- 如果发生了故障,在cs和eip装载引起异常的指令地址,以使得故障恢复后异常指令能够再次被执行
- 在栈中保存eflags,cs及eip的内容
- 装载cs和eip寄存器,其值分别是IDT表中第i项门描述符的段选择符和偏移量子段。
- 跳转执行中断异常处理程序
中断异常处理完以后,相应的处理程序必须产生一条iret指令,把控制权转交给被中断的进程。
6.中断优先级
PIC模式IRQ数目越低意味着优先级越高。在APIC模式下,IOAPIC连接的24个IRQ是平权的,决定优先级的是对应的中断向量的大小,中断向量有256,中断优先级的计算公式:
优先级=vector num/16
即每16个中断或异常一组,共享一个优先级,共16个。32以下的中断向量被异常和保留占据,因此2到15是中断的优先级。