標籤:
一 中斷分類
根據中斷源不同,可以將中斷分為
硬體中斷源又可以分為
通過處理器的INTR pin接收的插斷要求,典型地,INTR串連到8259A PIC上,在支援APIC的處理器上,LINT0被作為INTR串連到外部中斷控制器上
通過Local APIC產生的本地中斷源
來自晶片集上的I/O APIC產生的中斷資訊
- 不可屏蔽中斷:通過處理器NMI pin接收的插斷要求是不可屏蔽的,在支援APIC的處理器上INTR1 pin被作為NMI pin使用,接收來自外部的NMI訊號
二 中斷控制器
- 以前的8259A PIC(8259可程式化插斷控制器)
在單一處理器上,處理器的INTR pin接收來自外部8259中斷控制器傳送過來的插斷要求,其位於PCI-to-ISA bridge(南橋)晶片的LPC控制器裡。
每個8259A PIC的IR口都串連著一條IRQ線。主片的IR0到IR7對應著IRQ0到IRQ7線,但是IR2串連著從片的INTR pin。從片的IR0到IR7對應著IRQ8到IRQ15線。由於從片串連到主片的IR2上,所以從片的IR1同時串連到IRQ2和IRQ9。
在8259A中,主片IR0的插斷要求優先順序最高,主片IR7最低,從片IR0-7所有插斷要求優先順序都相當於IRQ2。所以IRQ線的優先順序由高到低次序為IRQ0,IRQ1,IRQ8-15,IRQ3-7。
為了適應多處理器,Intel在Pentium處理器開始引入了APIC(Advanced Programmable Interupt Controller)機制。
APIC經曆了4個版本,82489DX晶片,APIC,xAPIC,x2APIC。xAPIC共有256個IRQ線,而x2APIC比xAPIC多了256個,總共512條IRQ線。
三 插斷要求級IRQL
在APCI中,每個IRQ都有各自的優先順序,一個正在啟動並執行線程可能被中斷打斷,進入到中斷處理函數,當遇到優先順序更高的中斷,處在低優先順序的中斷也會被打斷,進入到更進階的中斷處理函數。
windows將中斷的概念進行了擴充,提出了插斷要求級的概念,數字低的優先順序高,其中不僅包括了APIC的所有中斷,也包括了3個軟體中斷。
使用者模式的代碼運行在最低優先順序PASSIVE_LEVEL。驅動中的DriverEntry,派遣函數,AddDevice等函數一般運行在PASSIVE_LEVEL,在必要的時候可申請進入DISPATCH_LEVEL函數。
需要特別注意的是,windows負責線程調度的組件是運行在DISPATCH_LEVEL層級,當前的線程運行完時間片後,系統自動從PASSIVE_LEVEL層級提升到DISPATCH_LEVEL層級。當線程切換完畢後,作業系統又從DISPATCH_LEVEL降到PASSIVE_LEVEL。驅動程式的StartIO函數和DPC函數也運行在DISPATCH_LEVEL層級。在核心模式,可以通過KeGetCurrentIrpl核心功能來得到當前的IRQL層級。
四 代碼中斷級
PASSIVE_LEVEL比DISPATCH_LEVEL低,在實際編程中,許多具有比較複雜功能的核心API都要求在PASSIVE下運行,而只有比較簡單的API能在DISPATCH級執行。
在調用任何一個核心API前,必須查看WDK文檔,瞭解這個核心API的中斷要求
中斷級的簡單判斷方法
如何判斷我們正在編寫的代碼的中斷級呢?暫時可以使用下面規則來處理。
- 規則1:如果在調用路徑沒有特殊情況(導致中斷級的提高或降低),則一個函數的中斷級與調用源的中斷級相同;
- 規則2:如果在調用路徑上有擷取自旋鎖,則中斷級隨之升高;如果有釋放自旋鎖,則中斷級隨之降低。
如果當前代碼運行在DISPATCH級,而我們又必須調用PASSIVE級的核心API,使用核心API強制降低當前的插斷要求級是不被允許的,windows的代碼都運行在規範的中斷級上,任意降低中斷級都會導致不可預料的後果。
這樣的問題有很多種解決方案,比如產生一個專門的線程去執行PASSIVE級的代碼。
本文連結:http://www.cnblogs.com/cposture/p/4782880.html
【原創】淺說windows下的插斷要求級IRQL