《30天自制操作系統(tǒng)》學(xué)習(xí)筆記(六)
本文關(guān)鍵詞:30天自制操作系統(tǒng),由筆耕文化傳播整理發(fā)布。
《30天自制操作系統(tǒng)》學(xué)習(xí)筆記(六)
發(fā)表于2016/7/3 14:51:55 99人閱讀
分類: 操作系統(tǒng)
IDT學(xué)習(xí)心得
(一)什么是中斷?
通常被定義為一個事件,該事件改變處理器執(zhí)行的指令順序。例如通過鍵盤輸入、點擊鼠標等
(二)為什么要引入中斷?
因為CPU的處理速度遠高于外圍硬件設(shè)備的響應(yīng)速度,為了提高CPU的利用率,所以引入了中斷機制。當(dāng)某個設(shè)備發(fā)生變化時便會產(chǎn)生中斷,CPU就暫時停止正在處理的事務(wù),并做好接下來能夠繼續(xù)處理的準備,轉(zhuǎn)而執(zhí)行中斷程序。中斷執(zhí)行完以后,在調(diào)用事先設(shè)定好的函數(shù),返回處理中的任務(wù)。這樣CPu可以不用一直查詢外圍硬件設(shè)備的狀態(tài),而將精力放在處理任務(wù)上。
(三)由中斷機制引出的問題--當(dāng)發(fā)生中斷時,如何告訴CPU該做些什么?
通過中斷描述,中斷描述符包括了中斷門描述符、陷阱門描述符和任務(wù)門描述符
(四)中斷描述符如何存儲?
與GDT類似,中斷描述符也是在內(nèi)存中連續(xù)存儲,形成了一個中斷描述符表(Interruptor Descriptor Table,IDT),所以要想正確使用中斷,必須正確設(shè)置GDT和IDT。
(五)CPU如何查找IDT?
與GDT的原理一樣,利用了一個叫IDTR的寄存器(注意此處是寄存器,不是內(nèi)存了,需要和IDT區(qū)別對待)。GDTR中高32位表示GDT在內(nèi)存中的基地址,低16位表示表界限,所以就明確的給出了GDT在內(nèi)存中的存儲信息。
通過中斷門描述符的結(jié)構(gòu)圖可知,其中存儲了16位的段選擇符(Segment Selector),CPU根據(jù)這個段選擇符,從GDT中選擇相應(yīng)的段描述符(Segment Descriptor),并執(zhí)行相應(yīng)的代碼。如下圖。
(七)中斷向量又是什么?
其實每一種中斷(異常)都會對應(yīng)一個中斷向量號,具體有哪些中斷向量,可以看下表:
向量號 助記符 描述 類型 出錯碼 源
0 #DE 除法錯 Fault 無 DIV和IDIV指令
1 #DB 調(diào)試異常 Fault/Trap 無 任何代碼和數(shù)據(jù)的訪問
2 — 非屏蔽中斷 Interrupt 無 非屏蔽外部中斷
3 #BP 調(diào)試斷點 Trap 無 指令I(lǐng)NT 3
4 #OF 溢出 Trap 無 指令I(lǐng)NTO
5 #BR 越界 Fault 無 指令BOUND
6 #UD 無效(未定義)操作碼 Fault 無 指令UD2或無效指令
7 #NM 設(shè)備不可用(無數(shù)學(xué)協(xié)處理器) Fault 無 浮點或WAIT/FWAIT指令
8
#DF
雙重錯誤
Abort
有(0)
所有能產(chǎn)生異;騈MI或INTR
的指令
9
異常)
10 #TS 無效TSS Fault 有 任務(wù)切換或訪問TSS時
11 #NP 段不存在 Fault 有 加載段寄存器或訪問系統(tǒng)段時
12 #SS 堆棧段錯誤 Fault 有 堆棧操作或加載SS時
13 #GP 常規(guī)保護錯誤 Fault 有 內(nèi)存或其他保護檢驗
14 #PF 頁錯誤 Fault 有 內(nèi)存訪問
15 — Intel保留,未使用
16 #MF x87FPU浮點錯(數(shù)學(xué)錯) Fault 無 x87FPU浮點指令或WAIT/FWAIT指令
17 #AC 對齊檢驗 Fault 有(0) 內(nèi)存中的數(shù)據(jù)訪問(486開始支持)
18
#MC
Machine Check
Abort
無
錯誤碼(若有的話)和源依賴于
具體模式(奔騰CPU開始支持)
19
#XF
SIMD浮點異常
Fault
無
SSE和SSE2浮點指令(奔騰三
開始支持)
20~31 — Inter保留,未使用
32~255 — 用戶定義中斷 Interrupt
上表中除了兩個Interrupt(中斷)外,其他還有三種Fault、Trap、Abort異常。我們這里討論的中斷主要是用戶定義中斷,這種中斷產(chǎn)生的原因有兩種:一是外部中斷,就是由硬件產(chǎn)生的中斷;另一種是由指令int n產(chǎn)生的中斷。
外部中斷的情況則復(fù)雜一些,因為需要建立硬件中斷和向量號之間的對應(yīng)關(guān)系。外部中斷的簡單示意圖如下:
(八)如何將中斷向量與中斷描述聯(lián)系起來
1.通過對8259A的配置,可將IRQ0~IRQ7對應(yīng)到中斷向量20h~27h,同樣地IRQ8~IRQ15可對應(yīng)到中斷向量28h~2Fh。書中給出的代碼如下:
void init_pic(void)
/* PIC初始化 */
{
io_out8(PIC0_IMR, 0xff ); /* 禁止所有中斷,主片 */
io_out8(PIC1_IMR, 0xff ); /* 禁止所有中斷,從片*/
//主片設(shè)置
io_out8(PIC0_ICW1, 0x11 ); /* 沿邊觸發(fā)模式 */
io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接收*/
io_out8(PIC0_ICW3, 1 << 2); /* PIC1由IRQ2連接*/
io_out8(PIC0_ICW4, 0x01 ); /*無緩沖區(qū)模式*/
//從片設(shè)置
io_out8(PIC1_ICW1, 0x11 );
io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15由INT28-2f接收 */
io_out8(PIC1_ICW3, 2 ); /*PIC1由IRQ2連接*/
io_out8(PIC1_ICW4, 0x01 );
io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1以外全部禁止 */
io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中斷*/
return;
}
2.制作中斷處理程序
3.注冊到IDT中
void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{
gd->offset_low = offset & 0xffff;
gd->selector = selector;
gd->dw_count = (ar >> 8) & 0xff;
gd->access_right = ar & 0xff;
gd->offset_high = (offset >> 16) & 0xffff;
return;
}
struct GATE_DESCRIPTOR *gd--表示要注冊的IDT位置
int offset--偏移(這個偏移是在代碼段中的偏移)
int selector--對應(yīng)的段描述符的選擇子
4.調(diào)用
例如set_getdesc(idt+0x21,(int)asm_inthandler21,2*8,AR_INTGATE32)
本文關(guān)鍵詞:30天自制操作系統(tǒng),由筆耕文化傳播整理發(fā)布。
,本文編號:317020
本文鏈接:http://sikaile.net/wenshubaike/mishujinen/317020.html