中断

中断和异常

中断(interrupt)通常被定义为一个事件,该事件改变处理器执行的指令顺序。这样的事件与CPU芯片内外部硬件电路产生的电信号相对应。
中断通常分为同步(synchronous)中断和异步(asynchronous)中断:

  • 同步中断是当指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后CPU才会发出中断。
  • 异步中断是由其他硬件设备依照CPU时钟信号随机产生的。

在Intel微处理器手册中,把同步和异步中断分别称为异常(exception)和中断(interrupt)。我们也采用这种分类,当然有时我们也用术语“中断信号”指这两种类型(同步及异步)。

中断是由间隔定时器和I/O设备产生的,例如,用户的一次按键会引起一个中断。另一方面,异常是由程序的错误产生的,或者是由内核必须处理的异常条件产生的。第一种情况下,内核通过发送一个每个Unix程序员都熟悉的信号来处理异常。第二种情况下,内核执行恢复异常需要的所有步骤,例如缺页,或对内核服务的一个请求(通过一条int或sysenter指令)。

中断和异常

  • 中断:

    • 可屏蔽中断

      I/O设备发出的所有中断请求(IRQ)都产生可屏蔽中断。可屏蔽中断可以处于两种状态:屏蔽的(masked)或非屏蔽的(unmasked):一个屏蔽的中断只要还是屏蔽的,控制单元就忽略它。

    • 非屏蔽中断

      只有几个危急事件(如硬件故障)才引起非屏蔽中断,非屏蔽中断总是由CPU辨认

  • 异常

    • 处理器探测异常

      当CPU执行指令时探测到的一个反常条件所产生的异常。可以进一步分为三组,这取决于CPU控制单元产生异常时保存在内核态堆栈eip寄存器(在 x86 指令集中,EIP 寄存器存储着 CPU 将要执行的下一条指令的内存地址)中的值。

      • 故障

        通常可以纠正;一且纠正,程序就可以在不失连贯性的情况下重新开始。保存在eip中的值是引起故障的指令地址,因此,当异常处理程序终止时,那条指令会被重新执行。我们将在“缺页异常处理程序”一节中看到,只要处理程序能纠正引起异常的反常条件,重新执行同一指令就是必要的。

      • 陷阱

        在陷指令执行后立即报告:内核把控制权返回给程序后就可以继续它的执行而不失连贯性。保存在eip中的值是一个随后要执行的指令地址。只有当没有必要重新执行已终止的指令时,才触发陷阱。陷阱的主要用途是为了调试程序。在这种情况下,中断信号的作用是通知调试程序一条特殊指令已被执行(例如到了一个程序内的断点)。一旦用户检查到调试程序所提供的数据,她就可能要求被调试程序从下一条指令重新开始执行。

      • 异常终止

        发生一个严重的错误:控制单元出了问题,不能在eip寄存器中保存引起异常的指令所在的确切位置。异常中止用于报告严重的错误,如硬件故障或系统表中无效的值或不一致的值。由控制单元发送的这个中断信号是紧急信号,用来把控制权切换到相应的异常中止处理程序,这个异常中止处理程序除了强制受影响的进程终止外,没有别的选择。

      • 编程异常

        在编程者发出请求时发生。是由int或int3指令触发的:当into(检查溢出)和bound(检查地址出界)指令检查的条件不为真时,也引起编程异常。控制单元把编程异常作为陷来处理。编程异常通常也叫做软中断(software interrupt)。这样的异常有两种常用的用途:执行系统调用及给调试程序通报一个特定的事件。

每个中断和异常是由0~255之间的一个数来标识。因为一些未知的原因,Intel把这个8位的无符号整数叫做一个向量(vector)。非屏蔽中断的向量和异常的向量是固定的,而可屏蔽中断的向量可以通过对中断控制器的编程来改变。

IRQ和中断

​ 每个能够发出中断请求的硬件设备控制器都有一条名为IRQ(Interrupt ReQuest)的输出线(复杂一些的设备有几条IRQ线,例知,PCI卡可能使用多达4条IRQ线)。所有现有的IRQ线(IRQ line)都与一个名为可编程中断控制器(Programmable Interrupt Controller,PIC)的硬件电路的输入引脚相连,可编程中断控制器执行下列动作:

 1. 监视IRQ线,检查产生的信号(raised signal)。如果有条或两条以上的IRQ线上产生信号,就选择引脚编号较小的IRQ线
 2. 如果一个引发信号出现在IRQ线上:
  - 把接收到的引发信号转换成对应的向量
  - 把这个向量存放在中断控制器的一个I/O端口,从而允许CPU通过数据总线读取此向量
  - 把引发信号发送到处理器的INTR引脚,即产生一个中断
  - 等待,直到CPU通过把这个中断信号写进可编程中断控制器的一个I/O端口来确认他;当这种情况发生时,清INTR线
 3. 返回到第一步

​ IRQ线是从0开始顺序编号的,因此,第一条IRQ线通常表示成IRQ0。与IRQn关联的Intel的缺省向量是n+32。如前所述,通过向中断控制器端口发布合适的指令,就可以修改IRQ和向量之间的映射。

​ 可以有选择地禁止每条IRQ线。因此,可以对PIC编程从而禁止IRQ,也就是说,可以告诉PIC停止对给定的IRQ线发布中断,或者激活它们。禁止的中断是丢失不了的,它们一旦被激活,PIC就又把它们发送到CPU。这个特点被大多数中断处理程序使用,因为这允许中断处理程序逐次地处理同一类型的IRQ

中断描述符表

​ 中断描述符表(Interrupt Descriptor Table.IDT)是一个系统表,它与每一个中断或异常向量(异常向量是一组预定义的内存地址,用于存储处理器在发生异常时应该跳转到的位置)相联系,每一个向量在表中有相应的中断或异常处理程序的入口地址。内核在允许中断发生前,必须适当地初始化IDT.

​ IDT包含三种类型的描述符:

​ 任务门:当中断信号发生时,必须取代当前进程的那个进程的TSS选择符存放在任务门中。

​ 中断门:包含段选择符和中断或异常处理程序的段内偏移量。当控制权转移到一个适当的段时,处理器清IF标志,从而关闭将来会发生的可屏蔽中断。

​ 陷阱门:与中断门相似,只是控制权传递到一个适当的段时处理器不修改IF标志。

​ Linux利用中断门处理中断,利用陷阱门处理异常


中断
https://tomwithkernel.github.io/中断/中断/
作者
Tom
发布于
2024年10月31日
更新于
2024年11月25日
许可协议