一.init有三个全局列表:
static list_declare(service_list);
static list_declare(action_list);
static list_declare(action_queue);
service_list记录了系统所有服务的列表;action_list记录了系统动作列表,但是相应的命令是不会运行的,除非将元素移动到queue_list列表;queue_list记录了将要执行的动作列表。
一.
parse_config_file("/init.rc")
on 关键字开头的项将会被会添加到 action_list 列表中。
service关键字定义的服务将会添加到 service_list 列表中。
例如:
on property:persist.service.adb.enable=1
start adbd
分别对应:action->name和action->commands
二.
action_for_each_trigger("early-init", action_add_queue_tail);
在action_list列表里查找以early-init为名的action变量,再调用 action_add_queue_tail(act)将它加到queue_list列表里,实际上就是执行act->name 为 early-init,act->commands列表中的所有命令。
三.
queue_builtin_action(property_init_action,"property_init");
把第一个(action.command.func)和第二个参数(action.name)组装成一个action变量加到action_list和queue_list列表。
四.
在act->name为boot的 act->commands列表中有class_start default
当 class_start 被触发后,实际上调用的是函数 do_class_start()
int do_class_start(int nargs, char **args)
{
/* Starting a class does not start services
* which are explicitly disabled. They must
* be started individually.
*/
service_for_each_class(args[1], service_start_if_not_disabled);
return 0;
}
void service_for_each_class(const char *classname,
void (*func)(struct service *svc))
{
struct listnode *node;
struct service *svc;
list_for_each(node, &service_list) {
svc = node_to_item(node, struct service, slist);
if (!strcmp(svc->classname, classname)) {
func(svc);
}
}
}
因为在调用 parse_service() 添加服务列表的时候,所有服务 svc->classname 默认取值:"default",所以 service_list 中的所有服务将会被执行。
五.
状态服务器相关:
在init.c 的main函数中启动状态服务器。
property_set_fd = start_property_service();
状态读取函数:
Property_service.c (system\core\init)
const char* property_get(const char *name)
Properties.c (system\core\libcutils)
int property_get(const char *key, char *value, const char *default_value)
状态设置函数:
Property_service.c (system\core\init)
int property_set(const char *name, const char *value)
Properties.c (system\core\libcutils)
int property_set(const char *key, const char *value)
在终端模式下我们可以通过执行命令 setprop
setprop 工具源代码所在文件: Setprop.c (system\core\toolbox)
Getprop.c (system\core\toolbox): property_get(argv[1], value, default_value);
Property_service.c (system\core\init)
中定义的状态读取和设置函数仅供init进程调用,
handle_property_set_fd(property_set_fd);
property_set() //Property_service.c (system\core\init)
property_changed(name, value) //Init.c (system\core\init)
queue_property_triggers(name, value)
drain_action_queue()
只要属性一改变就会被触发,然后执行相应的命令:
例如:
在init.rc 文件中有
on property:persist.service.adb.enable=1
start adbd
on property:persist.service.adb.enable=0
stop adbd
所以如果在终端下输入:
setprop property:persist.service.adb.enable 1或者0
那么将会开启或者关闭adbd 程序。