Android中init.rc檔案的解析

來源:互聯網
上載者:User

田海立@CSDN

2013-3-16

 

本文分析Android中如何解析init.rc檔案,重點描述了on action內的解析,並從解析的過程中總結出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的定義

#defineT_EOF 0#defineT_TEXT 1#defineT_NEWLINE 2

 

2.2 關鍵字定義

    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

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 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的關鍵字。

 

形式如下:

on <trigger>    <command>    <command>    <command>

這整個是一個Section;所有<command>叫action。

 

總結

本文解析了init.rc的基本文法,重點討論on section的解析,service的解析以及property的支援在後續專題中再詳細討論。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.