中断是现代 CPU 工作方式的重要组成部分。例如,每次您按下键盘上的一个键时,CPU 都会被中断,以便 PC 可以从键盘读取用户输入。这一切发生得非常快,您不会注意到用户体验有任何变化或损害。
此外,键盘不是唯一可以引起中断的组件。一般来说,有三种类型的事件可以导致 CPU 中断:硬件中断、软件中断和异常。在深入了解不同类型的中断之前,我将定义一些术语。
定义
中断请求(IRQ)由可编程中断控制器(PIC)请求,目的是中断 CPU 并执行中断服务例程(ISR)。ISR 是一个小型程序,它根据 IRQ 的原因处理特定数据。正常处理会中断,直到 ISR 完成。
过去,IRQ 由一个单独的微芯片(PIC)处理,I/O 设备直接连接到 PIC。PIC 管理各种硬件 IRQ,并可以直接与 CPU 通信。当发生 IRQ 时,PIC 将数据写入 CPU 并拉高中断请求(INTR)引脚。
如今,IRQ 由高级可编程中断控制器(APIC)处理,它是 CPU 的一部分。每个核心都有自己的 APIC。
中断类型
正如我所提到的,中断可以根据其来源分为三种类型
硬件中断
当硬件设备想告诉 CPU 某些数据已准备好处理时(例如,键盘输入或数据包到达网络接口时),它会发送一个 IRQ 信号给 CPU,表明数据可用。这会调用设备驱动程序在内核启动期间注册的特定 ISR。
软件中断
当您播放视频时,同步音乐和视频播放至关重要,以使音乐的速度不会发生变化。这通过一个软件中断来实现,该中断由精确的计时器系统(称为 jiffies)重复触发。此计时器使您的音乐播放器能够同步。软件中断也可以通过特殊指令来调用,以读取或写入硬件设备的数据。
当需要实时功能时(例如在工业应用中),软件中断也至关重要。您可以在 Linux 基金会的文章 嵌入式开发人员实时 Linux 简介 中找到更多相关信息。
异常
异常是您可能了解的中断类型。当 CPU 执行会导致除以零或页面错误的命令时,任何后续执行都会中断。在这种情况下,您将通过弹出窗口或在控制台输出中看到 segmentation fault (core dumped) 来获知。但并非每个异常都是由错误的指令引起的。
异常可以进一步分为故障、陷阱和中止。
- 故障: 故障是一种系统可以纠正的异常,例如,当进程尝试访问从硬盘驱动器交换出来的内存页中的数据时。请求的地址在进程地址空间内,并且访问权限是正确的。如果该页不在 RAM 中,则会引发 IRQ,并启动页面错误异常处理程序以将所需的内存页加载到 RAM 中。如果操作成功,执行将继续。
- 陷阱: 陷阱主要用于调试。如果在程序中设置断点,则会插入一个特殊指令,导致其触发陷阱。陷阱可以触发上下文切换,使您的调试器能够读取和显示局部变量的值。之后可以继续执行。陷阱也是执行系统调用(如杀死进程)的默认方式。
- 中止: 中止是由硬件故障或系统表中的不一致值引起的。中止不会报告导致异常的指令的位置。这些是最关键的中断。中止会调用系统的 中止异常处理程序,该处理程序会终止导致中止的进程。
动手实践
IRQ 按优先级在 APIC 上的向量中排序(0=最高优先级)。前 32 个中断(0-31)具有由 CPU 指定的固定序列。您可以在 OsDev 的 Exceptions 页面上找到它们的概述。后续的 IRQ 可以以不同的方式分配。中断描述符表(IDT)包含 IRQ 和 ISR 之间的分配。Linux 为分配定义了一个从 0 到 256 的 IRQ 向量。
要在您的系统上打印已注册中断的列表,请打开控制台并键入
cat /proc/interrupts
您应该看到类似这样的内容

内核版本 5.6.6 中注册的中断。(Stephan Avenwedde, CC BY-SA 4.0)
从左到右,各列分别是:IRQ 向量、每个 CPU 的中断计数(0 .. n
)、硬件源、硬件源的通道信息以及引起 IRQ 的设备的名称。
在表格的底部,有一些非数字中断。它们是特定于架构的中断,例如 IRQ 236 上的本地定时器中断(LOC)。其中一些在 Linux 内核源代码树的 Linux IRQ 向量布局 中指定。

特定于架构的中断 (Stephan Avenwedde, CC BY-SA 4.0)
要获得此表的实时视图,请运行
watch -n1 "cat /proc/interrupts"
结论
正确的 IRQ 处理对于硬件、驱动程序和软件的正确交互至关重要。幸运的是,Linux 内核在这方面做得非常好,普通的 PC 用户几乎不会注意到内核的整个中断处理过程。
这可能会变得非常复杂,本文仅对该主题进行了简要概述。深入了解该主题的良好信息来源是 Linux Inside 电子书 (CC BY-NC-SA 4.0) 和 Linux Kernel Teaching 仓库。
1 条评论