1. 程式人生 > >linux從上電到到啟動流程簡要過程以及關鍵函式

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