uboot 在初始化結束之後,會調用 start_kernel 來運行linux kernel.
剛剛簡單的看了看kernel 3.4, 現在的kernel是採用建立核心線程的形式來運行 init 的。 具體的代碼可以參考 linux kernel 代碼中的 init/main.c start_kernel -> rest_init , 在 rest_init 中建立了核心線程, 這個線程的處理函數是 init_post, 在 init_post 中系統會調用
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
早期的 linux kenel 還不支援核心線程,是直接在 start_kernel 調用 init 的。
Android 的 init 檔案在 system/core/sh/init.c 代碼不複雜,簡單的分析一下:
1. 程式開始先判斷一下是不是作為 ueventd 來運行,如果是就運行 ueventd 的邏輯了
2. 建立用到的檔案系統的結構 /dev, /proc, /sys, 掛接 tmpfs 等等
3. 建立 /dev/.booting 檔案
4. open_devnull_stdio 建立字元裝置 /dev/__null_
5. klog_init 建立 klog 用的字元裝置
6. 從 init.c 讀取設定檔
7. 讀取本機專註的配置資訊 /init.MACHINENAME.rc
8. ..... 最後讀取配置資訊的每一條,開始執行
init.rc 指令碼是整個 android 其他的一個關鍵點, init.rc 所支援的所有的關鍵字都包涵在 core\init\keywords. h
Android 中無數的細節都堪稱經典,這個小小的 init.rc 的解析的架構,完全可以複用在自己的項目,對設定檔的簡單解析,或者成為簡單的指令碼引擎。