Linux 内核如何处理中断

中断是计算机处理数据的关键部分。
84 位读者喜欢这篇文章。
How Linux got to be Linux: Test driving 1993-2003 distros

互联网档案馆图书图片。由 Opensource.com 修改。CC BY-SA 4.0

中断是现代 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

您应该看到类似这样的内容

Registered interrupts list

内核版本 5.6.6 中注册的中断。(Stephan Avenwedde, CC BY-SA 4.0)

从左到右,各列分别是:IRQ 向量、每个 CPU 的中断计数(0 .. n)、硬件源、硬件源的通道信息以及引起 IRQ 的设备的名称。

在表格的底部,有一些非数字中断。它们是特定于架构的中断,例如 IRQ 236 上的本地定时器中断(LOC)。其中一些在 Linux 内核源代码树的 Linux IRQ 向量布局 中指定。

Architecture-specific interrupts

特定于架构的中断 (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 仓库。

下一步阅读
标签
User profile image.
Stephan 是一位技术爱好者,他欣赏开源,因为它能深入了解事物的工作原理。Stephan 在工业自动化软件领域担任全职支持工程师,该领域主要涉及专有软件。如果可能,他会从事基于 Python 的开源项目、撰写文章或骑摩托车。

1 条评论

关于软件中断的部分是不正确的。定时器中断仍然是硬件中断,甚至可以来自 CPU 外部的定时器(就像任何其他设备一样)。软件中断完全通过硬件完成。一个常见的用例是网络代码。当收到数据包时,会触发硬件中断以从设备获取数据包。但是由于我们不允许在中断处理程序中发生其他中断,因此从中处理中断会花费太多工作。因此,触发“软件中断”以完成数据包的处理。硬件中断返回,软件中断接管。主要区别在于,其他硬件中断可能会进入并中断软件中断。关于 PREEMPT_RT(Linux 的实时版本),硬件中断处理程序在正常的线程上下文中运行(可能会被其他硬件中断中断),而软件中断主要在引发它的任何事物的上下文中运行。

© . All rights reserved.