mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
Merge pull request #20540 from mengxinayan/mengxinayan-translation
Finish translation (mengxinayan)
This commit is contained in:
commit
6af3e3befe
@ -1,113 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ()
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How the Linux kernel handles interrupts)
|
||||
[#]: via: (https://opensource.com/article/20/10/linux-kernel-interrupts)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
|
||||
How the Linux kernel handles interrupts
|
||||
======
|
||||
Interrupts are a crucial part of how computers process data.
|
||||
![Penguin driving a car with a yellow background][1]
|
||||
|
||||
Interrupts are an essential part of how modern CPUs work. For example, every time you press a key on the keyboard, the CPU is interrupted so that the PC can read user input from the keyboard. This happens so quickly that you don't notice any change or impairment in user experience.
|
||||
|
||||
Moreover, the keyboard is not the only component that can cause interrupts. In general, there are three types of events that can cause the CPU to interrupt: _Hardware interrupts_, _software interrupts_, and _exceptions_. Before getting into the different types of interrupts, I'll define some terms.
|
||||
|
||||
### Definitions
|
||||
|
||||
An interrupt request (**IRQ**) is requested by the programmable interrupt controller (**PIC**) with the aim of interrupting the CPU and executing the interrupt service routine (**ISR**). The ISR is a small program that processes certain data depending on the cause of the IRQ. Normal processing is interrupted until the ISR finishes.
|
||||
|
||||
In the past, IRQs were handled by a separate microchip—the PIC—and I/O devices were wired directly to the PIC. The PIC managed the various hardware IRQs and could talk directly to the CPU. When an IRQ occurred, the PIC wrote the data to the CPU and raised the interrupt request (**INTR**) pin.
|
||||
|
||||
Nowadays, IRQs are handled by an advanced programmable interrupt controller (**APIC**), which is part of the CPU. Each core has its own APIC.
|
||||
|
||||
### Types of interrupts
|
||||
|
||||
As I mentioned, interrupts can be separated into three types depending on their source:
|
||||
|
||||
#### Hardware interrupts
|
||||
|
||||
When a hardware device wants to tell the CPU that certain data is ready to process (e.g., a keyboard entry or when a packet arrives at the network interface), it sends an IRQ to signal the CPU that the data is available. This invokes a specific ISR that was registered by the device driver during the kernel's start.
|
||||
|
||||
#### Software interrupts
|
||||
|
||||
When you're playing a video, it is essential to synchronize the music and video playback so that the music's speed doesn't vary. This is accomplished through a software interrupt that is repetitively fired by a precise timer system (known as [jiffies][2]). This timer enables your music player to synchronize. A software interrupt can also be invoked by a special instruction to read or write data to a hardware device.
|
||||
|
||||
Software interrupts are also crucial when real-time capability is required (such as in industrial applications). You can find more information about this in the Linux Foundation's article _[Intro to real-time Linux for embedded developers][3]_.
|
||||
|
||||
#### Exceptions
|
||||
|
||||
Exceptions are the type of interrupt that you probably know about. When the CPU executes a command that would result in division by zero or a page fault, any additional execution is interrupted. In such a case, you will be informed about it by a pop-up window or by seeing **segmentation fault (core dumped)** in the console output. But not every exception is caused by a faulty instruction.
|
||||
|
||||
Exceptions can be further divided into _Faults_, _Traps_, and _Aborts_.
|
||||
|
||||
* **Faults:** Faults are an exception that the system can correct, e.g., when a process tries to access data from a memory page that was swapped to the hard drive. The requested address is within the process address space, and the access rights are correct. If the page is not present in RAM, an IRQ is raised and it starts the **page fault exception handler** to load the desired memory page into RAM. If the operation is successful, execution will continue.
|
||||
* **Traps:** Traps are mainly used for debugging. If you set a breakpoint in a program, you insert a special instruction that causes it to trigger a trap. A trap can trigger a context switch that allows your debugger to read and display values of local variables. Execution can continue afterward. Traps are also the default way to execute system calls (like killing a process).
|
||||
* **Aborts:** Aborts are caused by hardware failure or inconsistent values in system tables. An abort does not report the location of the instruction that causes the exception. These are the most critical interrupts. An abort invokes the system's **abort exception handler**, which terminates the process that caused it.
|
||||
|
||||
|
||||
|
||||
### Get hands-on
|
||||
|
||||
IRQs are ordered by priority in a vector on the APIC (0=highest priority). The first 32 interrupts (0–31) have a fixed sequence that is specified by the CPU. You can find an overview of them on [OsDev's Exceptions][4] page. Subsequent IRQs can be assigned differently. The interrupt descriptor table (**IDT**) contains the assignment between IRQ and ISR. Linux defines an IRQ vector from 0 to 256 for the assignment.
|
||||
|
||||
To print a list of registered interrupts on your system, open a console and type:
|
||||
|
||||
|
||||
```
|
||||
`cat /proc/interrupts`
|
||||
```
|
||||
|
||||
You should see something like this:
|
||||
|
||||
![Registered interrupts list][5]
|
||||
|
||||
Registered interrupts in kernel version 5.6.6 (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
From left to right, the columns are: IRQ vector, interrupt count per CPU (`0 .. n`), the hardware source, the hardware source's channel information, and the name of the device that caused the IRQ.
|
||||
|
||||
On the bottom of the table, there are some non-numeric interrupts. They are the architecture-specific interrupts, like the local timer interrupt (**LOC**) on IRQ 236. Some of them are specified in the [Linux IRQ vector layout][7] in the Linux kernel source tree.
|
||||
|
||||
![Architecture-specific interrupts][8]
|
||||
|
||||
Architecture-specific interrupts (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
To get a live view of this table, run:
|
||||
|
||||
|
||||
```
|
||||
`watch -n1 "cat /proc/interrupts"`
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
Proper IRQ handling is essential for the proper interaction of hardware, drivers, and software. Luckily, the Linux kernel does a really good job, and a normal PC user will hardly notice anything about the kernel's entire interrupt handling.
|
||||
|
||||
This can get very complicated, and this article gives only a brief overview of the topic. Good sources of information for a deeper dive into the subject are the _[Linux Inside][9]_ eBook (CC BY-NC-SA 4.0) and the [Linux Kernel Teaching][10] repository.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/10/linux-kernel-interrupts
|
||||
|
||||
作者:[Stephan Avenwedde][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hansic99
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
|
||||
[2]: https://elinux.org/Kernel_Timer_Systems
|
||||
[3]: https://www.linuxfoundation.org/blog/2013/03/intro-to-real-time-linux-for-embedded-developers/
|
||||
[4]: https://wiki.osdev.org/Exceptions
|
||||
[5]: https://opensource.com/sites/default/files/uploads/proc_interrupts_1.png (Registered interrupts list)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/irq_vectors.h
|
||||
[8]: https://opensource.com/sites/default/files/uploads/proc_interrupts_2.png (Architecture-specific interrupts)
|
||||
[9]: https://0xax.gitbooks.io/linux-insides/content/Interrupts/
|
||||
[10]: https://linux-kernel-labs.github.io/refs/heads/master/lectures/interrupts.html#
|
@ -0,0 +1,116 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ()
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How the Linux kernel handles interrupts)
|
||||
[#]: via: (https://opensource.com/article/20/10/linux-kernel-interrupts)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
|
||||
Linux 内核如何处理中断
|
||||
======
|
||||
|
||||
中断是计算机处理数据的关键部分。
|
||||
|
||||
![企鹅驾驶着黄色背景的汽车][1]
|
||||
|
||||
中断是现代CPU工作中必不可少的一部分。例如:当你每次在键盘上按下一个按键后,CPU会被中断以使得PC读取用户键盘的输入。这个过程发生得相当快以致于在使用体验上你不会感到任何变化或损害。
|
||||
|
||||
此外,键盘并不是导致中断的唯一元素。一般来说,有三种类型的事件会导致CPU发生中断:硬件中断、软件中断和异常。再具体介绍不同类型的中断前,我需要先定义一些术语。
|
||||
|
||||
### 定义
|
||||
|
||||
一个中断请求(**IRQ**)是被可编程的中断控制器(**PIC**)发起,其目的是为了中断CPU和执行中断服务程序(**ISR**)。中断服务程序(ISR)是一个小的程序来处理具体的数据,其具体的处理方式依赖于造成中断请求(IRQ)的原因。之前正在运行的进程在中断服务程序(ISR)运行结束前都会被中断。
|
||||
|
||||
在过去,中断请求由单独的芯片处理(中断控制器芯片),I/O 设备与中断控制器(PIC)直接相连。中断控制器(PIC)管理着多种硬件的中断请求并且可以直接与CPU通信。当一个中断请求(IRQ)产生后,中断控制器向CPU写入数据并且触发中断请求(**INTR**)引脚。
|
||||
|
||||
现如今,中断请求(IRQ)由CPU中的高级可编程中断控制器(APIC)部分来处理。每个核中都拥有属于自己的高级可编程中断控制器。
|
||||
|
||||
### 中断的类型
|
||||
|
||||
正如我前文中提到的,中断可以根据其来源分为三种类型。
|
||||
|
||||
#### 硬件中断
|
||||
|
||||
当一个硬件设备想要告诉CPU某一需要处理的数据已经准备好后(例如:当键盘被按下或者一个数据包到了网络接口处),它将会发送一个中断请求(IRQ)来告诉CPU数据是可用的。接下来会调用在内核启动时设备驱动注册的对应的中断服务程序(ISR)。
|
||||
|
||||
#### 软件中断
|
||||
|
||||
当你在播放一个视频时,音频和视频是同步播放是相当重要的,因此音频的播放速度不应该发生变化。这是由软件中断实现的,由精确的计时器系统(称为 [jiffies][2])重复发起的。这个计时器会使得你的音乐播放器同步。软件中断也可以被特殊的指令所调用来读取或写入数据到硬件设备。
|
||||
|
||||
当系统需要实时性时(例如在工业应用中),软件中断会变得重要。你可以在Linux基金会的文章中找到更多相关信息:[面向嵌入式开发者的实时Linux介绍][3]。
|
||||
|
||||
#### 异常
|
||||
|
||||
异常是你可能之前知道的中断类型。当CPU执行一些将会导致除以0或缺页错误的指令时,任何其他运行中的程序都会被中断。在这种情况下,你会被一个弹窗提醒,或在控制台输出中看到**段错误(核心已转存)**。但并不是所有异常都是由指令错误引起的。
|
||||
|
||||
异常可以进一步分为 _错误_、_陷阱_ 和 _中止_ ?
|
||||
|
||||
Exceptions can be further divided into _Faults_, _Traps_, and _Aborts_.
|
||||
|
||||
* **错误:** 错误是系统可以纠正的异常。例如当一个进程尝试访问某个已经被换出到硬盘的页时。当请求的地址在进程的地址空间中,并且满足访问权限时,如果页不在内存(RAM)中,将会产生一个中断请求(IRQ),并开始启用**缺页异常处理程序**把所需的页加载到内存中。如果操作成功执行,程序将继续运行。
|
||||
|
||||
* **陷阱:** 陷阱主要用在调试中。如果你在某个程序中设置了一个断点,你就插入了一条可以触发陷阱执行的指令。一个陷阱可以触发上下文切换来允许你的调试器读取和展示局部变量的值。之后程序可以继续运行。陷阱同样也是运行系统调用的方式(如杀死一个进程)
|
||||
|
||||
* **中止:** 中止是由系统表中的硬件错误或值不一致而导致的。一个中止不会报告造成异常的指令的所在位置。这是最严重的中断,一个中止将会调用系统的**中止异常处理程序**来结束造成异常的进程。
|
||||
|
||||
### 动手实践
|
||||
|
||||
中断请求按照高级可编程中断控制器(APIC)中的优先级高低排序(0是最高优先级)。前32个中断(0~31)是由CPU指定的固定序列。你可以在 [OsDev 异常][4] 页面找到关于它们的概述。接下来的中断请求可以不同的分配。中断描述表(**IDT**)中记录了中断请求(IRQ)和中断服务程序(ISR)的对应关系。Linux 中定义了从 0 到 256 的 IRQ 向量。
|
||||
|
||||
为了打印出在你的系统中已注册的中断,打开一个终端并输入:
|
||||
|
||||
```
|
||||
`cat /proc/interrupts`
|
||||
```
|
||||
|
||||
你应该会看到类似如下图的结果:
|
||||
|
||||
![注册的中断列表][5]
|
||||
|
||||
内核版本为5.6.6中注册的中断 (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
从左到右各列的含义依次为:中断向量号、每个CPU(0~n)中断发生次数、硬件来源、硬件源通道信息、以及造成中断请求的设备名。
|
||||
|
||||
在表的末尾,有一些非数字的中断。它们是特定于体系结构的中断,如本地计时器中断(**LOC**)的中断请求(IRQ)号为236。其中一些在 Linux 内核源树中的[Linux IRQ 向量布局][7]中指定。
|
||||
|
||||
![特定于体系结构的中断][8]
|
||||
|
||||
特定于体系结构的中断 (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
|
||||
如果要实时获取该表,请运行如下命令:
|
||||
|
||||
```
|
||||
`watch -n1 "cat /proc/interrupts"`
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
正确的中断请求(IRQ)处理对于硬件、驱动和软件的正常交互是必要的。幸运地是,Linux 内核很好地完成了它,一个PC的普通用户很难注意到内核整个中断处理的过程。
|
||||
|
||||
中断相当复杂,本文仅仅是一个关于中断的概述。如果想要深入了解该主题可以阅读 [Linux 内部电子书][9](CC BY-NC-SA 4.0)和 [Linux 内核教程][10] 仓库。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/10/linux-kernel-interrupts
|
||||
|
||||
作者:[Stephan Avenwedde][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hansic99
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
|
||||
[2]: https://elinux.org/Kernel_Timer_Systems
|
||||
[3]: https://www.linuxfoundation.org/blog/2013/03/intro-to-real-time-linux-for-embedded-developers/
|
||||
[4]: https://wiki.osdev.org/Exceptions
|
||||
[5]: https://opensource.com/sites/default/files/uploads/proc_interrupts_1.png (Registered interrupts list)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/irq_vectors.h
|
||||
[8]: https://opensource.com/sites/default/files/uploads/proc_interrupts_2.png (Architecture-specific interrupts)
|
||||
[9]: https://0xax.gitbooks.io/linux-insides/content/Interrupts/
|
||||
[10]: https://linux-kernel-labs.github.io/refs/heads/master/lectures/interrupts.html#
|
Loading…
Reference in New Issue
Block a user