所有user space processes的祖先process "init"的從核心(另一種從initramfs方式去啟動)正常啟動流程如下:
1. 核心中的start_kernel() (在linux-2.6.27/init/main.c)-> rest_init()->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND)-> init_post(),init_post()會做以下的檢查:
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
若上述檢查失敗則可透過grub 設定kernel cmline 變數"init" 例如:init=/sbin/your_init
2.一但 "1."找到init程式,就執行之其執行流程如下所述:
mian()->init_main(dfl_level)//dfl_level=0, init_main()所做的事如下:
runlevel = '#';//代表目前的runlevel ,系統啟動時runlevel 為"#"
read_inittab(); //讀取/etc/inittab,將其內容存入全域變數structure CHILD * family,將runlevel 為"#"與 //action "sysinit"做對應
start_if_needed(); // Walk through the "family" list and start up children. 由於系統啟動時runlevel //為"#"會執行對應action "sysinit" 的process "/etc/init.d/rcS"
while(1){
boot_transitions(); //將runlevel從"#"轉換到"/etc/inittab" 描述的"default runlevel"
check_init_fifo(); //check FIFO file "/dev/initctl"是否有request發生,系統剛啟動request是空的且建立一個FIFO file "/dev/initctl"
fail_check();
process_signals();// Init got hit by a signal. See which signal it is, and act accordingly.
start_if_needed();//執行於runlevel 為"default runlevel"的process group,以default的"/etc/ //inittab"為例default runlevel為2所以會執行"/etc/init.d/rc 2"
}
3. 由於init 在init_main loop會不斷檢FIFO file "/dev/initctl' 是否有其他process 透過該file轉換目前的runlevel ( check_init_fifo()) 若有就將新的runlevel設定給目前的runlevel(fifo_new_level()) 當執行到start_if_needed()就會執行以新runlevel為代表的process group,以系統關機指令shutdown為例,其實它是呼叫"init 0" 將系統由目前的runlevel轉換到runlevel 0,所以會執行"/etc/init.d/rc 0"
參考資料:
http://72.14.235.104/search?q=cache:df24chyWw54J:blogimg.chinaunix.net/blog/upfile2/080802120641.pdf+TELINIT_USES_INITLVL&hl=zh-TW&ct=clnk&cd=2&gl=tw&client=firefox-a#21
1 則留言:
vts72jg01ji
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
golden goose outlet
張貼留言