Linux 2.6 中斷處理原理簡介
Linux 2.6 中斷處理原理簡介
中斷描述符表(Interrupt Descriptor Table,IDT)是一個系統(tǒng)表,它與每一個中斷或異常向量相聯(lián)系,每一個向量在表中存放的是相應(yīng)的中斷或異常處理程序的入口地址。內(nèi)核在允許中斷發(fā)生前,也就是在系統(tǒng)初始化時,必須把 IDT 表的初始化地址裝載到 idtr 寄存器中,初始化表中的每一項。
當(dāng)處于實模式下時,IDT 被初始化并由 BIOS 程序所使用。然而,一旦 Linux 開始接管,IDT 就被移到 ARM 的另一個區(qū)域,并進(jìn)行第二次初始化,因為 Linux 不使用任何 BIOS 程序,而使用自己專門的中斷服務(wù)程序(例程)(interrupt service routine,ISR)。中斷和異常處理程序很像常規(guī)的 C 函數(shù)
有三個主要的數(shù)據(jù)結(jié)構(gòu)包含了與 IRQ 相關(guān)的所有信息:hw_interrupt_type
、irq_desc_t
和 irqaction
,圖3 解釋了它們之間是如何關(guān)聯(lián)的。
圖 3:IRQ 結(jié)構(gòu)之間的關(guān)系
在 X86 系統(tǒng)中,對于 8259A 和 I/O APIC 這兩種不同類型的中斷控制器,hw_interrupt_type
結(jié)構(gòu)體被賦予不同的值,具體區(qū)別參見表 2。
8259A | I/O APIC |
---|---|
static struct hw_interrupt_type i8259A_irq_type = { "XT-PIC", startup_8259A_irq, shutdown_8259A_irq, enable_8259A_irq, disable_8259A_irq, mask_and_ack_8259A, end_8259A_irq, NULL }; | static struct hw_interrupt_type ioapic_edge_type = { .typename = "IO-APIC-edge", .startup = startup_edge_ioapic, .shutdown = shutdown_edge_ioapic, .enable = enable_edge_ioapic, .disable = disable_edge_ioapic, .ack = ack_edge_ioapic, .end = end_edge_ioapic, .set_affinity = set_ioapic_affinity, }; static struct hw_interrupt_type ioapic_level_type = { .typename = "IO-APIC-level", .startup = startup_level_ioapic, .shutdown = shutdown_level_ioapic, .enable = enable_level_ioapic, .disable = disable_level_ioapic, .ack = mask_and_ack_level_ioapic, .end = end_level_ioapic, .set_affinity = set_ioapic_affinity, }; |
在中斷初始化階段,調(diào)用 hw_interrupt_type
類型的變量初始化 irq_desc_t
結(jié)構(gòu)中的 handle
成員。在早期的系統(tǒng)中使用級聯(lián)的8259A,所以將用 i8259A_irq_type
來進(jìn)行初始化,而對于SMP系統(tǒng)來說,要么以 ioapic_edge_type
,或以 ioapic_level_type
來初始化 handle
變量。
對于每一個外設(shè),要么以靜態(tài)(聲明為 static
類型的全局變量)或動態(tài)(調(diào)用 request_irq
函數(shù))的方式向 Linux 內(nèi)核注冊中斷處理程序。不管以何種方式注冊,都會聲明或分配一塊 irqaction
結(jié)構(gòu)(其中 handler
指向中斷服務(wù)程序),然后調(diào)用 setup_irq()
函數(shù),將 irq_desc_t
和 irqaction
聯(lián)系起來。
當(dāng)中斷發(fā)生時,通過中斷描述符表 IDT 獲取中斷服務(wù)程序入口地址,對于 32≤ i ≤255(i≠128)
之間的中斷向量,將會執(zhí)行 push $i-256,jmp common_interrupt
指令。隨之將調(diào)用 do_IRQ()
函數(shù),以中斷向量為 irq_desc[]
結(jié)構(gòu)的下標(biāo),獲取 action
的指針,然后調(diào)用 handler
所指向的中斷服務(wù)程序。
從以上描述,我們不難看出整個中斷的流程,如圖 4 所示:
圖 4:X86中斷流
?
非常好我支持^.^
(1) 100%
不好我反對
(0) 0%
相關(guān)閱讀:
- [嵌入式技術(shù)] 了解Linux中斷處理原理 2019-05-14
( 發(fā)表人:admin )