mit-6.828 boot/boot.S 原始碼閱讀
阿新 • • 發佈:2020-07-31
- boot/boot.S
-
該檔案的目的:
- start CPU, switch to 32-bit protected mode(啟動CPU 並且最終轉到32-bit 保護模式)
- BIOS loads code from first sector of the hard disk into memory at physical addr 07xc00
- executing in real mode (%cs=0, %ip=7c00)
-
步驟:
- 初始化重要的segment registers,全部初始化為0
- 16位指令下,遮蔽中斷,初始化段暫存器
- 開啟A20 gate,停止取模運算,將高位的空間也可訪問
- 利用bootstrap GDT轉換到protected mode
- 跳轉到32-bit模式下的下一個指令
- 然後在32-bit 保護模式下,設定保護模式的暫存器
- 設定stack pointer 然後呼叫main.c執行main.c裡面的bootmain函式
-
關於開啟A20 gate的程式碼部分解析:
11 # Enable A20: 12 # For backwards compatibility with the earliest PCs, physical 13 # address line 20 is tied low, so that addresses higher than 14 # 1MB wrap around to zero by default. This code undoes this. 15 seta20.1: 16 inb $0x64,%al # Wait for not busy 17 testb $0x2,%al 18 jnz seta20.1 19 movb $0xd1,%al # 0xd1 -> port 0x64 20 outb %al,$0x64 21 seta20.2: 22 inb $0x64,%al # Wait for not busy 23 testb $0x2,%al 24 jnz seta20.2 25 movb $0xdf,%al # 0xdf -> port 0x60 26 outb %al,$0x60
這部分指令就是在準備把CPU的工作模式從真實模式轉換為保護模式。我們可以看到其中的指令包括inb,outb這樣的IO埠命令。所以這些指令都是在對外部裝置進行操作。根據下面的連結:
http://bochs.sourceforge.net/techspec/PORTS.LST
我們可以檢視到,0x64埠屬於鍵盤控制器804x,名稱是控制器讀取狀態暫存器。下面是它各個位的含義。
所以16~18號指令是在不斷的檢測bit1。bit1的值代表輸入緩衝區是否滿了,也就是說CPU傳送給控制器的資料,控制器是否已經取走了,如果CPU想向控制器傳送新的資料的話,必須先保證這一位為0。所以這三條指令會一直等待這一位變為0,才能繼續向後執行。
當0x64埠準備好讀入資料後,現在就可以寫入資料了,所以19~20這兩條指令是把0xd1這條資料寫入到0x64埠中。當向0x64埠寫入資料時,則代表向鍵盤控制器804x傳送指令。這個指令將會被送給0x60埠。
通過圖中可見,D1指令代表下一次寫入0x60埠的資料將被寫入給804x控制器的輸出埠。可以理解為下一個寫入0x60埠的資料是一個控制指令。
然後21~24號指令又開始再次等待,等待剛剛寫入的指令D1,是否已經被讀取了。
如果指令被讀取了,25~26號指令會向控制器輸入新的指令,0xdf。通過查詢我們看到0xDF指令的含義如下
這個指令的含義可以從圖中看到,使能A20線,代表可以進入保護模式了。
注:部分資料來自網路