您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子百科>主機(jī)配件>主板>

Linux 2.6 中斷處理原理簡介

2010年02月05日 10:52 wenjunhu.com 作者:佚名 用戶評(píng)論(0
關(guān)鍵字:中斷處理原理(6282)

Linux 2.6 中斷處理原理簡介

中斷描述符表(Interrupt Descriptor Table,IDT)是一個(gè)系統(tǒng)表,它與每一個(gè)中斷或異常向量相聯(lián)系,每一個(gè)向量在表中存放的是相應(yīng)的中斷或異常處理程序的入口地址。內(nèi)核在允許中斷發(fā)生前,也就是在系統(tǒng)初始化時(shí),必須把 IDT 表的初始化地址裝載到 idtr 寄存器中,初始化表中的每一項(xiàng)。

當(dāng)處于實(shí)模式下時(shí),IDT 被初始化并由 BIOS 程序所使用。然而,一旦 Linux 開始接管,IDT 就被移到 ARM 的另一個(gè)區(qū)域,并進(jìn)行第二次初始化,因?yàn)?Linux 不使用任何 BIOS 程序,而使用自己專門的中斷服務(wù)程序(例程)(interrupt service routine,ISR)。中斷和異常處理程序很像常規(guī)的 C 函數(shù)

有三個(gè)主要的數(shù)據(jù)結(jié)構(gòu)包含了與 IRQ 相關(guān)的所有信息hw_interrupt_type、irq_desc_tirqaction,圖3 解釋了它們之間是如何關(guān)聯(lián)的。


圖 3:IRQ 結(jié)構(gòu)之間的關(guān)系
IRQ結(jié)構(gòu)之間的關(guān)系

在 X86 系統(tǒng)中,對(duì)于 8259A 和 I/O APIC 這兩種不同類型的中斷控制器,hw_interrupt_type 結(jié)構(gòu)體被賦予不同的值,具體區(qū)別參見表 2。

表 2:8259A 和 I/O APIC PIC 的區(qū)別
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)中使用級(jí)聯(lián)的8259A,所以將用 i8259A_irq_type 來進(jìn)行初始化,而對(duì)于SMP系統(tǒng)來說,要么以 ioapic_edge_type,或以 ioapic_level_type 來初始化 handle 變量。

對(duì)于每一個(gè)外設(shè),要么以靜態(tài)(聲明為 static 類型的全局變量)或動(dòng)態(tài)(調(diào)用 request_irq 函數(shù))的方式向 Linux 內(nèi)核注冊(cè)中斷處理程序。不管以何種方式注冊(cè),都會(huì)聲明或分配一塊 irqaction 結(jié)構(gòu)(其中 handler 指向中斷服務(wù)程序),然后調(diào)用 setup_irq() 函數(shù),將 irq_desc_tirqaction 聯(lián)系起來。

當(dāng)中斷發(fā)生時(shí),通過中斷描述符表 IDT 獲取中斷服務(wù)程序入口地址,對(duì)于 32≤ i ≤255(i≠128) 之間的中斷向量,將會(huì)執(zhí)行 push $i-256,jmp common_interrupt 指令。隨之將調(diào)用 do_IRQ() 函數(shù),以中斷向量為 irq_desc[] 結(jié)構(gòu)的下標(biāo),獲取 action 的指針,然后調(diào)用 handler 所指向的中斷服務(wù)程序。

從以上描述,我們不難看出整個(gè)中斷的流程,如圖 4 所示:


圖 4:X86中斷流
?

非常好我支持^.^

(1) 100%

不好我反對(duì)

(0) 0%

相關(guān)閱讀:

( 發(fā)表人:admin )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?