浅析kernel启动的第1个用户进程init如何解读init.rc脚本
来源:互联网 发布:平板上淘宝直播怎么看 编辑:程序博客网 时间:2024/05/10 15:15
浅析kernel启动的第1个用户进程init如何解读init.rc脚本
首先解读
1.on init字段到来,state->context为新申请到的struct action结构体,并将其挂接到action_list尾部,然后初始化处理方法,
之后该section内的所有command都将挂接到act->commands链表上,这样也就有了立体层次[luther.gliethttp].
state->parse_line = parse_line_action;这样以后的"行脚本"将使用这个方法来做处理.
2.loglevel 3因为为cmd,
所以会将动态malloc一个struct command缓冲区,
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(&act->commands, &cmd->clist);//先将cmd结构体放到list链表尾,后面会集中处理.
3.之后就都是上面的重复工作了.
一个on和一个service都将创建一个新的struct action结构体,之后作为当前state->context来处理接下来的所有cmd,
所以接下来的所有cmd也就都将挂接到这个新的act->commands链表上,感觉这样一来脚本非常有层次感,管理起来也很舒服.
4.对于service服务段处理,如果为service命令,那么,先检查service_list链表上是否已经有了同名的服务[luther.gliethttp].
svc = service_find_by_name(args[1]);
if (svc) {
parse_error(state, "ignored duplicate definition of service '%s'/n", args[1]);
return 0;
}
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;
list_add_tail(&service_list, &svc->slist);//将这个service控制结构体添加到service_list链表尾.
然后将paser的方法指向service方法
state->parse_line = parse_line_service;//以下所有参数都将使用parse_line_service进行解析.
5.service命令后边的参数都将用来改变该service控制结构体里的项,不同的service命令,
对args有不同的解析方式,都在parse_line_service中完成,比如:
1 service dund /system/bin/dund /
2 --listen --channel=5 --nodetach --pppd=/system/bin/pppd /
3 192.168.0.100:192.168.0.101 nodefaultroute unit 1 linkname bluetooth
4 user bluetooth
5 group bluetooth net_bt_admin
6 disabled
那么1行开始将申请一个service结构体,然后挂接到service_list链表上,
之后的5行都是用来控制这个service结构体里边的数据项,直到在行首遇到下一个service关键字或者on才会停止[luther.gliethttp].
好了,基本的命令字和立体的脚本解析结构,已经说完了,那么从init.rc脚本解析出来的咚咚在啥时候用呢,
1.对于on节提供的对外接口
void action_for_each_trigger(const char *trigger,
void (*func)(struct action *act))
void queue_property_triggers(const char *name, const char *value)
void queue_all_property_triggers()
举个例子
action_for_each_trigger("early-init", action_add_queue_tail);
action_for_each_trigger("init", action_add_queue_tail);
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
2.对于service节提供的对外接口
struct service *service_find_by_name(const char *name)
struct service *service_find_by_pid(pid_t pid)
void service_for_each_class(const char *classname,
void (*func)(struct service *svc))
void service_for_each_flags(unsigned matchflags,
void (*func)(struct service *svc))
举个例子
int do_start(int nargs, char **args)
{
struct service *svc;
svc = service_find_by_name(args[1]);
if (svc) {
service_start(svc);
}
return 0;
}
- 浅析kernel启动的第1个用户进程init如何解读init.rc脚本
- 浅析kernel启动的第1个用户进程init如何解读init.rc脚本
- 第1个用户进程init和init.rc脚本
- init进程 && 解析启动脚本init.rc && init.rc中启动sh文件 && JAVA中跑shell
- Android的启动脚本–init.rc
- Android的启动脚本–init.rc
- Android 启动分析 init进程 init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android启动脚本init.rc
- Volatile小记
- row_number()函数用法
- TypeError: __init__() got an unexpected keyword argument ‘maxlength’
- acm pku 1050 To the Max的动态规划方法
- 蜀道难 -- 李白
- 浅析kernel启动的第1个用户进程init如何解读init.rc脚本
- 浅析iniit.rc脚本中的service程序不写disabled字段why会自动执行
- Talking about Android Process
- php
- 2010南非世界杯电视直播表
- 地理-思想-意识-行为
- huffman树的编码及应用
- 这就是“爱”
- B-样条曲线的导数