Android 启动分析 --- init.c (system/core/init/init.c)

洪荒之初(其实不算是,kernel已经起来了)

从androidsrc/system/core/init.c开始


int main(){

......

init_parse_config_file("/init.rc");

/******************************************

*这里去打开文件系统根目录下的init.rc文件,这里可以去先看下init.rc文件内部的格式

*内部调用parse_config(fn, data);

*parse_config(fn, data);会把init.rc文件解析后传给parse_new_section(&state, kw, nargs, args);

void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
    printf("[ %s %s ]\n", args[0],
           nargs > 1 ? args[1] : "");
    switch(kw) {
    case K_service:
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
    case K_on:
        state->context = parse_action(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_action;
            return;
        }
        break;
    }
    state->parse_line = parse_line_no_op;
}

这就可以看出对init.rc文件格式解析的一些模式了,根据是service还是trigger继续深入解析执行脚本

通过这两个函数parse_service与parse_action。还有这两个函数仅仅是把解析出来的添加到相应的列表尾,最后会有统一的执行步骤。

*******************************************/

main中继续

读取loader给kernel的启动参数

mport_kernel_cmdline(0);

会去读取/proc/cmdline,cat下你就会发现这是什么东西。你也可以在host机器上看看。

main中继续

get_hardware_name(hardware, &revision);取你的硬件名,然后根据这个去找你硬件相关init脚本

mian中继续

snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
init_parse_config_file(tmp);  执行硬件相关的脚本


之后两个关键脚本就全部载入分析完毕,开始执行:

    action_for_each_trigger("early-init", action_add_queue_tail);

    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");

        /* execute all the boot actions to get us 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 us started */
    action_for_each_trigger("early-boot", action_add_queue_tail);
    action_for_each_trigger("boot", action_add_queue_tail);

        /* run all property triggers based on current state of the properties */
    queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");

这一系列的函数会按early-init,init,early-fs,fs,post-fs,early-boot,boot的顺序去执行所有脚本,这些关键字即是triggers的关键字。

action_for_each_trigger内部会使用func()执行每一条命令,queue_builtin_action则会按照triggers关键字去构建相应的命令列表。


随后就是一个for(;;)无限循环,

 - 重置輪詢事件的接受狀態,revents為0
      - 查詢action隊列,并执行。
      - 重啟需要重啟的服务
      - 輪詢注冊的事件

}


你可能感兴趣的:(Android)