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完成中斷的處理。