初始化中斷描述表

2021-05-26 14:53:46 字數 3066 閱讀 7206

現在,我們知道了

80x86

微處理器在硬體級對中斷和異常做了些什麼,接下來,我們可以繼續描述如何初始化中斷描述表。

核心啟用中斷以前,必須把

idt表的初始位址裝到

idtr

暫存器,並初始化表中的每項。這項工作是在初始化系統時完成的。

int指令允許使用者態程序發出乙個中斷訊號,其值可以是

0~255

的任意乙個向量。因此,為了防止使用者通過

int指令模擬非法的中斷和異常,

idt的初始化必須非常小心。這可以通過把中斷或陷阱門描述符的

dpl欄位設定成

0來實現。如果程序試圖發出其中的乙個中斷訊號,控制單元將檢查出

cpl的值與

dpl欄位有衝突,並且產生乙個」

generalprotection」

異常。然而,在少數情況下,使用者態程序必須能發出乙個程式設計異常。為此,只要把中斷或陷阱門描述符的

dpl欄位設定成

3,即特權級盡可能一樣高就足夠了。

現在,讓我們來看一下

linux

是如何實現這種策略的。

中斷門、陷阱門及系統門

與在前面」中斷描述符表」中所提到的一樣,

intel

提供了三種型別的中斷描述符:任務門、中斷門及陷阱門描述符。

linux

使用與intel

稍有不同的細目分類和術語,把它們如下進行分類:

中斷門使用者態的程序不能訪問的乙個

intel

中斷門。所有的

linux

中斷處理程式都通過中斷門啟用,並全部限制在核心態。

系統門使用者態的程序可以訪問的乙個

intel

陷阱門。通過系統門來啟用三個

linux

異常處理程式,它們的向量是4,

5及128。因此,在使用者態下,可以發布

into

、bound

及int$0x80

三條組合語言指令。

系統中斷門

能夠被使用者態程序訪問的

intel

中斷門。與向量

3相關的異常處理程式是由系統中斷門啟用的,因此,在使用者態可以使用組合語言指令

int3

。陷阱門

使用者態的程序不能訪問的乙個

intel

陷阱門。大部分

linux

異常處理程式都通過陷阱門來啟用。

任務門不能被使用者態程序訪問的

intel

任務門。

linux

對」doublefault」

異常的處理程式是由任務門啟用的。

下列體系結構相關的函式用來

idt中插入門:

set_intr_gate(n,addr)

在idt的第n

個表項插入乙個中斷門。門中的段選擇符設定成核心**的段選擇符,偏移量設定成中斷處理程式的位址

addr

,dpl

字段設定成0。

set_system_gate(n,addr)

在idt的每n

個表項插入乙個陷阱門。門中的段選擇符設定成核心**的段選擇符,偏移量設定成中斷處理程式的位址

addr

,dpl

字段設定成0。

set_system_intr_gate(n,addr)

在idt的第n

個表項插入乙個中斷門。門中的段選擇符設定成核心**的段選擇符,偏移量設定成中斷處理程式的位址

addr

,dpl

字段設定成0。

set_trap_gate(n,addr)

與前乙個函式類似,只不過

dpl的字段設定成0。

set_task_gate(n,gdt)

在idt的第n

個表項插入乙個中斷門。門中的段選擇符存放乙個

tss的全域性描述符指標,該

tss中包含要被啟用的函式,偏移量設定成0,

dpl欄位設定成3。

idt的初步初始化

當計算機還執行在模式時,

idt被初始化並由

bios

例程使用。然而,一旦

linux

接管,idt

就被移到

ram的另乙個區域,並進行第二次初始化,因為

linux

沒有利用任何

bios

例程。idt

存放在idt_table

表中,有

256個表項。

6位元組的

idt_descr

變數指定了

idt的大小和它的位址,只有當核心用

lidt

彙編指令初始化

idtr

暫存器時才用到這個變數。

在核心初始化過程中,

setup_idt()

彙編函式用同乙個斷門來填充所有這

256個

idt_table

表項。用組合語言寫成的

ignore_int()

中斷處理程式,可以看作乙個空的處理程式,它執行下列動作:

在棧中儲存一些暫存器的內容。

呼叫printk()

函式列印」

unknowninterrupt」

系統訊息。

從棧恢復暫存器的內容。

執行iret

指令以恢復被中斷的程式。

ignore_int()

處理程式應該從不被執行,在控制台或日誌檔案中出現的」

unknowninterrupt」

訊息標誌著要麼是出現了乙個硬體問題,要麼就是出現了乙個核心的問題。

緊接著這個預初始化,核心將在

idt中進行第二遍初始化,用有意義的陷阱和斷處理程式替換這個空處理程式。一旦這個過程完成,對控制單元產生的每個不同的異常,

idt都有乙個專門的陷阱或系統門,而對於可程式設計中斷控制器確認的每乙個

irq,

idt都將包含乙個專門的中斷門。

在接下來的兩節中,將分別針對異常和中斷來詳細地說明這個工作是如何完成。

中斷和異常 中斷描述符表的初始化

一 中斷描述符表的初始化 從作業系統角度描述中斷描述符表的初始化。linux核心在系統的初始化階段需要進行大量的初始化工作,與中斷相關的工作有 初始化可程式設計控制器 中斷控制器 8259a 將中斷描述符表的起始位址載入idtr暫存器,並初始化表中的每一項。使用者程序通過int指令發出乙個中斷請求,...

zynq freeRTOS初始化中斷

問題描述 zynq7000 上 ps standalone裸跑,ps timer計時器中斷,pl ps中斷均工作正常,將 移植到freertos工程時,中斷不執行,task執行正常。解決 xilinx freertos 9.0.1 bsp,中有乙個檔案 portzynq7000.c.定義了乙個全域性...

Fw 中斷的初始化

要使用中斷肯定得初始化,這些初始化在系統啟動時已經為你做好了,但是我們還是來看看怎樣初始化的,這樣就能更好的理解中斷機制了。先看下面函式 355 void init init isa irqs void 356 else 381 382 上面的函式分為兩個部分,一 個是init 8259a 0 另乙...