中斷機制的核心資料結構是 irq_desc,它完整地描述了一條中斷線(或稱為“中斷通道” ) 。
irq_desc 結構在 include/linux/irq.h 中定義在 kernel/irq/handle.c 中
有個全域 irq_desc 數組,描述了系統中所有的中斷線:
handle_irq,這是個函數指標,指向的是一個高層次的中斷事件處理函數,定義了處理中斷事件的一種策略。
在 kernel/irq/chip.c 中實現了 5 個函數:handle_simple_irq(),handle_level_irq(),
handle_irq 指標可handle_edge_irq(),handle_fasteoi_irq()以及 handle_percpu_irq()。
以指向這 5 個函數中的一個,選擇一種中斷事件處理策略,這是通過函數 set_irq_handler()完成的。
接下來是 chip, 這是個 irq_chip 結構指標。irq_chip 結構定義了對中斷線的底層硬體操作,
在 include/linux/irq.h 中:
最後的資料成員是 action,這是個 irq_action 結構指標。 irq_action 結構定義了安裝在中
斷線上的一個中斷處理常式,在 include/linux/interrupt.h 中
init/main.c
asmlinkage void __init start_kernel(void)
{
......
584 setup_arch(&command_line);//{750 init_arch_irq = mdesc->init_irq;} 對627行調用的init_arch_irq函數指標賦值。
......
/* 重定位中斷向量表,修改中斷向量表佔用頁面的存取權限 */
606 trap_init();
....
/* 這個函數首先把irq_desc數組中的所有元素的status設為IRQ_NOREQUEST|IRQ_NOPROBE(沒有請求,沒有檢測),然後調用init_arch_irq()*/
627 init_IRQ();//{init_arch_irq();...}
}
init_arch_irq()在setup_arch()中被賦值,指向machine_desc中定義的init_irq函數指標。AT91SAM9260EK 平台上,就指向了 arch/arm/mach-at91/board-sam9260ek.c 中定義的函數ek_init_irq()。ek_init_irq() 又 調 用 了 arch/arm/mach-at91/at91sam9260.c中的at91sam9260_init_interrupts()。(這個machine_desc的賦值在arch/arm/mach-at91/board-sam9260ek.c最後幾行中MACHINE_START(AT91SAM9260EK,
"Atmel AT91SAM9260-EK").....其中就有.init_irq = ek_init_irq。)
接下來 arch/arm/mach-at91/irq.c 中 的 at91_aic_init()進行AIC初始化,調用arch/arm/mach-at91/gpio.c 中的 at91_gpio_irq_setup()進行GPIO的中斷初始化。
arch/arm/mach-at91/irq.c
static struct irq_chip at91_aic_chip = {
.name = "AIC",
.ack = at91_aic_mask_irq,
.mask = at91_aic_mask_irq,
.unmask = at91_aic_unmask_irq,
.set_type = at91_aic_set_type,
.> .set_wake = at91_aic_set_wake,
};
132 void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
這個函數主要是寫了 AIC 的一些寄存器,還為每個中斷線設定了 chip(指向at91_aic_chip) 和 handle_irq ( 指 向 handle_level_irq ) 然 後 把 中 斷 線 的 狀 態 修 改 為IRQF_VALID | IRQF_PROBE(已有效&以檢測),at91_aic_chip 定義的底層操作函數也在arch/arm/mach-at91/irq.c 中,不再詳述。
至此,中斷機制的初始化工作已完成。