作業系統核心

中斷描述表(IDT)與中斷向量

/ EYE-dee-tee /

當一個陷阱、例外或中斷觸發時,CPU 面對一個轉瞬之間的問題:處理這個特定事件的核心程式碼在哪裡?中斷描述表就是答案——一張由核心在開機期間建立的表,它把每一類事件對應到應處理它的核心函式位址。把它想成核心的緊急電話簿:撥事件號碼 N,它就把你直接接到正確的應答者。

每一類事件都被指派一個稱為中斷向量的小數字。在 x86 上有 256 個(0 到 255):低號的保留給 CPU 例外(向量 0 是除以零,向量 14 是分頁錯誤,依此類推),較高的用於裝置中斷與系統呼叫。IDT 是一個由那個向量號碼索引的 256 項陣列;每一項(一個「閘門描述子」)存放處理常式的位址,外加權限位元,說明哪些特權層級可以呼叫它。當事件號碼 N 發生時,CPU 自動讀取 IDT 第 N 項、切換到特權模式,並跳到存在那裡的處理常式位址——這全在硬體裡完成,早於任何核心 C 程式碼執行。核心透過載入一個暫存器告訴 CPU 這張表在哪裡(x86 上的 lidt 把 CPU 指向 IDT)。

為何它重要:IDT 是硬體事件與核心程式碼之間實實在在的接線,所以理解它能揭開分頁錯誤如何「神奇地」抵達分頁錯誤處理常式、或一個裝置的訊號如何找到它的驅動之謎。兩個誠實的提醒:每個閘門裡的權限位元是一項安全功能——它們阻止使用者程式碼呼叫它不該呼叫的處理常式——而 IDT 是 x86 特有的術語;其他架構有同樣的理念但名稱不同(ARM 用例外向量表),所以這個概念是普世的,即便「IDT」這個名字不是。

誤用這張表是災難性的:一個損壞或錯誤的項目,意味著 CPU 在下一次中斷時跳到垃圾位址,這是立即而無法復原的當機——這也是 IDT 被早早建立並小心守護的原因之一。

發生分頁錯誤 -> CPU 讀取 IDT[14] -> 跳到 do_page_fault()。每一項存放處理常式位址與特權位元。核心在開機時用 'lidt' 載入這張表的位置一次。

IDT 是一個以中斷向量為索引的陣列;CPU 用它在硬體中直接跳到相符的核心處理常式。

「IDT」與「中斷向量」是 x86 的名稱;這個概念(一張從事件號碼到處理常式的表)是普世的,但在別處叫不同的名字(ARM 例外向量等)。此外,每個閘門裡的特權位元是真正的安全邊界,而非簿記——它們決定使用者程式碼是否可以觸發那一項。

又称
IDTinterrupt vector tableinterrupt vector中斷向量表