理解 Linux 系统中断
中断Interrupt,在 wikipedia 的定义为:“在计算机科学中是指处理器接收到来自硬件或软件的信号,提示发生了某个事件,应予以注意,这种情况就称为中断”。
从 wikipedia 定义中可以明确,中断信号可以来自于:
-
外围硬件
的异步信号
-
软件
的同步信号
CPU 接收到信号后,CPU会打断当前的工作并保存现场,然后CPU会根据中断信号找到一对应的处理程序来执行,处理完毕后再根据处理结果决定是否需要继续执行原来任务。
-
中断解决了什么问题?
中断一开始的设计初衷是为了避免CPU与外部设备通信时的忙等待。
众所周知,CPU的运算速度远超与存储设备、外部硬件的操作速度,例如当CPU下发读取数据的指令给硬盘设备后,在硬盘准备数据的期间,CPU需要进行忙等待,反复轮询硬盘设备是否已经完成动作并返回结果,这就导致了大量的CPU周期被浪费。
有了中断技术后,CPU给硬盘设备发生指令后,无需等待硬盘完成操作,可以立即返回以处理其他任务,待硬盘完成动作后,发送中断信号给CPU,CPU根据中断信号接着回来处理结果即可。
后来中断技术也被用于 CPU外部与内部的紧急事件的处理、机器故障的处理、时间控制等多个方面,并产生了通过软件方式进行中断处理的概念。
-
中断信号的类型
中断信号通常有以下几种:
-
硬件中断
硬件中断的信号是异步的,即CPU也不知道 硬件中断信号 什么时候会产生,它由外部硬件设备触发。硬件中断还可以被细分为:
-
可屏蔽中断
硬件中断的一类,可通过在中断屏蔽寄存器中设定位掩码来关闭。 -
非可屏蔽中断
CPU必须处理的中断,无法通过在中断屏蔽寄存器中设定位掩码来关闭。典型例子是时钟中断(一个硬件时钟以恒定频率—如50Hz—发出的中断)。 -
处理器间中断
一种特殊的硬件中断。由处理器发出,被其它处理器接收。仅见于多处理器系统,以便于处理器间通信或同步。 -
伪中断
一类不希望被产生的硬件中断。发生的原因有很多种,如中断线路上电气信号异常,或是中断请求设备本身有问题。
-
-
软件中断
软件中断,本质是一条CPU指令,用以自陷一个中断,因此软件中断的信号是同步的。
软件中断也被称为异常
, 通常是由 程序错误 或者 必须内核处理的异常条件 产生。异常可以分为:-
陷阱
:有意的异常,例如系统调用
-
故障
: 潜在可恢复的错误 -
中止
: 不可恢复的错误
-
-
中断系统的设计和实例
作为一个程序员,硬件实现原理的确超出我的技术范畴,在这里只能说有兴趣了解的可以看下wikipedia:
这里面介绍了关于中断系统在设计层面,外部设备如何触发中断请求,CPU如何获得中断信号和寻找和执行中断处理程序等。
并简单介绍了CPU引脚
、中断向量表
等。
中断处理程序
中断处理程序,顾名思义,CPU收到中断信号后,所需要执行的对应处理程序。
硬件中断
和软件中断
的处理程序区别:
- 硬件中断的处理程序是由设备的驱动程序提供的,而软件中断的处理程序是由操作系统内核提供的。
- 硬件中断的处理程序是用于被内核调用来响应中断的,运行在被称为
中断上下文
的特殊上下文中(偶尔也被称为原子上下文
),该上下文中执行的代码不可阻塞。由于
硬件中断信号
随时都可能发生,需要保证中断处理程序能快速执行,且能快速恢复中断代码的执行,一般将中断处理的过程切成两部分:
上半部
上半部就是中断处理程序
,是一系列需要CPU立即执行的工作,在这里只做严格时限的工作,如对接收的中断进行应答或复位硬件。
下半部
下半部则是允许稍后完成的工作。我们以网卡为例,当网卡接收到来自网络的数据包时,需要通知内核数据包到了,网卡需要立即完成这件事,从而优化网络的吞吐量和传输周期,避免超时。因此网卡立即发出中断,内核通过执行网卡注册的中断处理程序来应答。中断开始执行,通知硬件,拷贝最新的网络数据包到内存,然后再去读取网卡更多的数据包。这些重要且急迫,又与硬件相关的工作都由上半部来完成。内核通常需要快速的拷贝网络数据包到系统内存,因为网卡上接收网络数据包的缓存大小固定,而且相比系统内存也要小得多。所以如果拷贝的动作延迟了,必然会导致缓存溢出,进入的网络包占满了网卡的缓存,后续到来的网络包只能被丢弃。当网络数据包被拷贝到系统内存后,中断的任务就完成了,此时它将控制权还给系统被中断前原先运行的程序,处理和操作数据包的工作都在随后的下半部来完成。