分析脚本文件AndroidInitProcess分析心得(1)
本篇文章是一篇關(guān)于分析腳本文件的帖子
????眾所皆知,Android Init process是Android動(dòng)啟后先最起來的進(jìn)程. 真正說來Android Init process是由Linux Kernel的動(dòng)啟程序所驅(qū)動(dòng)起來. 從device上電, Bootloader載加Kernel, 然后Kernel接著驅(qū)動(dòng)Android Init process. 這一段屬于Linux 的范疇, 其簡(jiǎn)略的數(shù)函呼叫流程如下:
?
????kernel_init===> init_post ==> run_init_process ==> 動(dòng)啟 Android Init process.
?
????由于這篇重要是分析AndroidInit process在處始化所作的作工, 因此kernel_init, init_post,run_init_process 這三個(gè)數(shù)函里的流程就不在這里作分析.
?
??????? Android Init process 在初始化階段重要做三件事.
????1. 分析和執(zhí)行init.rc腳本文件
????2. 建創(chuàng)devicenode file
????3. 監(jiān)控系統(tǒng)屬性變更跟事件
????以下就分離依照這三點(diǎn)來做研討分析.
????分析和執(zhí)行init.rc腳本文件
??????? init.rc腳本文件重要是用來設(shè)定Android系統(tǒng)環(huán)境,還有一些待執(zhí)行的進(jìn)程記載.整個(gè)腳本文件可以分為兩類action list跟 service list. 這兩類會(huì)根據(jù)腳本文件中的關(guān)鍵詞來作分類,
??????? 1. 以"on"關(guān)鍵詞掃尾的為actionlist中的素元,
??????? 2. 以"Services"關(guān)鍵詞的為servicelist中的素元.
????這兩個(gè)關(guān)鍵詞就跟init.rc腳本文件用使的AIL(Android Init Language)有關(guān)了.AIL 重要包括四種類型, Action, Commands, Services, Option. 這四類的法語用法在system\core\init\readme.txt中有詳細(xì)描述. 這里只是簡(jiǎn)略的紹介這四類的關(guān)系, 法語用法請(qǐng)考參system\core\init\readme.txt.
??????? Action和Services代表著一段新的Section,全部的Section下都有Command跟Option的一些告宣.Command最重要是用來建創(chuàng)一些系統(tǒng)目錄或是動(dòng)啟進(jìn)程.Option則作為ServicesSection的一些屬性設(shè)定. 比如進(jìn)程是不是從新被動(dòng)啟.
??????? 分析和執(zhí)行init.rc腳本文件的研討分析就由init_parse_config_file數(shù)函開始.因?yàn)榇藬?shù)函是正用來init.rc腳本文件作分析流程.
// \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; } 每日一道理父親對(duì)于兒子說來,是座聳立的高山,而兒子只是顆石子,源于山,卻并不了解山。生活中諸多愛的密碼,是需用細(xì)節(jié)來解讀的,在親情的沃土上,要想搞得最美的果實(shí),惟有期待那存在于瞬間的心與心的共鳴,愛與愛的默契。
????由面上的程序代碼可以很楚清的看到, 只是把init.rc腳本文件中的section中的command跟option的動(dòng)作入加actionlist和service list待等執(zhí)行.入加的動(dòng)作可以研討 parse_action 和 parse_service的實(shí)作.分析流程先到此, 以后再來看parse_action 和 parse_service的實(shí)作.
??????? 以上是作init.rc腳本文件的分析流程, 而init.rc腳本文件的執(zhí)行流程就由execute_one_command 數(shù)函來實(shí)作.
// \system\core\init\init.c void execute_one_command(void) {int ret;if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {cur_action = action_remove_queue_head();cur_command = NULL;if (!cur_action)return;INFO("processing action %p (%s)\n", cur_action, cur_action->name);cur_command = get_first_command(cur_action);} else {cur_command = get_next_command(cur_action, cur_command);}if (!cur_command)return;ret = cur_command->func(cur_command->nargs, cur_command->args);INFO("command '%s' r=%d\n", cur_command->args[0], ret); }????此數(shù)函執(zhí)行到最后是利用cur_command所帶的function去執(zhí)行actionlist中的command. 此cur_command所帶的function是底到甚么呢? 可以由后面的呼叫數(shù)函 get_first_command和 get_next_command去推導(dǎo).
// \system\core\init\init.c static struct command *get_first_command(struct action *act) {struct listnode *node;node = list_head(&act->commands);if (!node || list_empty(&act->commands))return NULL;return node_to_item(node, struct command, clist); }static struct command *get_next_command(struct action *act, struct command *cmd) {struct listnode *node;node = cmd->clist.next;if (!node)return NULL;if (node == &act->commands)return NULL;return node_to_item(node, struct command, clist); }????到此我們只知道這兩個(gè)數(shù)函只是從action list把a(bǔ)ctioncommand node的據(jù)數(shù)取出來, 至于這個(gè)command node所帶的function還是不知道怎么來的?
??????? 只好在往分析流程去找蛛絲馬跡了. 在分析流程中直一執(zhí)行到利用parse_config數(shù)函來做析解init.rc的動(dòng)作時(shí), 有發(fā)明在呼叫parse_new_section之前會(huì)須要先執(zhí)行l(wèi)ookup_keyword數(shù)函去獲得一個(gè)keyword作當(dāng)參數(shù). 就來從這數(shù)函開始分析
文章結(jié)束給大家分享下程序員的一些笑話語錄: 很多所謂的牛人也不過如此,離開了你,微軟還是微軟,Google還是Google,蘋果還是蘋果,暴雪還是暴雪,而這些牛人離開了公司,自己什么都不是。
總結(jié)
以上是生活随笔為你收集整理的分析脚本文件AndroidInitProcess分析心得(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql5.5数据库安装
- 下一篇: man-翻译和epoll相关的内容,部分