天天看點

android init.rc解析

參考:system/core/init/readme.txt (android init language)

init.rc名詞:action,service,commands,option,trigger

1. action

一系列commands的集合,由觸發器控制執行順序

on post-fs-data
    chown system system /data
    chmod 0771 /data
           

2. commands

可執行的commands和可以使用的option在system/core/init/keywords.h中定義。

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(class_reset, COMMAND, 1, do_class_reset)
    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)
           

每個commands的實作為do_commands。

3. option

option如上定義。option用來修飾service,影響service的運作。

critical(關鍵)

            說明這是一個對于裝置關鍵的服務。如果他四分鐘内退出大于四次,系統将會重新開機并進入recovery(恢複)模式。

disabled(失效)

            說明這個服務不會同與他同trigger(觸發器)下的服務自動啟動。他必須被明确的按名啟動。

setenv <name> <value> (設定環境變量)

            在程序啟動時将環境變量<name>設定為<value>。

socket <name> <type> <perm> [ <user> [ <group> ] ]

            建立一個Uinx域的名為/dev/socket/<name> 的套接字,并傳遞它的檔案描述符給已啟動的程序。<type> 必須是 "dgram"或"stream"。User 和 group預設為0。

user <username>

            在啟動這個服務前改變該服務的使用者名。此時預設為root。目前,如果你的程序要求Linux capabilities(能力),你無法使用這個指令。即使你是root,你也必須在程式中請求capabilities(能力)。然後降到你想要的 uid。

group <groupname> [ <groupname> ]*

            在啟動這個服務前改變該服務的組名。除了(必需的)第一個組名,附加的組名通常被用于設定程序的補充組(通過setgroups())。此時預設為root。

oneshot

            服務退出時不重新開機。

class <name>

            指定一個服務類。所有同一類的服務可以同時啟動和停止。如果不通過class選項指定一個類,則預設為"default"類服務。

onrestart

            當服務重新開機,執行一個指令

4. service

service定義格式:

service name path args
		option
           

重要服務舉例:adbd, ril-daemon,vold,zygote

service vold /system/bin/vold
    class core
    socket vold stream 0660 root mount
    ioprio be 2
           

service在代碼中啟動:

c++:
<span style="white-space:pre">	</span>property_set("ctl.start", "service_name");
<span style="white-space:pre">	</span>property_set("ctl.stop", "service_name");
java:
<span style="white-space:pre">	</span>SystemProperties.set
           

5. trigger

控制action發生,trigger發生時,action的commands依次加入到隊列執行。

服務啟動順序

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");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");

    /* execute all the boot actions to get us started */
    action_for_each_trigger("init", action_add_queue_tail);

    /* skip mounting filesystems in charger mode */
    if (!is_charger) {
        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);
        action_for_each_trigger("post-fs-data", 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");

    if (is_charger) {
        action_for_each_trigger("charger", action_add_queue_tail);
    } else {
        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_property_triggers");
           

init.rc解析完成後,依次将這些trigger加入,對應的action加入隊尾開始執行。

on boot
    class_start core
    class_start main
           

on boot最後class_start core & main,class 為core和main的service開始依次執行。