嵌入式設備啟動時bootloader加載linux內核,linux內核啟動後運行第一個用戶級進程init,從此進程進入Android世界,所以,android是一個框架而不是kernel。
在linux系統啟動時,內核引導參數上一般都會設置“init=/init”,當android 最底層linux kernel 啟動後會執行一個用戶級進程init,此進程為所有進程的父進程,進程號為1,這裡為整個android框架的入口,init進程為android內所有進程的父進程。init 可執行程序一般位於/xbin/init 下,init程序源碼在Android源碼的system/core/init中,我們的分析就從main開始進入android framework。
/system/core/init/init.c#main
init進程 為標准linux進程,它可以使用linux 內核提供的api,也可以使用標准庫。
init 進程分兩部分,boot 部分 及 daemon部分,
int main(int argc, char **argv)
{
/* Boot part */
for(;;) {
/* Daemon part */
}
}
首先執行boot 部分,此部分創建文件系統基本目錄,包括 /dev, /proc, /sys 等。
初始化kmsg log 模塊,此模塊用於獲取linux kernle log 信息。
boot部分 最後解析init.rc配置文件,init_parse_config_file("/init.rc");/system/core/rootdir/init.rc
init.rc 語法解釋參考 /system/core/init/readme.txt
此文件定義了一系列 action及service。這裡指定了系統啟動時執行哪些動作,可以設置環境變量,
使用linux命令執行某個動作,啟動服務,掛載文件系統等等。
action 是一個命令的序列,每個action定義了某一命令,action有觸發機制,及在什麼情況下執行此命令。當某一事件與此action的出發機制匹配,此action會被加到action執行隊列中被執行。
parse_service 把解析後的 action 都放到 action_list鏈表,parse_action 把Service放在service_list。
boot部分最後遍歷action_list執行相應命令,具體如下:
(1)console_init_action :初始化console,顯示A N D R O I D 字樣在終端上。
(2)property_init_action
(3)set_init_properties_action
(4)property_service_init_action
Daemon part :
for(;;)不斷執行一下動作:
(1)啟動service_list中指定的服務,所有android其他服務在此處通過service 方式啟動,如虛擬機,servicemanager,mediaserver等,
每個服務對應init進程的一個子進程。
(2)不斷調用poll 監控3個fd狀態
property_set_fd
signal_recv_fd
keychord_fd
property_set_fd 解釋:
作為一個系統服務管理著系統的配置和狀態,所有的這些系統配置和狀態都是屬性(property)。屬性(property)是一對鍵/值(key/value)組合,鍵和值都是字符串類型。Androd中非常多的應用程序和庫直接或者間接的依賴於屬性系統,並由此決定其運行期的行為。例如:adbd進程通過屬性來決定是否當前運行在模擬器中。再比如:java.io.File.pathSeparator方法返回存儲在屬性服務中的值,property_service_init_action 在boot階段調用,初始化android 屬性系統,系統固定的屬性在目錄 "/data/property" 下面。init 進程管理android屬性系統所有數據,其他進程通過android提供的ashmem驅動只讀屬性系統。
signal_recv_fd :
子進程信號處理,waitpid等候子進程退出,清理資源,如果子進程是服務則重啟子進程。
keychord_fd:
監控輸入設備事件並啟動相應服務。
至此,init進程啟動完畢。
上面的daamon部分提到service_list保存了 init.rc中配置的啟動項,android內給上層提供的一些主要服務都是在此處指定並啟動。
如:servicemanager
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
--------------------#android運行時環境虛擬機啟動
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
---------------------------------
service media /system/bin/mediaserver #多媒體service啟動。
user media
group system audio camera graphics inet net_bt net_bt_admin net_raw
ioprio rt 4
------------------------------------------------------------------------