田海立@CSDN
2013-3-16
本文分析Android中init進程的執行過程,只是分析init進程啟動的流水,具體細節在今後的各個專題中再分別詳細分析。本文雖是後面各個專題的基礎,讀者初看可能理解不深,可以在閱讀後面各個專題的時候,結合本文的整體流程會有更清晰的理解。
Init進程從 /system/core/init/init.c裡的main()函數開始
1. mkdir && mount
2. import_kernel_cmdline
從核心中通過/proc/cmdline匯入下列命令列參數,這些參數會分別被設定到各個屬性值中:
androidboot.console // 設定console androidboot.mode // 設定屬性ro.factorytest androidboot.serialno // 設定屬性ro.serialno androidboot.baseband // 設定屬性ro.baseband androidboot.carrier // 設定屬性ro.carrier androidboot.bootloader // 設定屬性ro.bootloader androidboot.hardware // 設定屬性ro.hardware androidboot.bsp // 根據這個設定與否,選擇不同的init.rc版本
注意:以上說的設定屬性還未真正設定,property機制還未工作。
3. init_parse_config_file()
解析init.rc或者init_bsp.rc(看步驟2匯入的參數“androidboot.bsp”是否設定)
Init.rc的解析,參見《Android中init.rc檔案的解析》
4. get_hardware_name()
從/proc/cpuinfo中擷取“Hardware”欄位資訊寫入<hw>;“Reversion” 欄位資訊寫入<reversion>
5. init_parse_config_file()
解析init.<hw>.rc或者init_bsp.<hw>.rc(看步驟2匯入的參數“androidboot.bsp”是否設定)
Init.rc的解析,參見《Android中init.rc檔案的解析》
6. action_for_each_trigger("early-init",action_add_queue_tail);
對init???.rc中解析出的early-initsection裡action,執行action_add_queue_tail操作,也就是把act->qlist加入到action_queue的列尾
注:此時並未真正執行,只是掛在隊列尾。
7. 把一些初始化操作加入到action_queue列表中
queue_builtin_action(wait_for_coldboot_done_action,"wait_for_coldboot_done"); queue_builtin_action(property_init_action,"property_init"); queue_builtin_action(keychord_init_action,"keychord_init"); queue_builtin_action(console_init_action,"console_init"); queue_builtin_action(set_init_properties_action,"set_init_properties");
queue_builtin_action(int (*func)(int nargs,char **args), char *name)是以name形成action,掛在action_list上;以func和name組成command,掛在action的commands上。然後加入到action_queue的隊尾。
8. 對其他section內的action,加入到action_queue列表中
另外一些初始操作也加入到action_queue列表中
/* execute all the boot actions to getus started */ action_for_each_trigger("init",action_add_queue_tail); action_for_each_trigger("early-fs", action_add_queue_tail); action_for_each_trigger("fs",action_add_queue_tail); action_for_each_trigger("post-fs",action_add_queue_tail); queue_builtin_action(property_service_init_action,"property_service_init"); queue_builtin_action(signal_init_action,"signal_init"); queue_builtin_action(check_startup_action,"check_startup"); /* execute all the boot actions to get usstarted */ action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot",action_add_queue_tail); /* run all property triggers based oncurrent state of the properties */ queue_builtin_action(queue_property_triggers_action,"queue_propety_triggers");
9. 進入無限迴圈中for(;;)
9.1 execute_one_command():[system/core/init/init.c]
1) 從action_queue取下structaction *act賦給cur_action;
2) 從cur_action獲得struct command *賦給cur_command;
3) 執行cur_command->func(cur_command->nargs, cur_command->args)
注1:以上是第一次執行時,如果action中還有command,就不需要1,而2中就是直接再在action上取下一條command即可。
注2:這裡才是真正地命令的執行,前面的action_for_each_trigger()和queue_builtin_action()只是加入到action_queue隊列中,而這裡是從隊列中順序取出,並執行。
所以,排入佇列action_queue的順序也就決定了執行的順序。Init???.rc中action所在的section決定了它們執行的先後次序:early-init -> init -> early-fs -> fs -> post-fs ->early-boot -> boot。
9.2 restart_processes():system/core/init/init.c
對有SVC_RESTARTING標誌的service,執行restart_service_if_needed()
9.3 用poll等待幾個事件:property事件/子進程結束的signal事件/keychord
9.4 處理等到的事件
對property_set事件,調用handle_property_set_fd()處理;
對keychord事件,調用handle_keychord()處理;
對signal事件,調用handle_signal()處理;
總結:
本文分析了Android裡的init進程的啟動過程,從中可以知道init做的主要工作包括對init.rc的解析,property機制的實現,service支撐的實現。詳細細節在後面的專題中討論。