Android-init進程(1)

來源:互聯網
上載者:User

Android-init進程(1)

init進程是android啟動的第一個進程 進程pid為1.其主要做了如下幾件事:

*解析設定檔

*根據設定檔執行操作early_init init early_boot boot

*設定屬性服務


本節主要內容講解如何解析init.rc檔案和運行zygote.

1.解析init.rc設定檔

/**init.c*/

在main函數中,執行如下函數:

init_parse_config_file("/init.rc");
/**init_parse.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);

parse_config函數主要找到一個SECTION的節點開始解析if (kw_is(kw, SECTION)) {        state.parse_line(&state, 0, 0);        parse_new_section(&state, kw, nargs, args);} 

kw_is函數執行了keywords檔案 並找處指定標示 k_##symbol

/**keywords.h*/

1>定義枚舉.枚舉值為k_class k_mkdir等
2>定義結構體數組keyword_info,把KEYOWRD宏改變成結構體,通過宏定義找出symbol與func解析init.rc檔案
如關鍵字section的symbol為chdir 則找到如int do_chdir(int nargs, char **args)的聲明查看對應定義
>>>關鍵字有:OPTION,COMMAND,SECTION
/**init.rc*/
on init #表示on的SECTION名稱為init 基本步驟為early-init init early-boot boot
#從一個section開始 到下一個section開始標籤前結束

export ANDROID_ROOT /system #表示export為一個COMMAND

*如




2.分析zygote

/**init.rc設定檔*/

在該檔案中 zygote被定義為需要執行4個操作並且擁有一個socket為660的服務,他是init的一個子進程.<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxicj4KPC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd
---------------Service定義資訊------------------
-維護所有產生Service的一個雙向鏈表listnode
-service的name zygote的name為init.svc.zygote
-className 預設"default"
-屬性flag pid uid gid io優先順序 參數(個數)
-time_started time_crashed nr_crashed 上次啟動死亡時 總死亡次數
-socketinfo(socket環境變數資訊) svcenvinfo(進程所需環境變數資訊)
-struct action onrestart; 儲存OPTION後面的COMMAND資訊
------------------------------------------------

---------------onrestart定義資訊------------------

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 a trigger */    struct listnode tlist;    unsigned hash;    const char *name;        struct listnode commands;    struct command *current;//儲存restart裡面的COMMOND動作};

------------------------------------------------


/**init_parse.c*/
#主要執行parse_service 和parse_line_service
//建立service結構體主要架構,並添加到service_list雙向鏈表中
//socketinfo是一個單向鏈表 zygote只有一個660 的TCP scoket
//onrestart通過commond指向一個commonds鏈表 zygote如上在init.rc中可以看出有4個commond

static void *parse_service(struct parse_state *state, int nargs, char **args){struct service *svc;svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);    if (!svc) {        parse_error(state, "out of memory\n");        return 0;    }    svc->name = args[1];    svc->classname = "default";    memcpy(svc->args, args + 2, sizeof(char*) * nargs);    svc->args[nargs] = 0;    svc->nargs = nargs;    svc->onrestart.name = "onrestart";    list_init(&svc->onrestart.commands);    list_add_tail(&service_list, &svc->slist);    return svc;}

static void parse_line_service(struct parse_state *state, int nargs, char **args){struct service *svc = state->context;        nargs--;        args++;        kw = lookup_keyword(args[0]);//建立Commond結構體        cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);        cmd->func = kw_func(kw);        cmd->nargs = nargs;        memcpy(cmd->args, args, sizeof(char*) * nargs);//添加到雙向列表中        list_add_tail(&svc->onrestart.commands, &cmd->clist);}

**********init 啟動zygote**********
1)init.c::main>
// 將boot的commond加入到執行隊列中 因為zygote 包含在boot動作中
action_for_each_trigger("boot", action_add_queue_tail);
//執行隊列中的commond 並統一執行所有section的commond
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
2)Bultins.c::do_class_start>
//因為class_start是一個COMMOND所以他會被執行 在這裡zygote是一個 "default"的className
//所以執行service_start_if_not_disabled函數

//如果service的flag被明確規定為disable 那麼執行該service必須單獨再執行
service_for_each_class(args[1],service_start_if_not_disabled);
3)Bultins.c::service_start_if_not_disabled>
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc, NULL);//之前設定沒有建立flags 表示該service還未啟用 執行service_start
}
4)init.c::service_start>
>>判斷檔案進程/system/bin/process檔案是否存在 一般service有自己的進程
rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
>>啟動init子進程
pid = fork();
>>添加進程環境變數資訊
>>添加socket環境變數資訊並建立socket
>>設定uid gid並啟動/system/bin/app_process檔案的main函數

>>設定service的啟動時間 pid等等


**********init 重啟zygote**********
>>綁定操作 響應事件
1)init.c::main>>
queue_builtin_action(signal_init_action, "signal_init");
2)init.c::signal_init_action>>
signal_init();
3)signal_handler::signal_init>>
struct sigaction act;//綁定2個方法 sigchld_handler handle_signal 其結構體還包括了一個sa_flags標示
>>zygote死後父進程init調用sigchld_handler
1)signal_handler::sigchld_handler>>
write(signal_fd, &s, 1);//往signal_fd中寫資料 signal_fd是socketpair中兩條socket中的一條
2)init.c::main>>
nr = poll(ufds, fd_count, timeout);
if (nr <= 0)
continue;
for (i = 0; i < fd_count; i++) {
if (ufds[i].revents == POLLIN) {
else if (ufds[i].fd == get_signal_fd())
handle_signal();
}
}
3)signal_handler::handle_signal>>
read(signal_recv_fd, tmp, sizeof(tmp));
while (!wait_for_one_process(0)) ;
4)signal_handler::wait_for_one_process>>
//殺掉zygote的所有子進程
//清除我們將要重建的scoket
//將所有onrestart的commond(zygote中有4個)添加到svc中的action結構體列表中
//改變svc狀態為restarting
5)init.c::main>>
//poll後進入下一輪迴圈 又執行main
execute_one_command();//執行所有COMMOND

restart_processes();//改變flag標識


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.