1. irq_desc数组
kernel/irq/irqdesc.c
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
}
};
每一个中断号(或者叫一条中断线),对应一个数组元素。
不同设备,可能共用同一个中断号
2. 中断到来后,cpu会根据中断号,找到相应的中断门,进而跳到对应的中断处理例程执行。这个过程完全由硬件完成。
当然,中断门已由OS在启动时做了妥善的初始化。
3. 所有的中断处理例程,均获取并保存一下中断号(当然还有别的一些系统方面的工作),然后执行do_IRQ。
do_IRQ再调用handle_irq
handle_irq根据中断号,索引到irq_desc中的对应元素desc,然后调用desc->handle_irq完成中断处理。
desc->handle_irq可能是如下的一些函数
handle_level_irq
handle_edge_irq
当然,也可能是别的函数,反正我没有理全。
这些函数,最终会调用handle_irq_event,进而进入handle_irq_event_percpu。
后者,会遍历desc->action指向的一个struct irqaction类型的链表(每一个共享此同一中断线的设备对应一个action),尝试调用其handler完成中断的处理。