核心內部與作業系統建構

中斷描述表(IDT)

/ I-D-T /

CPU 必須不斷對毫無預警就到來的事件做出反應——有人按下按鍵、網路封包抵達、計時器觸發,或程式本身做了違法的事,例如除以零。對每一種事件,CPU 都必須立即知道該執行哪個核心常式。中斷描述表(interrupt descriptor table,IDT)就是存放這些答案的查找表:一個編號清單,每一格指向處理某個特定事件的處理常式。把它想成 119 派遣中心的緊急呼叫路由表——當某種類型的警報進來時,表上明確指出該派哪位救援人員,毫不耽誤地搜尋。

具體來說,每個中斷與例外都有一個向量編號(在 x86 上為 0 到 255)。IDT 的第 N 項是一個描述符,告訴 CPU 處理向量 N 的處理常式位址,以及進入它的特權規則。當事件觸發時,硬體自己查到那一項、切換進核心模式、把被中斷情境的足夠內容(指令指標、旗標等)保存到核心堆疊,然後跳到處理常式。處理常式完成工作後,用一個特殊的「從中斷返回」指令返回,還原所保存的狀態,讓被中斷的程式碼彷彿什麼都沒發生地繼續。中斷可以巢狀——更高優先權的中斷可以中斷一個處理常式——這正是為什麼情境的保存/還原必須精確。核心在開機早期透過載入一個暫存器(在 x86 上是 lidt)告訴 CPU 這張 IDT 位於何處。

它之所以重要,是因為 IDT 是三件感覺不同、底層管線卻相同之事背後的單一機制:硬體中斷(非同步,來自裝置)、陷阱(同步且刻意,例如系統呼叫或除錯器斷點),以及錯誤(同步且意外,例如分頁錯誤或除法錯誤)。一個常見的混淆是把這三者當成毫不相干——它們全都透過一個 IDT 向量進入核心;差別只在於它們的來源,以及出錯的那道指令是否會被重試。

在 x86 上向量 14 是分頁錯誤。當程式碰觸一個不在記憶體中的頁時,CPU 查閱 IDT 的第 14 項、跳到核心的分頁錯誤處理常式,由它在磁碟上找到該頁、載入一個空閒頁框、更新分頁表,然後返回——CPU 重跑那道出錯的指令,這次便成功了。向量 0(除法錯誤)與系統呼叫路徑用的是同一套 IDT 機制,只是不同的項目。

中斷、陷阱與錯誤全都透過一個編號的 IDT 項目進入核心。

關鍵區別:中斷是非同步的(由裝置引起,與 CPU 當下在執行什麼無關),而陷阱或錯誤是同步的(由當前指令引起)。錯誤在修好問題後會重啟那道出錯的指令;陷阱則越過它繼續。把這些搞混,會導致對「程式碼何時、是否會恢復」的錯誤推理。

又稱
IDTinterrupt vector table中斷向量表