天天看點

計算機系統引導過程

從BIOS啟動到Kernel加載

大家天天使用電腦,有沒有想過整個系統是如何啟動的?從你按下電源鍵,到顯示登入界面,中間究竟經曆了什麼?

本文主要講述加載計算機核心系統的全過程,主要參考了MIT 6.828lab1實驗以及其他參考資料。某些位址、行為在不同計算機上可能不同,這裡僅用JOS系統做例子,重要的是了解整個過程。

-----------------------------------記憶體示意--------------------------------------
    
+------------------+  <- 0x00100000 (1MB)
|     BIOS ROM     |  <- 0x000FFFF0 (BIOS起始位址)
+------------------+  <- 0x000F0000 (960KB)
|  16-bit devices, |
|  expansion ROMs  |
+------------------+  <- 0x000C0000 (768KB)
|   VGA Display    |
+------------------+  <- 0x000A0000 (640KB)
|                  |
|    Low Memory    |  <- 0x00007C00 (Boot Loader将要載入的位址)
|                  |
+------------------+  <- 0x00000000
           

第一步 從BIOS開始

首先,我們必須知道,程式隻有加載到記憶體中後,才能被使用。由于某些曆史原因,計算機在開機時運作于實模式下,實模式采用16位尋址模式,最大尋址空間為1MB,即在實模式下,CPU僅能通路到1MB的記憶體位址,而BIOS就被固化在這1MB中(實際會更複雜一些,BIOS存儲在可讀寫ROM中,通過硬接線到實體位址0x000f0000-0x000fffff)。

CPU硬體邏輯設計為在加電瞬間強行将CS值置為0XF000,IP為0XFFF0。該CS:IP位址正是BIOS程式的入口位址。是以,一旦接通電源,計算機将從BIOS指令開始執行。

  1. BIOS首先對機器進行加電自檢(POST),目的是檢查電腦各部件是否良好,包括加載顯示卡、檢查記憶體總量等操作。
  2. 而後,BIOS将開始初始化工作,主要是設定中斷向量表、對外部裝置進行一些初始化和檢查工作。
  3. 完成一系列初始化工作後,BIOS将磁盤中的第一個扇區載入到記憶體中(放在 0x7c00-0x7dff 處),該扇區為引導扇區,存儲着Boot Loader程式(引導程式)。之後,BIOS使用跳轉指令到0x7c00(Boot Loader程式入口)處,将計算機的控制權交給Boot Loader程式,由其繼續進行Kernel的引導。

第二步 Boot Loader加載Kernel

在JOS中,Boot Loader包括boot.S彙程式設計式和main.c兩個部分

BIOS使用跳轉指令後,來到0x7c00,即boot.S的入口。

boot.S主要是将處理器從實模式轉換到 32 位的保護模式,讓CPU可以通路到1MB以上的記憶體區域

  1. 首先,初始化常用寄存器
  2. 而後,打開A20位址線,讓程式可以通路1MB以上的記憶體位址。
  3. 加載全局描述符表,打開保護模式
  4. 跳轉到main.c程式位址,執行bootmain函數

bootmain函數負責從硬碟中将kernel讀入到記憶體之中。如何讀取的呢?首先,bootmain從第一個扇區開始讀入4K資料(引導扇區一般稱為第0個扇區),該資料為ELF頭和程式頭表,儲存着整個Kernel的位址、格式資訊,獲得了一系列資訊後,按表中資料将核心讀入到記憶體0x00100000中。至此核心已經被轉載至記憶體中。最後,bootmain函數跳轉到Kernel的入口處,将計算機控制權交給核心。

繼續閱讀