1. 程式人生 > 實用技巧 >mit-6.828 boot/boot.S 原始碼閱讀

mit-6.828 boot/boot.S 原始碼閱讀

- boot/boot.S

  • 該檔案的目的:

    1. start CPU, switch to 32-bit protected mode(啟動CPU 並且最終轉到32-bit 保護模式)
    2. BIOS loads code from first sector of the hard disk into memory at physical addr 07xc00
    3. executing in real mode (%cs=0, %ip=7c00)
  • 步驟:

    1. 初始化重要的segment registers,全部初始化為0
    2. 16位指令下,遮蔽中斷,初始化段暫存器
    3. 開啟A20 gate,停止取模運算,將高位的空間也可訪問
    4. 利用bootstrap GDT轉換到protected mode
    5. 跳轉到32-bit模式下的下一個指令
    6. 然後在32-bit 保護模式下,設定保護模式的暫存器
    7. 設定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線,代表可以進入保護模式了。

注:部分資料來自網路