1. Linux设备驱动中的中断机制基础
中断处理是Linux设备驱动开发中最核心也最容易出问题的部分之一。想象一下你正在厨房做饭——炉灶上的水烧开了发出鸣笛声(硬件中断),你暂停切菜(保存当前任务上下文)去关火(中断处理),然后回来继续切菜(恢复上下文)。Linux内核处理硬件中断的过程与此高度相似。
在x86架构中,中断分为可屏蔽中断(INTR)和不可屏蔽中断(NMI),我们主要讨论通过中断控制器(如APIC)管理的可屏蔽中断。当设备触发中断时,处理器会:
- 保存当前EFLAGS、CS和EIP寄存器到内核栈
- 从中断描述符表(IDT)加载对应的中断服务例程(ISR)
- 关闭本地CPU的中断响应(防止嵌套中断导致栈溢出)
关键数据结构irq_desc包含了中断处理的所有元信息:
c复制struct irq_desc {
struct irq_data irq_data;
unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq;
struct irqaction *action; // 设备驱动注册的处理函数链表
wait_queue_head_t wait_for_threads;
// ...其他字段省略
};
注意:在ARM架构中,中断处理流程略有不同,涉及GIC(Generic Interrupt Controller)和异常向量表,但基本原理相通。
2. 驱动开发者视角的中断注册
2.1 请求中断线
现代Linux驱动通常使用devm_request_irq()这个托管版本的中断注册函数,其原型为:
c复制int devm_request_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, unsigned long flags,
const char *name, void *dev_id);
关键参数解析:
flags常用组合:IRQF_SHARED:允
