1.BIOS/UEFI
首先,計算機一加電,主板中固化的一段程序就會啟動,這段程序就是?BIOS?(老機器中常見)或者?UEFI?(新機器中常見)。這段程序首先會檢查各個硬件是否正常(CPU、內存、鍵盤等),這一步叫做自檢(?POST?,Power-On Self Test)。然后,這段程序會決定將控制權交給哪個設備里的引導程序。如果是 BIOS,它會去硬盤(涉及?啟動順序?)的開頭(MBR 區)找一小段引導代碼,將這段引導代碼讀進內存并運行;如果是 UEFI,它會去硬盤的一個專用分區(EFI System Partition)里找一個 .efi 程序,比如 grubx64.efi,并運行它。BIOS/UEFI的工作由此結束。
1.1 固化是什么意思?
將一段程序寫入硬件里邊,讓這段程序不會隨著斷電而消失。
1.2 POST
在最小的硬件環境下,運行一些非常基礎的小程序,查看各個關鍵部件是否正常。例如:
- CPU:會做簡單的寄存器測試、算術測試,確保 CPU 基本沒壞。
- 內存:BIOS 會嘗試往內存寫入一些固定的測試數據,再讀出來,看看對不對。
- 鍵盤、硬盤:檢查鍵盤是否連接上,掃描硬盤、光驅是否能用。
1.3 啟動順序
主板中有一個啟動順序,比如:
- U盤
- 硬盤
- 網絡
BIOS/UEFI會按照這個順序去檢查設備,看他們是否有“可啟動”的標記,如果有,BIOS就會從他的第一個扇區讀取代碼并運行;UEFI會去讀啟動設備的ESP分區中的.efi文件,并執行它。(所以啟動設備不一定是硬盤)
2.引導加載器(bootloader)
引導加載器把內核和啟動所需的輔助數據加載進入內存里,然后將控制權交給內核。
更細一點:
- 加載內核
- 內核是個可執行文件(通常是壓縮過的 ELF 格式,比如
/boot/vmlinuz-...)。 - 引導加載器會把這個文件讀出來,放到內存的合適位置。
- 內核是個可執行文件(通常是壓縮過的 ELF 格式,比如
- 準備啟動環境
- 內核本身通常需要一些額外的信息,比如“根文件系統在哪里”、“啟動參數是什么”、“加密磁盤怎么解鎖”。
- 這些就通過 ?initrd?/initramfs 提供。bootloader 會把 initramfs 也塞到內存里。
- 傳遞啟動參數
- 引導加載器會告訴內核:“我已經幫你把東西放好了,你從這里開始執行,參數是這些。”
- 常見參數就是
root=/dev/sda2、quiet、ro之類的。可以用cat /proc/cmdline查看。
- 交出控制權
- 最后一步很關鍵:bootloader 會調用內核的入口點,把 CPU 的執行權交過去。
- 之后就不再干涉,接下來就是內核接手,初始化驅動、掛載根文件系統、啟動第一個用戶態進程(
/sbin/init)。
2.1 引導加載器是上一個流程中的引導代碼?
- 在傳統BIOS中,BIOS會去設備的第一個扇區(512bytes)讀出一小段引導代碼,它的任務非常有限:因為 512 字節根本裝不下一個完整的bootloader,它只能做點“小動作”,比如:檢查自己是不是“可引導”的(最后兩個字節要是
0x55AA標志); 然后再去加載“第二階段引導加載器”,比如GRUB的下一段更大代碼。真正完整的bootloader一般分布在磁盤后序的幾個扇區中。 - 在UEFI中,它會直接去EFI分區(ESP)找到那個.efi程序,這個程序就是完成的bootloader。
3.內核
- Linux 內核存放在
/boot/vmlinuz-xxx里,其實是個壓縮過的鏡像。內核啟動后,先把自己解壓到內存中真正要運行的位置。 - 然后初始化最基礎的環境:CPU 模式、內存管理、頁表、堆棧、調度器的基本框架。
- 之后內核需要加載顯卡驅動、磁盤驅動等。
- 內核會掛載initramfs(臨時根文件系統),在這里加載額外驅動、組裝RAID、找到真正的根文件系統。
- 之后內核會掛載真正的根文件系統,掛載成功之后,系統算是有了真正的“家”。
- 啟動第一個用戶態進程:內核調用/sbin/systemd服務,從這里開始,用戶空間的進程就接管了大部分的工作。(systemd是所有其他進程的父進程 pid=1)
4.systemd
systemd會據目標狀態(target)決定啟動哪些服務(daemon)。常見的 target 有:
multi-user.target—— 純命令行模式,適合服務器。graphical.target—— 啟動圖形界面(桌面環境),常見于桌面版 Linux。rescue.target—— 類似單用戶模式,用來修復系統。
等這些服務都準備就緒了,系統就會進入登錄階段。你可以在終端里輸入用戶名密碼登錄,或者在圖形界面輸入密碼進入桌面環境。至此,Linux 的啟動才算完成。