天天看點

中斷描述符表IDT以及Linux核心IDT表的初始化的基本情況

IDT,Interrupt Descriptor Table,中斷描述符表是CPU用來進行中斷和程式異常的。

一 中斷和IDT表概要

    中斷可以由硬體産生(稱為外部中斷),也可以由軟體産生(稱為内部中斷),在程式中寫入int n指令可以産生n号中斷和異常(n從0-ffh)。

    每一種中斷對應一個中斷号。CPU執行中斷指令時,會去IDT表中查找對應的中斷服務程式(interrupt service routine ,ISR)。ISR(為了表述友善用ISR n表示n号中斷的處理程式),x86CPU最大可以支援256種中斷。

    不管運作的是什麼作業系統,隻要是運作于x86架構,IDT結構必然存在。IDT表中的ISRs應該由作業系統提供。

    Intel指定或保留了前32個中斷号的作用,作業系統可以指定其餘的中斷号的作用。

    中斷處理過程是由CPU直接調用的,CPU有專門的寄存器IDTR來儲存IDT在記憶體中的位置。程式可以使用LIDT和SIDT指令來讀寫IDTR。

    IDT是一個最大為256項的表,每個表項為8位元組。也稱為中斷門。

    中斷門和陷阱門描述中斷/異常處理程式的人口點。

二 Linux核心IDT表的初始化的基本情況

    linux核心的中斷描述符表IDT是一個全局的資料,在i386平台上被定義為:

struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };

摘自arch/kernel/i386/traps.c;

   其中每一個表項均是一個desc_struct結構,該結構被定以為:

struct desc_struct {

    unsigned long a,b;

};

摘自/inlcude/asm-i386/processor.h;

可以看出IDT表共256個表項,每一個表項是8個位元組,在idt_table數組被定義時靜态初始化為0。

作業系統啟動時,在setup32_up()函數中,會調用setup_idt()函數初始化IDT,該函數使用AT&T彙編寫成,在/arch/i386/kernel/head.S中;

其主要代碼如下:

    ......

    mov $256,%ecx

    rp_sidt:

    movl %eax,(%edi)

    movl %edx,4(%edi)

    addl $8,%edi

    dec %ecx

    ......

AT&T彙編:

    movl:mov long,四個位元組;

    引用寄存器要在寄存器号前加百分号%, 如"movl %eax, %ebx";

    使用立即數,要在數前面加符号$, 如"movl $0x04, %ebx";

繼續閱讀