linux從上電到到啟動流程簡要過程以及關鍵函式
linux 4.1.x
ARM上電。執行BOOTLOADER
bootloader載入kernel 。傳遞引數給kernel 然後執行kernel
設定一些暫存器,初始化一些狀態等等。然後跳到head.s執行
head.s已經屬於kernel的部分了
head.s主要是硬體相關的部分,解壓kernel等等。最終跳轉到
start_kernel裡面執行
start_kernel 依舊需要很多初始化 pid 中斷等等
這些基本完成後呼叫rest_init
static noinline void __init_refok rest_init(void)
{
..............................
kernel_thread(kernel_init, NULL, CLONE_FS);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
cpu_startup_entry(CPUHP_ONLINE);
}
cpu_startup_entry 呼叫cpu_idle_loop
void cpu_startup_entry(enum cpuhp_state state)
{
cpu_idle_loop();
}
cpu_idle_loop 是一個死迴圈 idle程序是0號程序。當CPU沒有任何事情可以做的時候就進入了Idle程序。
static void cpu_idle_loop(void)
{
while (1)
{
xx
}
}
所以後續的事情其實主要是
kernel_thread(kernel_init, NULL, CLONE_FS);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
也就是建立兩個程序
第二個 kthreadd主要是排程其他的執行緒。
idle程序Pid=0
kernel_init 程序Pid=1
kthreadd 程序pid=2
所以最關鍵的就是kernel_init函數了(之前vfs_cache 以及後續的操作 什麼的已經將檔案系統建立起來了)
kernel_init 主要是執行一個特定的程序任務。
只要由一個任務執行成功就返回。否則一直try 到最後一個。如果還是執行失敗,那麼系統起不來
執行順序是
1 傳遞給核心的引數 init=xxxxxxxxx
ramdisk_execute_command
2傳遞給核心的引數 rdinit=xxxxxxxxxxxx
execute_command
3 /sbin/init
4 /etc/init
5 /bin/init
有一個啟動成功就返回。全部失敗。系統啟動失敗panic