源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Android中init.rc文件的解析 分享

  • 时间:2022-05-03 02:59 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Android中init.rc文件的解析 分享
对init.rc的解析是在parse_config(): [system/core/init/init_parser.c]中进行的。解析发生在init全过程中的哪个阶段,参看《Android init进程启动过程分析》。 一、解析过程 1.      扫描init.rc中的token     找到其中的 文件结束EOF/文本TEXT/新行NEWLINE,其中的空格‘ '、‘\t'、‘\r'会被忽略,#开头的行也被忽略掉;     而对于TEXT,空格‘ '、‘\t'、‘\r'、‘\n'都是TEXT的结束标志。 2.      对每一个TEXT token,都加入到args[]数组中 3.  当遇到新一行(‘\n')的时候,用args[0]通过lookup_keyword()检索匹配关键字;    1) 对Section(on和service),调用parse_new_section() 解析:      - 对on section,调用parse_action(),并设置解析函数parse_line为parse_line_action()      - 对service section,调用parse_service(),并设置解析函数parse_line为parse_line_service()    2) 对其他关键字的行(非on或service开头的地方,也就是没有切换section)调用parse_line()      也就是,        - 对于on section内的命令行,调用parse_line_action()解析;        - 对于service section内的命令行,调用parse_line_service()解析。 二、关键数据类型原型及关键数据定义 2.1 Token的定义 [cpp] #defineT_EOF 0   #defineT_TEXT 1   #defineT_NEWLINE 2  #defineT_EOF 0 #defineT_TEXT 1 #defineT_NEWLINE 2 2.2 关键字定义 [cpp] KEYWORD(capability,  OPTION, 0, 0)  KEYWORD(chdir,       COMMAND, 1, do_chdir)  KEYWORD(chroot,      COMMAND, 1, do_chroot)  KEYWORD(class,       OPTION, 0, 0)  KEYWORD(class_start, COMMAND, 1,do_class_start)  KEYWORD(class_stop,  COMMAND, 1, do_class_stop)  KEYWORD(console,     OPTION, 0, 0)  KEYWORD(critical,    OPTION, 0, 0)  KEYWORD(disabled,    OPTION, 0, 0)  KEYWORD(domainname,  COMMAND, 1, do_domainname)  KEYWORD(exec,        COMMAND, 1, do_exec)  KEYWORD(export,      COMMAND, 2, do_export)  KEYWORD(group,       OPTION, 0, 0)  KEYWORD(hostname,    COMMAND, 1, do_hostname)  KEYWORD(ifup,        COMMAND, 1, do_ifup)  KEYWORD(insmod,      COMMAND, 1, do_insmod)  KEYWORD(import,      COMMAND, 1, do_import)  KEYWORD(keycodes,    OPTION, 0, 0)  KEYWORD(mkdir,       COMMAND, 1, do_mkdir)  KEYWORD(mount,       COMMAND, 3, do_mount)  KEYWORD(on,          SECTION, 0, 0)  KEYWORD(oneshot,     OPTION, 0, 0)  KEYWORD(onrestart,   OPTION, 0, 0)  KEYWORD(restart,     COMMAND, 1, do_restart)  KEYWORD(service,     SECTION, 0, 0)  KEYWORD(setenv,      OPTION, 2, 0)  KEYWORD(setkey,      COMMAND, 0, do_setkey)  KEYWORD(setprop,     COMMAND, 2, do_setprop)  KEYWORD(setrlimit,   COMMAND, 3, do_setrlimit)  KEYWORD(socket,      OPTION, 0, 0)  KEYWORD(start,       COMMAND, 1, do_start)  KEYWORD(stop,        COMMAND, 1, do_stop)  KEYWORD(trigger,     COMMAND, 1, do_trigger)  KEYWORD(symlink,     COMMAND, 1, do_symlink)  KEYWORD(sysclktz,    COMMAND, 1, do_sysclktz)  KEYWORD(user,        OPTION, 0, 0)  KEYWORD(wait,        COMMAND, 1, do_wait)  KEYWORD(write,       COMMAND, 2, do_write)  KEYWORD(copy,        COMMAND, 2, do_copy)  KEYWORD(chown,       COMMAND, 2, do_chown)  KEYWORD(chmod,       COMMAND, 2, do_chmod)  KEYWORD(loglevel,    COMMAND, 1, do_loglevel)  KEYWORD(ioprio,      OPTION, 0, 0)      KEYWORD(capability,  OPTION, 0, 0)     KEYWORD(chdir,       COMMAND, 1, do_chdir)     KEYWORD(chroot,      COMMAND, 1, do_chroot)     KEYWORD(class,       OPTION, 0, 0)     KEYWORD(class_start, COMMAND, 1,do_class_start)     KEYWORD(class_stop,  COMMAND, 1, do_class_stop)     KEYWORD(console,     OPTION, 0, 0)     KEYWORD(critical,    OPTION, 0, 0)     KEYWORD(disabled,    OPTION, 0, 0)     KEYWORD(domainname,  COMMAND, 1, do_domainname)     KEYWORD(exec,        COMMAND, 1, do_exec)     KEYWORD(export,      COMMAND, 2, do_export)     KEYWORD(group,       OPTION, 0, 0)     KEYWORD(hostname,    COMMAND, 1, do_hostname)     KEYWORD(ifup,        COMMAND, 1, do_ifup)     KEYWORD(insmod,      COMMAND, 1, do_insmod)     KEYWORD(import,      COMMAND, 1, do_import)     KEYWORD(keycodes,    OPTION, 0, 0)     KEYWORD(mkdir,       COMMAND, 1, do_mkdir)     KEYWORD(mount,       COMMAND, 3, do_mount)     KEYWORD(on,          SECTION, 0, 0)     KEYWORD(oneshot,     OPTION, 0, 0)     KEYWORD(onrestart,   OPTION, 0, 0)     KEYWORD(restart,     COMMAND, 1, do_restart)     KEYWORD(service,     SECTION, 0, 0)     KEYWORD(setenv,      OPTION, 2, 0)     KEYWORD(setkey,      COMMAND, 0, do_setkey)     KEYWORD(setprop,     COMMAND, 2, do_setprop)     KEYWORD(setrlimit,   COMMAND, 3, do_setrlimit)     KEYWORD(socket,      OPTION, 0, 0)     KEYWORD(start,       COMMAND, 1, do_start)     KEYWORD(stop,        COMMAND, 1, do_stop)     KEYWORD(trigger,     COMMAND, 1, do_trigger)     KEYWORD(symlink,     COMMAND, 1, do_symlink)     KEYWORD(sysclktz,    COMMAND, 1, do_sysclktz)     KEYWORD(user,        OPTION, 0, 0)     KEYWORD(wait,        COMMAND, 1, do_wait)     KEYWORD(write,       COMMAND, 2, do_write)     KEYWORD(copy,        COMMAND, 2, do_copy)     KEYWORD(chown,       COMMAND, 2, do_chown)     KEYWORD(chmod,       COMMAND, 2, do_chmod)     KEYWORD(loglevel,    COMMAND, 1, do_loglevel)     KEYWORD(ioprio,      OPTION, 0, 0) 2.3 struct action 和struct command   [cpp]
[u]复制代码[/u] 代码如下:
struct action {          /* node in list of all actions */      struct listnode alist;          /* node in the queue of pending actions*/      struct listnode qlist;          /* node in list of actions for atrigger */      struct listnode tlist;      unsigned hash;      const char *name;      struct listnode commands;      struct command *current;  };  struct action {         /* node in list of all actions */     struct listnode alist;         /* node in the queue of pending actions*/     struct listnode qlist;         /* node in list of actions for atrigger */     struct listnode tlist;     unsigned hash;     const char *name;     struct listnode commands;     struct command *current; };
[cpp] view plaincopyprint?
[u]复制代码[/u] 代码如下:
struct command  {          /* list of commands in an action */      struct listnode clist;      int (*func)(int nargs, char **args);      int nargs;      char *args[1];  };  struct command {         /* list of commands in an action */     struct listnode clist;     int (*func)(int nargs, char **args);     int nargs;     char *args[1]; };
2.4 list action_list和action_queue action_list     解析init.rc时,遇到on action通过act->alist加入;     queue_builtin_action()把执行的函数组成command,创建action,挂在action_list上。 action_queue     执行action_for_each_trigger(),通过act->qlist加入;     queue_builtin_action()把执行的函数组成command,创建action,挂在action_list上,并追加到action_queue的队尾。 三、对action的解析 结合init的启动过程以及前面讲述的init.rc的解析,总结一下对init对init.rc里action的解析. 3.1 on section内action的解析     1.3.1中解析到新的on section调用parse_action()时,申请了struct action *act,设置:      1) act->name为on section的名字(比如boot/fs/);      2) 初始化list act->commands;      3) 把act->alist加入到action_list的列尾     这样,action创建并加入到了action_list中。 3.2 on section内action里的command的解析     对on section内action里的command,调用parse_line_action()      1) 查找关键字,核对是否是COMMAND,参数数目是否正确      2) 申请struct command *cmd        - cmd->func从keyword表中获取;        - 设置参数个数给cmd->nargs,拷贝参数给cmd->args;        - 把cmd->clist加入到act->commands的列尾     这样,command加入到了action中。 3.3 action_list里的action加入action_queue中     action_for_each_trigger()把队列action_list里所匹配的action,追加到action_queue的队尾;     queue_builtin_action()把执行的函数组成command,创建action,挂在action_list上,并追加到action_queue的队尾。 3.4 命令的执行     Init的无限循环中execute_one_command():system/core/init/init.c       1) 从action_queue取下structaction *act赋给cur_action;       2) 从cur_action获得struct command *赋给cur_command;       3) 执行cur_command->func(cur_command->nargs, cur_command->args) 上面步骤中1, 2 & 3是一次执行的,4是无限循环执行,从action_queue上取下action,action里获得command,然后执行command。  四、init.rc语法小结     system/core/init/Readme里有init.rc语法的描述。之前笔者没有分析init源码时,也读过这个Readme文件,但是对一些概念界定都搞不太清楚。现在分析过init.rc的解析之后,下面试着对init.rc语法做一下梳理。 1.      #开头的行也被忽略掉,用于注释; 2.      ‘'、‘\t'、‘\r'都会被忽略,所以属性中含有空格的话,后面的不会被识别;每一个Action里command前的缩进并无语法的要求,只是便于人阅读; 3.      ‘\n'是换行的标志,init语法里新解析的开始都是基于新行开始才进行的,是逐行扫描解析的; 4.      一些概念:Section / Action / Command / Trigger -         Init.rc里,遇到on<trigger>或service <name> <pathname> [ <argument> ]*行,标志着一个新section的开始[参看2.2里关键字定义里,类型为SECTION的也就只有on和service]; -         遇到on <trigger>,trigger是触发条件,发生的时机。可以是early-init / init / early-fs / fs / post-fs / early-boot / boot;也可以是property:<name>=<value>,属性<name>的值被设置为<value>时;device-added-<path>/ device-removed-<path>设备节点被加入或移除时;service-exited-<name>服务退出时。 -         on <trigger>发生时,执行action,也就是on<trigger>后面的部分,可包含多个command; -         command每条一行,支持哪些command,看2.2里关键字定义里类型为COMMAND的关键字。 形式如下: [cpp] on <trigger>      <command>      <command>      <command>  on <trigger>     <command>     <command>     <command>这整个是一个Section;所有<command>叫action。 总结 本文解析了init.rc的基本语法,重点讨论on section的解析,service的解析以及property的支持在后续专题中再详细讨论。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部