概述
Linux內核啟動流程根據是否與體系結構相關主要可分為兩個階段。
第一階段:引導過程
==> 系統上電
===> CPU自身初始化
---------------------------------BIOS------------------------------------------
===> 加電自檢
===> 加載內核引導程序
------------------------------內核引導程序-----------------------------------
===> 主引導程序
===> 次引導程序
----------------------------------------------------------------------------------
===> 調用內核
1、CPU自身初始化
CPU 自身的初始化是引導過程的第一步,如果有多個 CPU,即多處理器系統,則每個CPU 都要進行自身初始化。CPU自身初始化之后從一個固定的位置(一般是0xfffffff0)取得指令並執行該指令為跳轉指令跳轉到BIOS代碼的首部。
2、BIOS
BIOS 被固化於主板上一個容量相對較小的只讀存儲器(Read-Only Memory,ROM)中,它的工作主要有兩個:加電自檢,即進行所謂的 POST(Power On Self Test)和加載內核引導程序。
POST 階段完成系統硬件的檢測,包括內存檢測、系統總線檢測等。POST 完成之后,BIOS 讀取啟動設備第一個扇區,即首 512 字節的信息, 該扇區又被稱之為主引導記錄(Master Boot Record,MBR)。MBR 中保存了內核引導程序的開始部分,BIOS 將其加載到內存並執行。
3、內核引導程序
內核引導程序分為兩個階段:MBR 中的主引導程序;活動分區引導記錄中的次引導程序。MBR 中的主引導程序是一個 512 字節的映像,它包含了 446 字節的程序代碼和 64 字節的分區表,最后兩個字節固定為 0xAA55,用於檢查 MBR 是否有效。
主引導程序:掃描分區表,尋找活動分區,將位於活動分區引導記錄中的次引導程序加載到內存中並執行。
次引導程序:負責加載 Linux 內核映像,並將控制權轉交給內核。
4、內核
函數 | 位置(ARCH為體系架構,如arm、i386....) | 功能 |
start | arch/ARCH/boot/head.S | 進行一些基本的硬件設置 |
startup_32 | arch/ARCH/boot/compressed/head.S | 例程設置一個基本的運行環境(堆棧等),並清除 BSS(Block Started by Symbol) |
decompress_kernel | arch/ARCH/boot/compressed/misc.c | 解壓內核 |
startup_32 | arch/ARCH/kernel/head.S | 對頁表進行初始化,啟用內存分頁功能,並為任何可選的浮點單元(FPU)檢測 CPU 的類型 |
start_kernel | arch/ARCH/kernel/head.S | 進入體系結構無關的內核部分。自此,內核的引導過程告一段落,進入內核的初始化過程。 |
總結:引導過程可歸納為:CPU 加載 BIOS,BIOS 加載內核引導程序,內核引導程序加載壓縮內核,壓縮內核加載解壓內核。
第二階段:內核初始化
函數 | 位置 | 功能 |
start_kernel | init/main.c | 完成了內核的大部分初始化工作,相當於內核的 main 函數 |
reset_init | init/main.c | 啟動內核線程 kernel_init |
kernel_init | init/main.c | 完成設備驅動程序的初始化 |
init_post | init/main.c | 啟動用戶空間的 init進程 |
至此,內核已被引導並進行了初始化,且啟動了自己的第一個用戶空間應用程序,即 init。這是調用的第一個使用標准 C 庫編譯的程序,其進程編號始終為 1。