計算機是如何啟動的,網絡上很多博文1都從 BIOS 程序的加載開始說起,有的也跳到 BIOS 程序加載 Bootloader 階段。個人認為把這個過程稱為操作系統是如何被加載并啟動應該更加貼切一點。同時,也有計算機硬件大神的文章[1][5]詳細分析計算機加電的過程。在閱讀前人的優秀文章之后,歸納總結寫下了這篇文章以梳理從計算機上電之前到操作系統開始工作的整個過程。
開機鍵按下之前:黑暗中的一點星光
“滴答…滴答…”微弱的聲音有規律地響起。
“是誰?”從睡夢中醒來,身邊漆黑一片,我驚呼出聲。
“哇,終于有朋友過來陪我玩了。你好你好,我是 RTC (Real-Time Clock,實時時鐘)芯片,你可以叫我小 R,計算機世界的時間由我掌控哦,厲害吧~”,小R()得瑟地說。
我剛想說話,一個年邁爽朗的笑聲傳來,“哈哈,孩子,你又偷偷溜出來玩啦。”一位老爺爺走過來,慈祥地摸著小 R 的小腦袋說。
“家里太無聊了嘛,都沒人可以陪我一起玩,沒有"電",大家都不說話。對啦,這是我的電池爺爺,爺爺特別喜歡我,能讓我一直活躍著呢!”
我一拍腦袋,感情這是來到了計算機的世界呀,而且還是沒接入外部電源之前的計算機。在沒有外部電源的情況下,基本只有 RTC 和 CMOS 在 RTC 電源供電的情況下才能正常工作。“電池爺爺”一般是個紐扣電池。RTC 芯片保持機器內部的時鐘,這也是為什么我們的計算機關機之后再次啟動時間還是準確的(不考慮操作系統啟動后利用網絡同步時間)。而 CMOS 是電腦主板上的一塊可讀寫的RAM芯片。因為可讀寫的特性,所以在電腦主板上用來保存 BIOS 設置計算機硬件參數后的數據。在計算機領域,CMOS 常指保存計算機基本啟動信息(如日期、時間、啟動設置等)的芯片。
正回想著,突然天空一道光柱射向地面,后如溪流一般四處蔓延開來。“嘻嘻,有新朋友要醒來咯”,小 R 邊跳邊喊。“電池爺爺,您辛苦啦,回去休息吧,現在我能靠外面的能源生活啦。”
看來是外部的 ATX 電源接入了。ATX 會使用 +5VSB 電源喚醒一部分小伙伴,例如南橋(系統 I/O 芯片)、EC(嵌入式控制器,單片機)等。"+5V Stand-By 電壓為開機電路和需要喚醒機器的WOL(Wake-up On Lan)和 USB 等設備提供電源”[7],不會為 CPU 等提供工作電壓。
這里需要說明一下,實際上不同的主板、應用場景都會采用不同的電源時序控制方案,筆記本采用 EC,臺式機很多用SIO(Super I/O)或者定制芯片,嵌入式設備以及手機采用PMIC(Power Management IC)。以上的故事都是基于臺式機形式,但是我們選用 EC 來解釋電源時序控制過程,是考慮到國內關于 EC 的資料較多。與臺式機不同的一點是,筆記本因為有鋰電池的原因,在沒有接入電源適配器前,EC 以及南橋就已經處于工作狀態了。這也是為什么我們打開筆記本電腦,按下開機鍵,系統能接收到這個信號,并準備開始工作。
討論到這里,基本可以形成這樣一個概念:在關機狀態下,只有 RTC 、EC 以及南橋部分組件在工作。紐扣電池維持著計算機的時鐘信息(RTC的工作)和 CMOS 信息,而 EC 則在等待用戶按下開機鍵。當然 EC 還負責電池的充放電的檢測,指示燈,功能鍵等功能。
黎明:計算機開始運轉
主人說要有光,按下了神圣的開機鍵。EC 在黑暗中接收到這個PWRSW#信號,興奮地不行,立馬去通知南橋,“PM_PWRBTN#! PM_PWRBTN#! 我們的黎明到來啦!”。
“好啦,我知道!”,南橋回應 EC 三個信號SLP_S5#(退出 S5 關機狀態),SLP_S4#(退出 S4 休眠狀態),SLP_S3#(退出 S3 待機狀態)。
“ATX 電源,賦予我們光明吧!”EC 收到南橋發來的信號后,明白南橋已經準備就緒。ATX電源收到信號,開始工作,發出各路基本電壓給主板上的各個元件。然后發送PWROK#信號給 EC,并由 EC 轉發給南橋與北橋…經過一系列你來我往(這個流程必須嚴格控制,任意一步出錯都會造成計算機無法正常啟動),終于等到通知 CPU 老大的時刻啦。
”嘿,北橋大哥,我們叫 CPU 老大醒來指揮我們吧。我會告訴 CPU 老大電源都準備就緒啦。“,南橋發送PLT_RST#給北橋,緊接著向 CPU 發送 PWRGOOD#信號。北橋接收到南橋的信號,默念一秒鐘后,向 CPU 老大發送了CPU_RST#信號。
從此計算機世界開始熱鬧起來。
BIOS 現身
目前只是所有硬件開始工作,如果整個系統中沒有指令存在,CPU 醒來也不知道該去做什么。計算機啟動的英文表達是bootstrap,這來自于一句諺語:“pull oneself up by one’s bootstraps”,意思是”拽著自己的鞋帶把自己拉起來“。
這當然是不可能的事情。最早的時候,工程師們用它來比喻,計算機啟動是一個很矛盾的過程:必須先運行程序,然后計算機才能啟動,但是計算機不啟動就無法運行程序!早期真的是這樣,必須想盡各種辦法,把一小段程序裝進內存,然后計算機才能正常運行[2]。
那么這就是BIOS(Basic Input/Output System,基本輸入輸出系統)階段了。具體是如何工作的呢?
CPU 一醒來,毫不遲疑,立馬開始工作。以Intel 32位 CPU 為例,CPU 知道自己的使命,第一步就是取地址0xFFFFFFF0[8]處的指令(CPU 設計時固化的功能,理解這個很重要)。CPU拿到指令后執行,發現這條指令是告知自己,下一次去另一個地址取指(跳轉指令jmp [0xFFFF0000,0xE05B])。喔,想起來了,這是 BIOS 老弟等我去執行他保存的那一堆指令呢!CPU 又立馬開始工作,通過 FSB(前端總線)將這個地址發送到北橋,然后通過 HUB-LINK 到南橋,通過LPC(Low Pin Count Bus)到 EC,再通過 X-BUS 一直到達 BIOS 取指令。在CPU讀到所發出的地址內的指令后,開始 BIOS 程序執行。
BIOS 芯片中也保存了不少指令,形成的功能包括:
自診斷程序:讀取 CMOS 中的內容獲得硬件配置信息,并對其進行自檢和初始化;完整的 POST(Power On Self Test) 自檢將包括CPU、640K基本內存、1M以上的擴展內存、ROM、主板、 CMOS RAM、串并口、顯示卡、軟硬盤子系統及鍵盤測試。
CMOS 設置程序:引導過程中,用特殊熱鍵啟動,進行設置后,存入CMOS RAM中;對應 Dell 計算機啟動時我們按F12,進入的 BIOS 設置界面。
系統自舉裝載程序:在自檢成功后將磁盤相對 0 道 0 扇區上的引導程序裝入內存,讓其運行引導操作系統;
主要 I/O 設備的驅動程序和中斷服務:系統硬件的變化由 BIOS 隱藏,程序使用 BIOS 功能而不是直接控制硬件。不過現代操作系統會忽略 BIOS 提供的抽象層并直接控制硬件組件。
操作系統引導:Bootloader
在前面提到,BIOS 會負責將磁盤相對 0 道 0 扇區的引導程序裝入內存。不知道大家是否會有這樣的疑問:為什么我們一定需要一個引導程序呢?為什么不能直接讓 BIOS 將操作系統加載到內存中?
為了解答這個問題,首先要知道 Bootloader 都實現了什么功能。Bootloader 最直觀的功能就是將操作系統加載到內存中。首先可以考慮在硬盤上存在多個操作系統的情況下,操作系統的加載方式過程可能就不同。如果讓 BIOS 來考慮各個操作系統待加載到內存中的目的地址,這會導致 BIOS 程序的膨脹。而 BIOS 程序是固化在 BIOS 芯片中,正常情況下是無法修改的,解決加載新的操作系統出現問題就會很麻煩。而保證 BIOS 的正常功能就要降低 BOIS 的復雜性,那么適配不同操作系統的任務誰來做呢?那當然就是 bootloader 啦。并且在嵌入式環境下,操作系統的加載并不僅僅從磁盤上加載,還可能是Nor Flash 、NAND flash、USB 甚至是網絡。那么 Bootloader 就應該實現基本的網絡功能,例如著名的開源項目 U-Boot就是這樣做的。當然本文在這里只是拋磚引玉,為什么要分出一個 Bootloader 層,可以從很多方面分析這樣做的優勢。
普通的 Bootloader 都需要實現什么功能呢:
初始化硬件設備
為操作系統準備RAM空間
將操作系統代碼載入到RAM中
設置堆棧執行環境,為高級語言(如 C 語言)提供執行環境。這里要多說一句,操作系統并不都是 C 語言寫的哦。現在 Rust 語言接近 C 語言性能,并且因為其提供的安全性,已經被用來寫操作系統了。
將控制權交給操作系統。到這一步,系統的完整啟動也就結束啦。之后就是操作系統主宰的世界了!
如果讀者對 Bootloader 的詳細工作工作過程感興趣,可以參考 MIT6.828 操作系統課程 Lab1。這個實驗引導學生一步一步 Coding 了操作系統的啟動。讀者若對操作系統的設計感興趣,想詳細了解這個課程,墻裂推薦!
一丁點兒:MIT6.828-神級OS課程-要是早遇到,我還會是這種 five 系列
?
最后,最近讀了《碼農翻身-用故事給技術加點料》這本書,用故事來講技術知識。讀的時候就覺得作者特別有趣有才,尤其在自己也嘗試用故事來講技術之后,發現真的不容易,直接五體投地的服!
這是我第一次嘗試以擬人+故事的方式來寫技術相關的文章,不喜輕噴(逃…
參考文獻
[1]. 老狼. 按下開機鍵后,電腦都干了些什么? - 老狼的回答 - 知乎
[2]. 阮一峰. 計算機是如何啟動的?
[3]. Iknow. 筆記本電源管理芯片(EC)作用的介紹
[4]. StackOverflow. Why do we need a bootloader in an embedded device?
[5]. 人生一次萬般活法. 按下開機鍵后,電腦都干了些什么? - 人生一次萬般活法的回答 - 知乎
[6]. W3Cschool BIOS完全手冊. 什么是BIOS和COMS
[7]. 老狼. 電源是如何提供電力給主板的,又是如何切斷的?
[8]. Intel Corporation. 英特爾? 64 位和 IA-32 架構開發人員手冊:卷 3A
2 ??