中斷描述符表(Interrupt Descriptor Table,IDT)

中斷描述符表(Interrupt Descriptor Table,IDT)將每一個異常或 中斷向量分別與它們的處理過程聯繫起來。與GDT和LDT表相似,IDT也是由8字節長描述符組成的一個數組。
#pragma pack(push, 1)
//IDT的內存空間是一個數組。每一個元素都有以下的結構
typedef struct P2C_IDT_ENTRY_ {
    P2C_U16        offset_low;
    P2C_U16        selector;
    P2C_U8        reserved;
    P2C_U8        type:4;
    P2C_U8        always0:1;
    P2C_U8        dpl:2;
    P2C_U8        present:1;
    P2C_U16        offset_high;
}P2C_IDTENTRY, *PP2C_IDTENTRY;
#pragma pack(pop)

 

中斷描述符表
能夠包含描述符。爲了構成IDT表中的一個索引值,處理器把異常或中斷的向量號乘以8。由於最多隻
有256箇中斷或異常向量,因此IDT無需包含多於256個描述符。IDT中能夠含有少於256個描述符,由於
只有可能發生的異常或中斷才須要描述符。不過IDT中全部空描述符項應該設置其存在位(標誌)爲0
//
//如今這個中斷門沒有用了,設置type = 0使之空閒
//
idt_addr[old_id].type = 0;
IDT表能夠駐留在線性 地址空間的任何地方,處理器使用IDTR 寄存器來定位IDT表的位置。這個寄存器
中含有IDT表32位的基地址和16位的長度(限長)值。IDT表基地址應該對齊在8 字節
界上以提升處理器的訪問效率。限長值是以 字節爲單位的IDT表的長度。
#pragma pack(push, 1)
//從sidt指令得到一個以下的結構,從這裏能夠獲得IDT的開始地址
typedef struct P2C_IDTR_ {
    P2C_U16        limit; // 範圍
    P2C_U32        base; //基地址
}P2C_IDTR, *PP2C_IDTR;
#pragma pack(pop)

 

中斷描述符表IDT和寄存器IDTR
LIDT和SIDT指令分別用於加載和保存IDTR寄存器的內容
LIDT指令用於把內存中的限長值和基地址操做數加載到IDTR寄存器中。該指令僅能由當前 特權級CPL是0的代碼執行,一般被用於建立IDT時的操做
系統初始化代碼中。
SIDT指令用於把IDTR中的基地址和限長內容複製到內存中。該指令可在任何特權
級上執行。
VOID    *p2cGetIdt()
{
    PAGED_CODE();

    P2C_IDTR idtr;

    //
    //一句彙編讀取到IDT的位置
    //
    _asm sidt idtr;
    return (void *)idtr.base;
}
 
若是中斷或異常向量引用的描述符超過了IDT的界限,處理器會產生一個通常保護性異常
在實地址模式中CPU把內存中從0開始的1K字節做爲一個中斷向量表。表中的 每一個表項佔四個字節,由兩個字節的 段地址和兩個字節的 偏移量組成,這樣構成的地址即是相應 中斷處理程序的入口地址。可是,在保護模式下,由四 字節的表項構成的 中斷向量表顯然知足不了要求。這是由於,除了兩個字節的 段描述符偏移量必用四字節來表示;‚要有反映 模式切換的信息

 
在保護模式下中斷向量表中的表項由8個字節組成,中斷向量表也改叫作中斷描述符表IDT(InterruptDescriptor Table)。其中的每一個表項叫作一個門描述符(gate descriptor),「門」的含義是當中斷髮生時必須先經過這些門,而後才能進入相應的處理程序。
#pragma pack(push, 1)
//IDT的內存空間是一個數組。每一個元素都有以下的結構
typedef struct P2C_IDT_ENTRY_ {
    P2C_U16        offset_low;
    P2C_U16        selector;
    P2C_U8        reserved;
    P2C_U8        type:4;
    P2C_U8        always0:1;
    P2C_U8        dpl:2;
    P2C_U8        present:1;
    P2C_U16        offset_high;
}P2C_IDTENTRY, *PP2C_IDTENTRY;
#pragma pack(pop)
 
主要門描述符是:
· 中斷門(Interrupt gate)
其類型碼爲110,中斷門包含了一箇中斷或 異常處理程序所在段的選擇符和段內 偏移量。當控制權經過中斷門進入 中斷處理程序時,處理器清IF標誌,即關中斷,以免嵌套中斷的發生。中斷門中的DPL(Descriptor Privilege Level)爲0,所以,用戶態的進程不能訪問Intel的中斷門。全部的 中斷處理程序都由中斷門激活,並所有限制在 內核態。
·  陷阱門(Trap gate)
其類型碼爲111,與中斷門相似,其惟一的區別是,控制權經過 陷阱門進入處理程序時維持IF標誌位不變,也就是說,不關中斷。
· 系統門(System gate)
這是Linux內核特別設置的,用來讓用戶態的進程訪問Intel的 陷阱門,所以,門描述符的DPL爲3。經過系統門來激活4個Linux 異常處理程序,它們的向量是三、四、5及128,也就是說,在用戶態下,可使用int三、into、bound 及int0x80四條 彙編指令
最後,在保護模式下,中斷描述符表在內存的位置再也不限於從地址0開始的地方,而是能夠放在內存的任何地方。爲此,CPU中增設了一箇中斷描述符表寄存器IDTR,用來存放中斷描述符表在內存的起始地址。中斷描述符表寄存器IDTR是一個48位的寄存器,其低16位保存中斷描述符表的大小,高32位保存IDT的 基址.
相關文章
相關標籤/搜索