Android系統啓動時在加載完內核之後會啓動Init進程,Init進程的啓動過程中會讀取根目錄下的腳本文件Init.rc,以便將Zygote進程啓動起來。
//Android系統在加載內核之後會啓動init進程,以下爲Init進程的main函數
int main(int argc, char **argv)
{
//解析配置文件的初始化
init_parse_config_file("/init.rc");
action_for_each_trigger("early-init", action_add_queue_tail);
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
//逐一執行隊列中的命令
execute_one_command();
}
void action_for_each_trigger(const char *trigger,
void (*func)(struct action *act))
{
//調用func指向的函數
func(act);
}
void queue_builtin_action(int (*func)(int nargs, char **args), char *name)
{
//命令結構體cmd的成員函數func指向函數參數func所指向的函數
cmd->func = func;
}
int init_parse_config_file(const char *fn)
{
//讀取配置文件init.rc到字符串指針data
data = read_file(fn, 0);
//解析配置文件
parse_config(fn, data);
}
static void parse_config(const char *fn, char *s)
{
//解析狀態結構體state的成員變量parse_lint是個函數指針,默認指向無解析操作函數parse_line_no_op,也可指向解析服務函數parse_line_service,或者解析動作函數parse_line_action
state.parse_line = parse_line_no_op;
//確定關鍵字
int kw = lookup_keyword(args[0]);
//調用state.parse_line指向的函數解析新的行
state.parse_line(&state, 0, 0);
//解析一個新的章節
parse_new_section(&state, kw, nargs, args);
//遞歸調用init_parse_config_file來解析import的文件
ret = init_parse_config_file(import->filename);
}
static void parse_new_section(struct parse_state *state, int kw,
int nargs, char **args)
{
//解析服務
state->context = parse_service(state, nargs, args);
//解析狀態結構體state的成員變量parse_line指向函數parse_line_service
state->parse_line = parse_line_service;
//解析加載文件部分
parse_import(state, nargs, args);
}
static void parse_line_service(struct parse_state *state, int nargs, char **args)
{
//調用函數kw_func
cmd->func = kw_func(kw);
}
static void parse_line_action(struct parse_state* state, int nargs, char **args)
{
//調用函數kw_func
cmd->func = kw_func(kw);
}
int do_class_start(int nargs, char **args)
{
/* Starting a class does not start services
* which are explicitly disabled. They must
* be started individually.
*/
service_for_each_class(args[1], service_start_if_not_disabled);
}
void service_for_each_class(const char *classname,
void (*func)(struct service *svc))
{
//func指向service_start_if_not_disabled
func(svc);
}
//參數dynamic_args用來描述服務的動態參數列表,相對於腳本文件init.rc中配置的靜態啓動參數而言
void service_start(struct service *svc, const char *dynamic_args)
{
//fork創建子進程
pid = fork();
if (pid == 0) {
//在新創建的子進程中返回
//創建socket
int s = create_socket(si->name, socket_type,
si->perm, si->uid, si->gid, si->socketcon ?: scon);
//將創建socket返回的fd發佈到系統中
publish_socket(si->name, s);
//如果動態參數爲空,直接執行新程序/system/bin/app_process
if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
//合併動態參數和靜態參數之後加載應用程序文件/system/bin/app_process,並把數組arg_ptrs傳給它
execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
}
Init.rc
import /init.${ro.zygote}.rc
on nonencrypted
//啓動main類型的class
class_start main
class_start late_start
Init.zygote32.rc
//Zygote進程以服務service的形式啓動,對應的程序文件是/system/bin/app_process,後面是4個啓動參數,"--start-system-server"表示Zygote啓動完成後啓動System進程
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
//Zygote進程內部會創建一個名稱爲Zygote的socket
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
Keywords.h
//class是一個OPTION
KEYWORD(class, OPTION, 0, 0)
//注意class_start是COMMAND,對應的函數是do_class_start
KEYWORD(class_start, COMMAND, 1, do_class_start)
//注意service是一個SECTION
KEYWORD(service, SECTION, 0, 0)
Init_parser.c
//第一次包含頭文件"keywords.h",是爲了聲明函數和枚舉
#include "keywords.h"
#define KEYWORD(symbol, flags, nargs, func) \
[ K_##symbol ] = { #symbol, func, nargs + 1, flags, },
static struct {
const char *name;
int (*func)(int nargs, char **args);
unsigned char nargs;
unsigned char flags;
} keyword_info[KEYWORD_COUNT] = {
[ K_UNKNOWN ] = { "unknown", 0, 0, 0 },
//第二次包含頭文件"keywords.h",是爲了利用枚舉裏面的變量來給數組keyword_info初始化
//注意作用域在數組keyword_info裏面,
#include "keywords.h"
};