当前位置:操作系统 > 安卓/Android >>

AndroidInitProcess分析心得(1)

[cpp] 

众所皆知,Android Init process是Android启动后最先起来的进程. 真正来说Android Init process是由Linux Kernel的启动程序所驱动起来. 从device上电, Bootloader加载Kernel, 然后Kernel接着驱动Android Init process. 这一段属于Linux 的范畴, 其简单的函数呼叫流程如下:

 

kernel_init===> init_post ==> run_init_process ==> 启动 Android Init process.

 

由于这篇主要是分析AndroidInit process在处始化所作的工作, 因此kernel_init, init_post,run_init_process 这三个函数里的流程就不在这里作分析.

 

        Android Init process 在初始化阶段主要做三件事.

1. 分析和执行init.rc脚本文件

2. 创建devicenode file

3. 监控系统属性变化跟事件

以下就分别依照这三点来做研究分析.

分析和执行init.rc脚本文件

        init.rc脚本文件主要是用来设定Android系统环境,还有一些待执行的进程记录.整个脚本文件可以分为两类action list跟 service list. 这两类会根据脚本文件中的关键词来作分类,

        1. 以"on"关键词开头的为actionlist中的元素,

        2. 以"Services"关键词的为servicelist中的元素.

这两个关键词就跟init.rc脚本文件使用的AIL(Android Init Language)有关了.AIL 主要包含四种类型, Action, Commands, Services, Option. 这四类的语法用法在system\core\init\readme.txt中有详细描述. 这里只是简单的介绍这四类的关系, 语法用法请参考system\core\init\readme.txt.

        Action和Services代表着一段新的Section,所有的Section下都有Command跟Option的一些宣告.Command最主要是用来创建一些系统目录或是启动进程.Option则作为ServicesSection的一些属性设定. 比如进程是否从新被启动.

        分析和执行init.rc脚本文件的研究分析就由init_parse_config_file函数开始.因为此函数正是用来init.rc脚本文件作分析流程.


[cpp]
// \system\core\init\init_parser.c  
int init_parse_config_file(const char *fn) 

    char *data; 
    data = read_file(fn, 0); 
    if (!data) return -1; 
 
    parse_config(fn, data); 
    DUMP(); 
    return 0; 

 
static void parse_config(const char *fn, char *s) 

   struct parse_state state; 
   // ...  
   state.filename = fn; 
   state.line = 0; 
   state.ptr = s; 
   state.nexttoken = 0; 
   state.parse_line = parse_line_no_op; 
   // ...  
   for (;;) { 
      switch (next_token(&state)) { 
      case T_EOF: 
          state.parse_line(&state, 0, 0); 
          goto parser_done; 
      case T_NEWLINE: 
            state.line++; 
            if (nargs) { 
                int kw = lookup_keyword(args[0]); 
                if (kw_is(kw, SECTION)) { 
                    state.parse_line(&state, 0, 0); 
                    parse_new_section(&state, kw, nargs, args); 
                } else { 
                    state.parse_line(&state, nargs, args); 
                } 
                nargs = 0; 
            } 
            break; 
        case T_TEXT: 
            if (nargs < INIT_PARSER_MAXARGS) { 
                args[nargs++] = state.text; 
            } 
            break; 
      } 
   } 

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; 
    case K_import: 
        parse_import(state, nargs, args); 
        break; 
    } 
    state->parse_line = parse_line_no_op; 

// \system\core\init\init_parser.c
int init_parse_config_file(const char *fn)
{
    char *data;
    data = read_file(fn, 0);
    if (!data) return -1;

    parse_config(fn, data);
    DUMP();
    return 0;
}

static void parse_config(const char *fn, char *s)
{
   struct parse_state state;
   // ...
   state.filename = fn;
   state.line = 0;
   state.ptr = s;
   state.nexttoken = 0;
   state.parse_line = parse_line_no_op;
   // ...
   for (;;) {
      switch (

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,