if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
mount("proc", "/proc", "proc", 0, NULL);
mount("sysfs", "/sys", "sysfs", 0, NULL);
}
...import导入其他脚本
import /init.${ro.hardware}.rc
import /init.${ro.zygote}.rc
import /init.trace.rc
//on命令
on early-init
//主要这几个关键的服务
service servicemanager /system/bin/servicemanager
service surfaceflinger /system/bin/surfaceflinger
service media /system/bin/mediaserver
init.rc是Android的启动脚本,基本组成单位是section,stction分为三种类型,分别由三个关键字来区分,这三个关键字是import导入、on命令、service服务,接下来看如何解析启动脚本
//初始化signal_handler
signal_handler_init();
...
//解析init.rc启动脚本
init_parse_config_file("/init.rc");
//将early-init加入到队列中
action_for_each_trigger("early-init", action_add_queue_tail);
while (true) {
if (!waiting_for_exec) {
//执行命令
execute_one_command();
restart_processes();
}
}
static void parse_config(const char *fn, const std::string& data)
{
...
for (;;) {
switch (next_token(&state)) {
//T_EOF 如果是文件结束符,则跳转到parser_done
case T_EOF:
state.parse_line(&state, 0, 0);
goto parser_done;
//如果是新的一行,则一行行解析section
case T_NEWLINE:
state.line++;
if (nargs) {
int kw = lookup_keyword(args[0]);
if (kw_is(kw, SECTION)) {
state.parse_line(&state, 0, 0);
//解析section:包括parse
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;
}
}
parser_done:
//循环解析import
list_for_each(node, &import_list) {
struct import *import = node_to_item(node, struct import, list);
int ret;
ret = init_parse_config_file(import->filename);
if (ret)
ERROR("could not import file '%s' from '%s'\n",
import->filename, fn);
}
}
system/core/init/builtins.cpp
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);
return0;
}
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);
//如果名字相等则执行回调函数 service_start_if_not_disabled
if (!strcmp(svc->classname, classname)) {
func(svc);
}
}
}
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc, NULL);
} else {
svc->flags |= SVC_DISABLED_START;
}
}
void service_start(struct service *svc, const char *dynamic_args) {
...
//真正的service启动函数,利用fork子进程,复制父进程中的所有资源
pid_t pid = fork();
if (pid == 0) {
execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
}
}
如何理解fork函数:fork是Linux中创建进程的方式,通过fork来复制父进程中的所有资源,fpid=fork()==0,则子进程创建成功,fork调用一次,但会回调两次:一次是子进程中,一次是父进程中
void signal_handler_init() {
// Create a signalling mechanism for SIGCHLD.
int s[2];
//创建socket pair用于通信
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
ERROR("socketpair failed: %s\n", strerror(errno));
exit(1);
}
//当捕获信号,则写入signal_write_fd
signal_write_fd = s[0];
signal_read_fd = s[1];
// Write to signal_write_fd if we catch SIGCHLD.
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SIGCHLD_handler;
act.sa_flags = SA_NOCLDSTOP;
//SA_NOCLDSTOP 表示只有子进程终止时,父进程才会收到SIGCHLD信号
sigaction(SIGCHLD, &act, 0);
//
reap_any_outstanding_children();
register_epoll_handler(signal_read_fd, handle_signal);
}
static bool wait_for_one_process() {
int status;
//等待任意子进程,如果子进程没有退出则返回0,否则返回pid
pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
if (pid == 0) {
returnfalse;
} elseif (pid == -1) {
ERROR("waitpid failed: %s\n", strerror(errno));
returnfalse;
}
//根据pid查找服务
service* svc = service_find_by_pid(pid);
...
//当svc是RESTART且不是ONESHOT时,kill进程组内的所有进程
if (!(svc->flags & SVC_ONESHOT) || (svc->flags & SVC_RESTART)) {
NOTICE("Service '%s' (pid %d) killing any children in process group\n", svc->name, pid);
kill(-pid, SIGKILL);
}
// 移除已经创建的socket
for (socketinfo* si = svc->sockets; si; si = si->next) {
char tmp[128];
snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
unlink(tmp);
}
//当flag为EXEC时,释放相应服务
if (svc->flags & SVC_EXEC) {
INFO("SVC_EXEC pid %d finished...\n", svc->pid);
waiting_for_exec = false;
list_remove(&svc->slist);
free(svc->name);
free(svc);
returntrue;
}
svc->pid = 0;
svc->flags &= (~SVC_RUNNING);
//对于ONESHOT服务,使其进入DISABLED状态
if ((svc->flags & SVC_ONESHOT) && !(svc->flags & SVC_RESTART)) {
svc->flags |= SVC_DISABLED;
}
//禁用和重置的服务,都不能自动重启
if (svc->flags & (SVC_DISABLED | SVC_RESET)) {
svc->NotifyStateChange("stopped");
returntrue;
}
...
// 执行当前服务中的重启命令
struct listnode* node;
list_for_each(node, &svc->onrestart.commands) {
command* cmd = node_to_item(node, struct command, clist);
cmd->func(cmd->nargs, cmd->args);
}
svc->NotifyStateChange("restarting");
returntrue;
}
init进程是Linux系统中用户空间的第一个进程,做了以下工作
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8