操作系統是如何啓動的

Part1 系統啓動

這篇文章,要講操作系統是如何啓動的,操作系統啓動的過程十分值得我們學習,這篇文章的內容也能很好的的把後面的內容串了起來,幫助大家樹立一個對操作系統的直觀印象。我們可以把操作系統的啓動分爲讀入內存切換保護模式啓動段頁式系統初始化四個階段。

在這裏也要提前說一下,大家會在操作系統源碼中見到一部分源碼是 c 語言寫的,一部分源碼是彙編寫的。爲什麼一部分源碼用匯編寫我們等會解釋,現在主要是想說這個系列的文章會提到一些比較重要的源碼中的彙編指令,但是大家不會彙編也不要擔心,我在提到彙編指令時都會特別介紹,只要你知道這條彙編指令是做什麼的就行。

我們先畫個流程圖看下操作系統啓動的整體流程:

其實操作系統主要講的就是把我們裝在磁盤中的操作系統載入內存,並且進行相應初始化的過程。下面我們來一步步拆解流程:

1 第一階段 -- 讀入內存

計算機的運轉其實就是不斷的進行 “取指 - 執行” 的這個過程,而取指就是從內存中取指。大家都知道,我們在裝系統的時候會把操作系統裝在磁盤裏。既然要啓動操作系統,那麼要做的第一步自然就是把存在磁盤中的操作系統讀入內存的指定位置中。

計算機硬件廠商在只讀存儲器 ROM (ROM 的特點是一次寫入反覆讀取,RAM 斷電後存的數據就沒了中開闢了一塊空間,這段空間被稱爲 BIOS(basic input/output system)。BIOS 大家應該都見過,但具體的功能可能說不清,其實 BIOS 中放置的代碼是對 基本硬件的測試代碼,以及一些讓用戶調用硬件基本輸入輸出功能的子程序。計算機加電後最先做的事就是要把尋址的 PC (程序計數器)指向存放 BIOS 的地方。BIOS 主要能幹兩件事;(1)檢測硬件。如果硬件有問題,大家看到計算機就卡在初始頁面了,大家可能也有過計算機硬盤損壞然後卡在開機界面的經歷;(2)BIOS 提供中斷功能。大家要明確,BIOS 的輸入輸出功能也是以中斷調用形式提供給用戶的,在第三階段操作系統接管中斷以前,都是用的 BIOS 中斷。通過第一步,如果 BIOS 檢測硬件正常,就利用 BIOS 的中斷將啓動磁盤上啓動扇區中的內容讀入到內存中

啓動扇區中的內容就是文件 bootsect.s(是一個彙編文件)。我們接着看 bootsect.s 中的代碼做了什麼。bootsect.s 主要做了三件事:

(1)把 setup.s 文件讀到內存的指定位置。第二階段啓動保護模式就要靠 setup.s 這個文件。

(2)顯示系統標識。這裏就需要調用 BIOS 提供的中斷了,我推薦的哈工大李治軍老師的《操作系統》課程裏的一個配套實驗就是修改這裏,讓操作系統打出自己的 logo,建議大家做一下。

(3)把 system(進程模塊、內存模塊、設備驅動等)讀到系統的指定位置。

注意,我一直在強調要把這些模塊讀到內存的指定位置,這也是用匯編的真正原因。操作系統的啓動過程中,從哪裏取指、賦值給哪裏、執行完後跳到哪裏繼續都是有嚴格要求的。C 程序經過編譯後好多細節都是不可控的,所以要用匯編。我們通過下面的流程圖把執行過程再進行一個整理。

2 第二階段 -- 啓動保護模式

bootsect.s 把該讀入的文件讀入後,要爲系統初始化做準備了。那麼就要開始執行讀入的 setup.s 文件了。setup.s 文件主要做了兩件事:(1)獲取硬件參數(比如內存和硬盤大小等等) (2)將實模式切換爲保護模式。我們這裏還是強調將實模式切換成保護模式這件事,理解了這裏對於大家對操作系統的理解會更進一步。

在這裏說一下爲什麼要從實模式切換成保護模式,主要有兩個原因:

(1)實模式的尋址方式爲段基址左移四位加偏移,內存尋址範圍只在 1M 以內。而切換成保護模式後,32 位機的尋址範圍就內達到 4G(大家可能也聽說過 32 位系統不適配 4G 以上的內存。

(2)另外一個原因是實模式對於內存的訪問不會有任何保護,誰來了也能訪問,而保護模式可以對內存的訪問進行一定的限制。這對操作系統來說很重要,如果操作系統不能保護內存,使得每個進程都能直接對任意內存進行訪問,併發時會出大問題。

對於實模式和保護模式的區別這篇文章就講這麼多,今天主要對操作系統有個直觀映像。我專門寫了一篇文章詳細解讀保護模式和實模式的區別以及其原理,下週發。

3 第三階段 -- 啓動段頁

操作系統進入 32 位的保護模式後,緊接着要執行一段名爲 head.s 的代碼。head.s 主要做以下幾件事:

(1)設置中斷表。

這裏先給大家簡單介紹一下中斷是什麼。操作系統中是把 CPU 對系統發生某個事件做出反應的行爲都叫做中斷。比如敲擊鍵盤後,系統做出響應,這種就叫 I/O 中斷;剛纔第一階段時 BIOS 的輸入輸出功能也是一種中斷;後面文章講到系統調用也是通過中斷。爲什麼要在這個時候設置中斷表呢?剛把 BIOS 載入時,操作系統使用的是 BIOS 中斷,而現在 BIOS 中斷已經不能用了。另外不同的操作系統遇到不同中斷反應是有差別的,所以操作系統是必須要接管中斷的。

(2)設置 GDT 表

GDT 表是切換到保護模式後要用到的,GDT(Global Descriptor Table) 表也叫全局描述表,是一個很重要的數據結構。對於保護模式下的尋址以及控制權限很重要。今天瞭解就好,下一篇展開講保護模式時在詳細介紹這個東西。在第二階段執行 setup.s 時建立了一個臨時的 GDT 表,現在進入 system 模式,需要重新建立 GDT 表

(3)設置頁表

這個涉及到分頁,以後講內存管理時會詳細講,大家記住在這裏幹了這麼個事就好了。

4 第四階段

這一階段操作系統開始初始化並運行了,這一階段就用上 c 語言了,主要做的是初始化各種管理軟硬件資源的數據結構,可以調用各種初始化函數來完成相應的初始化操作。咱們來看一段 main 函數的代碼:

void main(void)
{
    ......
    mem_init(memory_start, memory_end);
    hd_init();
    ......
    sti();
    move_to_user_mode();
    if(!fork()){init();}
    for(;;){pause();}
}

咱們一個一個的函數看,mem_init(memory_start, memory_end) 中 memory_start 表示起始內存地址,memory_end 表示結束內存地址。系統內核 system 分配到 0~1 MB,磁盤高速緩存分配在 1- 4MB,所以 memory_start 是 4 MB,mem_init() 就是爲了初始化 4MB 以後的內存空間。初始完內存,接着就用 hd_init() 初始化硬盤。sti() 大家可能有點陌生,這個和系統調用相關;move_to_user_mode() 大家直接翻譯就能知道他啥意思了吧,切換用戶態,大家應該很耳熟,用戶態和內核態的區別等講系統調用的時候寫。再後面的 fork 大家應該會比較眼熟了,要開啓進程了。

CS 指南 編程必備基礎知識、數據結構和算法、操作系統、計算機網絡、計算機組成原理

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/MKC7nCcYm1Uab_HYCKnRyg