您的位置:首页 > 移动开发 > Android开发

android启动代码init.c文件分析(三)

2013-02-01 21:44 369 查看
/*****************************************************************

*version:android4.2

*author:冷雨

*嵌入式开发群:122879839

*****************************************************************/

我们回到system/core/init/init.c文件中,上一部分我们完成了解析文件的过程,现在我们来看两个函数。先看代码。
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");

#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif


这部分代码其实主要就是两个函数action_for_each_trigger和queue_builtin_action函数。我们首先看一下action_for_each_trigger函数,这个函数位于system/core/init/init_parser.c文件中。我们以第一次使用它的那段代码为例分析一下。
action_for_each_trigger("early-init", action_add_queue_tail);
void action_for_each_trigger(const char *trigger,
void (*func)(struct action *act))
{
struct listnode *node;
struct action *act;
list_for_each(node, &action_list) {
act = node_to_item(node, struct action, alist);
if (!strcmp(act->name, trigger)) {
func(act);
}
}
}


这个函数逻辑很简单,首先在action_list中寻找那个和early-init同名的那个action结构体,如果能够找到的话就执行传入的第二个参数名的函数。
void action_add_queue_tail(struct action *act)
{
list_add_tail(&action_queue, &act->qlist);
}


也就是将刚才取得的那个action结构体添加到action_queue尾部。
现在我们看看另一个函数queue_builtin_action,我们仍然是以第一次使用它的地方为例。
queue_builtin_action(wait_for_coldboot_done_action,"wait_for_coldboot_done");
void queue_builtin_action(int (*func)(int nargs, char **args), char *name)
{
struct action *act;
struct command *cmd;

act = calloc(1, sizeof(*act));
act->name = name;
list_init(&act->commands);

cmd = calloc(1, sizeof(*cmd));
cmd->func = func;
cmd->args[0] = name;
list_add_tail(&act->commands, &cmd->clist);

list_add_tail(&action_list, &act->alist);
action_add_queue_tail(act);
}


在这个函数函数中构造了一个action结构体和一个command结构体,并且将command结构体链入action结构体,将action结构体链入action_list,最后调用action_add_queue_tail函数,即将这个action链入全局链表action_queue。
在刚才我们贴出的system/core/init/init.c文件中通过action_for_each_trigger和queue_builtin_action函数将许多action结构体链入了action_queue。在下一部分我们就会看到这样做的作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: