Linux 内核的中断机制是操作系统核心部分之一,它负责在硬件设备发出中断请求(IRQ)时快速响应、处理,并在需要时延迟部分工作。中断机制的设计考虑了效率、并发性、实时性等要求,以确保系统能够稳定地处理外部设备的请求。
1. 中断的基本原理
中断是一种硬件机制,允许设备向 CPU 发出请求,以通知有数据要处理或某个事件已经发生。与轮询不同,中断机制无需 CPU 持续检查设备状态,而是由设备主动通知 CPU,从而提高系统的效率。
1.1 中断的分类
- 硬中断 (Hard IRQ):由外部设备产生的异步事件,需要立即处理。硬中断服务程序(ISR)必须快速执行,处理完后通常会安排后续工作。
- 软中断 (Soft IRQ):软中断是内核的一个机制,用于将一些工作延迟到稍后进行,通常用于处理那些不需要在硬中断上下文中执行的任务。软中断由内核在合适的时机进行调度和执行。
2. 中断的处理过程
中断处理包括几个关键步骤:
2.1 中断发生
当外部设备触发中断时,中断控制器 (如 PIC、APIC、GIC) 捕获中断请求,并将其发送给 CPU。CPU 会停止当前正在执行的任务,保存处理器状态,并跳转到对应的中断向量表,找到中断处理程序(ISR)。
2.2 硬中断处理
硬中断处理程序运行在中断上下文中,不允许睡眠或调度,因此只能进行非常有限的工作。典型的硬中断处理程序执行以下任务:
- 读取硬件状态(如读取设备寄存器)。
- 清除中断源(如告诉设备中断已经被处理)。
- 缓存必要的数据(如将数据放入缓冲区)。
- 通知内核有延迟处理任务需要执行。
2.3 延迟处理机制
由于硬中断的上下文不允许进行复杂的操作,因此需要将一些复杂任务推迟到稍后处理。Linux 提供了多种延迟处理机制来解决这一问题:
- Softirq: 是一种轻量级的延迟中断处理机制,主要用于网络栈、定时器等高频事件。Softirq 在更灵活的上下文中执行,允许多处理器同时处理不同的 Softirq。
- Tasklets: 基于 Softirq 的机制,用于调度轻量级的任务。Tasklets 是非抢占的,通常在单个处理器上执行,适合小而简单的任务。
- Workqueues: 允许将复杂任务推迟到内核线程中执行,内核线程上下文可以执行阻塞操作,适合更复杂的任务。
2.4 中断结束
当硬中断处理程序和延迟处理程序执行完毕后,CPU 恢复之前保存的状态,继续执行被中断的任务。
3. 中断控制器
中断控制器(如 PIC、APIC、GIC)负责接收来自外设的中断信号并传递给处理器。不同的体系结构有不同的中断控制器。
- PIC (Programmable Interrupt Controller):早期的中断控制器,通常应用于单处理器系统。
- APIC (Advanced Programmable Interrupt Controller):支持多处理器的中断控制器,能够处理更复杂的中断分发。
- GIC (Generic Interrupt Controller):用于 ARM 架构的中断控制器,支持多核系统的中断管理。
内核通过抽象这些中断控制器,使得驱动程序无需关心底层硬件的差异,只需通过统一的接口与中断机制交互。
4. 中断处理程序的注册与解除
在 Linux 内核中,设备驱动可以通过 request_irq()
函数向内核注册中断处理程序。该函数将设备的中断号和中断处理函数关联起来。
4.1 中断注册 (request_irq
)
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);
irq
:中断号,代表设备的中断请求线。handler
:中断处理程序,处理中断发生时的逻辑。flags
:指定中断的触发类型,如边沿触发或电平触发,是否共享中断等。name
:中断处理程序的名称,方便调试。dev