Android框架架構圖
Linux內核啓動之後就到Android Init進程,進而啓動Android相關的服務和應用。
啓動的過程如下圖所示
下面將從Android4.0源碼中,和網絡達人對此的總結中,對此過程加以學習瞭解和總結,
以下學習過程中代碼片段中均有省略不完整,請參照源碼
一 Init進程的啓動
init進程,它是一個由內核啓動的用戶級進程。內核自行啓動(已經被載入內存,開始運行,
並已初始化所有的設備驅動程序和數據結構等)之後,就通過啓動一個用戶級程序init的方式,完成引導進程。init始終是第一個進程。
啓動過程就是代碼init.c中main函數執行過程:system\core\init\init.c
在函數中執行了:文件夾建立,掛載,rc文件解析,屬性設置,啓動服務,執行動作,socket監聽……
下面看兩個重要的過程:rc文件解析和服務啓動。
1 rc文件解析
.rc文件是Android使用的初始化腳本文件 (System/Core/Init/readme.txt中有描述:
four broad classes of statements which are Actions, Commands, Services, and Options.)
其中Command 就是系統支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,
還有一些是 android 添加的,如:class_start : 啓動服務,class_stop :關閉服務,等等。
其中Options是針對 Service 的選項的。
系統初始化要觸發的動作和要啓動的服務及其各自屬性都在rc腳本文件中定義。 具體看一下啓動腳本:\system\core\rootdir\init.rc
在解析rc腳本文件時,將相應的類型放入各自的List中:
\system\core\init\Init_parser.c :init_parse_config_file( )存入到
action_queue、 action_list、 service_list中,解析過程可以看一下parse_config函數,類似狀態機形式挺有意思。
這其中包含了服務:adbd、servicemanager、vold、ril-daemon、debuggerd、surfaceflinger、zygote、media……
2 服務啓動
文件解析完成之後將service放入到service_list中。
文件解析完成之後將service放入到service_list中。
\system\core\init\builtins.c
Service的啓動是在do_class_start函數中完成:
int do_class_start(int nargs, char **args)
{
service_for_each_class(args[1], service_start_if_not_disabled);
return 0;
}
遍歷所有名稱爲classname,狀態不爲SVC_DISABLED的Service啓動
void service_for_each_class(const char *classname,
void (*func)(struct service *svc))
{
……
}
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc, NULL);
}
}
do_class_start對應的命令:
KEYWORD(class_start, COMMAND, 1, do_class_start)
init.rc文件中搜索class_start:class_start main 、class_start core、……
main、core即爲do_class_start參數classname
init.rc文件中Service class名稱都是main:
service drm /system/bin/drmserver
class main
service surfaceflinger /system/bin/surfaceflinger
class main
於是就能夠通過main名稱遍歷到所有的Service,將其啓動。
do_class_start調用:
init.rc中
on boot //action
class_start core //執行command 對應 do_class_start
class_start main
Init進程main函數中:
system/core/init/init.c中:
int main(){
//掛在文件
//解析配置文件:init.rc……
//初始化化action queue
……
for(;;){
execute_one_command();
restart_processes();
for (i = 0; i < fd_count; i++) {
if (ufds[i].revents == POLLIN) {
if (ufds[i].fd == get_property_set_fd())
handle_property_set_fd();
else if (ufds[i].fd == get_keychord_fd())
handle_keychord();
else if (ufds[i].fd == get_signal_fd())
handle_signal();
}
}
}
}
循環調用service_start,將狀態SVC_RESTARTING啓動, 將啓動後的service狀態設置爲SVC_RUNNING。
pid=fork();
execve();
在消息循環中:Init進程執行了Android的Command,啓動了Android的NativeService,監聽Service的變化需求,Signal處理。
Init進程是作爲屬性服務(Property service),維護這些NativeService。
二 ServiceManager啓動
在.rc腳本文件中zygote的描述:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
ServiceManager用來管理系統中所有的binder service,不管是本地的c++實現的還是java語言實現的都需要
這個進程來統一管理,最主要的管理就是,註冊添加服務,獲取服務。所有的Service使用前都必須先在servicemanager中進行註冊。
do_find_service( )
do_add_service( )
svcmgr_handler( )
代碼位置:frameworks\base\cmds\servicemanager\Service_manager.c
三 Zygote進程的啓動
Zygote這個進程是非常重要的一個進程,Zygote進程的建立是真正的Android運行空間,初始化建立的Service都是Navtive service.
(1) 在.rc腳本文件中zygote的描述:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
參數:--zygote --start-system-server
代碼位置:frameworks/base/cmds/app_process/app_main.cpp
上面的參數在這裏就會用上,決定是否要啓動和啓動那些進程。