30天自制操作系統日志第6天_第1頁
30天自制操作系統日志第6天_第2頁
30天自制操作系統日志第6天_第3頁
30天自制操作系統日志第6天_第4頁
30天自制操作系統日志第6天_第5頁
已閱讀5頁,還剩7頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、精選優質文檔-傾情為你奉上操作系統實驗日志學號姓名甘昆祿專業年級班級智能1601實驗日期2018.10.31實驗項目第6天:分段編譯與中斷處理一、 實驗主要內容1、 分割源文件分割文件的優劣:優劣(1)按照處理內容進行分類,如果分的好的話,將來進行修改時,容易找到地方。(5)源文件數量增加。(2)如果Makefile寫的好,只需要編譯修改過的文件,就可以提高make的速度。(就不用重新編譯全部的源文件)(6)分類分得不好的話,修改時不容易找到地方。(3)單個源文件都不長,多個小文件比大文件好處理。(4)更簡潔規范Bootpack.c的分割:Makefile根據bootpack.c的分割后應增加

2、的功能:2、 整理Makefile和頭文件Makefile里有很多相似的普通規則,這時候為了更加簡潔,我們可以引入一般規則,像下面這樣:make.exe會首先尋找普通的生成規則如果沒有找到,就嘗試用一般規則。普通生成規則要優于一般規則。將c文件里重復的聲明添加到.h頭文件中,然后在其余.c文件中增加#include “bootpack.h”表示告訴編譯器,這里要替換成指定的內容,然后進行編譯。頭文件名用(”“)表示該頭文件與源文件位于同一個文件夾里,而尖括號()則表示該頭文件位于編譯器所提供的文件夾里。3、 設定GDT這個函數用來將指定的段上限(limit)和地址賦值給名為GDTR的48位寄存

3、器。給GDTR賦值唯一的辦法是指定一個內存地址,從指定的地址讀取6個字節(48位),然后賦值給GDTR寄存器,完成這一任務的就是LGDT。該寄存器的低16位(即內存的最初2個字節)是段上限,它等于“GDT的有效字節數-1”。今后我們還會偶爾用到上限這個詞,意思都是表示量的大小,一般為“字節數-1”剩下的高32位(即剩余的4個字節),代表GDT的開始地址。DWORDESP+4里存放段上限(0x0000ffff),DWORDESP+8里存放地址(0x)。若是按字節寫出來就成了FF FF 00 00 00 27 00 00。用圖來描述棧就美滋滋:為了執行LGDT,作者希望把它們排列成FF FF 00

4、 27 00 00的樣子。所以就先”MOV AX, ESP+4”讀取最初的0xffff,然后再寫到ESP+6里。結果就成了FF FF FF FF 00 27 00 00,如果從ESP+6開啟讀6個字節的話正好是想要的結果,即如下圖:然后講set_segmdesc函數:這個函數是按照CPU的規格要求,將段的信息歸結成8個字節寫入內存。填入內容在前一章已經提到過。首先是段的地址。地址用32位表示,稱為段的基址(base)。在這里分為low(2字節),mid(1字節)和high(1字節)3段,合起來32位。是為了與80286時代的程序兼容才分為三段。段上限最大4GB,但只能使用20位,指定到1MB為

5、止。為了擴大指定段的大小,段屬性里設置了一個標志位Gbit。當這個標志位位1時,limit的單位不解釋成字節(BYTE),而解釋成頁(page,有4KB)。這樣4KBx1M=4GB。20位的段上限分別寫到limit_low和limit_high里。段屬性,又稱為“段的訪問控制權屬性”,在程序中用變量名access_right或ar來表示。因為12位段屬性中的高4位放在limit_high的高4位里,所以程序里有意把ar當做如下的16位構成來處理: xxxx0000xxxxxxxx(其中x是1或1)ar的高四位被稱為“擴展訪問權”GD00Gbit指段模式 1指32位模式 0指16位模式 除運行8

6、0286程序外,通常都使用D=1ar的低8位:(0x00)未使用的記錄表(description table)(0x92)系統專用,可讀寫的段。不可執行。Ring0系統模式(0x9a)系統專用,可執行的段。可讀不可寫。(0xf2)應用程序專用,可讀寫的段。不可執行。Ring3應用模式(0xfa)應用程序專用,可執行的段。可讀不可寫。CPU到底是處于系統模式還是應用模式取決于執行中的應用程序是位于訪問權為0x9a的段,還是位于訪問權為0xfa的段。前者為系統模式。4、 初始化PIC要使用鼠標必須使用中斷,將GDT和IDT正確無誤地初始化。同時還要初始化PIC(programmable inter

7、rupt controller),“可編程中斷控制器”。PIC是將8個中斷信號集合成一個中斷信號的裝置。與CPU直接相連的PIC稱為主PIC(master PIC),與主PIC相連的PIC稱為從PIC(slave PIC)。主PIC負責處理第0到第7號中斷信號,從PIC負責8到15.PIC的初始化: int.c的主要內容:#include bootpack.hvoid init_pic(void)/* PIC的初始化 */ io_out8(PIC0_IMR, 0xff ); /* 禁止所有中斷 */ io_out8(PIC1_IMR, 0xff ); /* 禁止所有中斷 */ io_out8(

8、PIC0_ICW1, 0x11 ); /* 邊沿觸發模式(edge trigger mode) */ io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接收 */ io_out8(PIC0_ICW3, 1 vram, binfo-scrnx, 0, 0, COL8_FFFFFF, *INT 21 (IRQ-1) : PS/2 kwyboard*); for (;) io_hlt(); 這個函數就是產生21號中斷(鍵盤中斷)時程序跳往的地方,也就是在屏幕的開頭輸出*INT 21 (IRQ-1) : PS/2 kwyboard*這段文字。Inthandle2

9、1接收了esp指針的值,但函數中沒有使用。中斷處理完成后要返回原程序,不能執行“return”但必須執行IRSTD指令,這個指令還是得用nas寫。EXTERN _inthandler21, _inthandler27, _inthandler2c_asm_inthandler21: PUSH ES PUSH DS PUSHAD MOV EAX,ESP PUSH EAX MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler21 POP EAX POPAD POP DS POP ES IRETD數據結構的時候我們詳細的講過棧這個數據類型,這里作者講了緩沖區分

10、類。棧屬于緩沖區。緩沖區有兩種:一種是將信息從上面逐漸加入進來,需要時再從下面一個個取出。最先加入的信息也最先取出,所以這種緩沖區是“先進先出”,簡稱FIFO。還有一種緩沖區是信息從上加入,也從最上面開始取。所以這種緩沖區是“先進后出”,簡稱FILO。棧正是FILO型的緩沖區,PUSH將數據壓入棧頂,POP將數據從棧頂取出。PUSH EAX這個指令相當于:ADD ESP, -4MOV SS:ESP, EAXPOP EAX指令相當于:MOV EAX, SS:ESPADD ESP,4還有一個不常見的指令PUSHAD相當于:PUSH EAXPUSH ECXPUSH EDXPUSH EBXPUSH E

11、SPPUSH EBPPUSH ESIPUSH EDI反過來POPAD指令同上相反順序。函數_asm_inthandler21的目的是保存中斷現場的值,然后將該函數注冊到IDT中去。/* IDT的設定 */ set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8,

12、AR_INTGATE32);asm_inthandler注冊在idt的第0x21號,2*8表示的是asm_inthandler的屬于哪一個段,即段號是2,乘以8是因為低3位有著別的意思,所以低三位必須是0。所以“2*8”也可以寫成“23”或者16。號碼為2的段:set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);這個語句說明這個段正好涵蓋了整個bootpack.hrb。最后的AR_INTGATE32將IDT的屬性設定為0x008e,表示這是用于中斷處理的有效設定。二、遇到的問題及解決方法1、set_segmdesc函數中關

13、于limit /= 0x1000的理解;我們看到段上限是20位,這樣段最大也只能指定到1MB,所以才有設置標志位Gbit為1,使limit的單位為頁,而不是字節,那么具體如何實現呢?就是要讓相應數字除以一頁的字節數。所以這個也就好理解了。Limit沒超過0xffff時就用字節為單位,超過就使用頁為單位,并將單位換算,也就是進行limit /= 0x1000的處理。2、鍵盤中斷是怎么實現的;首先就是我們進行了一個PIC初始化的工作(上面有代碼),將原來設置電腦時設置好的對應中斷和中斷號對應了起來。初始化成功后,程序就能接收到外部的中斷的信號了,只是還沒弄好對應的中斷程序和中斷序列表而已了。然后我們進行idt的初始化,然后將中斷函數的初始地址等信息放入到idt即中斷序列表中。當電腦接收到相應的鍵盤信號后,就會尋找相應的idt序號,并跳轉到相應的程序執行。這里就是事實上跳轉到這里后CPU就停止在鍵盤中斷函數里了。三、程序設計創新點1、這次學了中斷,然后上次的動態條就可以改變停止方式了。程序運行結果:這次在主函數加上上次一個實現動態等待條的代碼即可,鍵盤中斷后CPU進入掛起的狀態。動態條停止。等待條代碼(函數dtiao())和上次實現時的相

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論