https://blog.csdn.net/qq_30621333/article/details/113863338 (详细的启动框架图)
https://zhuanlan.zhihu.com/p/127074795?utm_source=wechat_session
https://blog.csdn.net/lvyaer_1122/article/details/130508216 (Android12 内核启动与init进程启动)
https://www.jianshu.com/p/3460d78e4299
https://www.cnblogs.com/Oude/p/12365102.html
https://blog.csdn.net/weixin_34399060/article/details/91417682 (详解了Action如何触发、Service如何启动)
https://article.itxueyuan.com/xOMye (selinux机制与init启动)
https://zhuanlan.zhihu.com/p/109199714
https://blog.csdn.net/mafei852213034/article/details/117049319
https://mp.weixin.qq.com/s/N1zIlIETYxHwnxBPVvnGfw (系列型文章,非常之详细!)
https://www.cnblogs.com/yuanqiangfei/p/16802086.html(非常全)
目录
一、init进程启动流程
内核是如何启动init进程的
https://blog.csdn.net/fu_kevin0606/article/details/53320515
https://blog.csdn.net/u010783226/article/details/119810208
通过kernel/init/main.c
中的static int __ref kernel_init(void *unused)
调用init程序
static int __ref kernel_init(void *unused)
{
if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\n",
ramdisk_execute_command, ret);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
panic("Requested init %s failed (error %d).",
execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
1.init进程的启动
内核启动之后将会初始化软硬件环境,加载驱动程序,挂载根文件系统,然后创建 init 进程,init 作为系统中的第一个用户进程,其进程号为 1,在创建 init 进程之时,系统会执行位于 system/core/init
下的 init.cpp 程序.init 进程主要做了三件事情:创建用户空间文件夹并挂载、启动属性服务、解析位于 system\core\rootdir 文件夹下的 init.rc 文件。
2.init.rc配置文件
https://blog.csdn.net/zhonglunshun/article/details/78615980 (几乎每一行都注释了)
要点:
1)Android初始化语言编写(Android Init Language)语法
(https://www.jianshu.com/p/13fb7dbc283c)
包括:Action、Commands、Services(开机服务)、Options和Import。
1-1)Action:
on <trigger> [&& <trigger>]* //设置触发器
<command>
<command> //动作触发之后要执行的命令
Action的command:https://blog.csdn.net/zhangyongfeiyong/article/details/53668124
1-2)Services:
service <name> <pathname> [ <argument> ]* //<service的名字><执行程序路径><传递参数>
<option> //option是service的修饰词,影响什么时候、如何启动services
<option>
...
service的常用option:
https://blog.csdn.net/langxianwenye/article/details/41043261
-
onrestart
在Service重启时执行命令. -
shutdown critical
shutdown critical属性可以被用来标记一个服务为“关闭关键”服务,这意味着在系统关闭过程中,如果这个服务没有正确关闭,系统可能会继续尝试关闭,以防止进入不稳定状态。
service分类
由class关键字标识,有main、core、late_start3种类型。 https://blog.csdn.net/w2064004678/article/details/105651543
Import: 导入子init.rc文件
2)解析
类似于xml解析,反序列化的过程。 Action、Service、Import解析
3.服务的启动(zygote进程启动)
init 进程通过解析 init.rc 文件将 action 保存在 ActionManager 的 actions 链表中,然后通过遍历 actions 链表,执行 action 命令对应的处理函数,从而转至 builtins.cpp 的 do_class_start 函数,之后通过 Service 的 StartIfNotDisabled 调用 Service 的 Start 函数,最终通过 Start 函数创建 zygote 进程,执行对应的 app_main.cpp 文件(frameworks/base/cmds/app_process/app_main.cpp)启动 zygote。
- 查看服务的运行情况 通过
getprop | grep init.svc
可查看所有的service运行状态
4.init进程的作用
init 是系统中的第一个用户进程,它的主要作用是创建用户空间文件夹并挂载、启动属性服务、 解析 init.rc 文件并启动 zygote 进程。
二、Zygote进程启动流程
https://zhuanlan.zhihu.com/p/343232160
https://blog.csdn.net/weixin_34399060/article/details/91417682
init.rc文件中:
import /init.${ro.zygote}.rc
on nonencrypted
# A/B update verifier that marks a successful boot.
exec - root -- /system/bin/update_verifier nonencrypted
class_start main
class_start late_start复制代码
ro.zygote相关文件中,zygote的class是main,所以nonencrypted触发器被触发时,zygote服务启动。
1)nonencrypted触发器何时触发:
研究class_start的实现原理可知:
1-1)init无限循环时system/core/init/builtins.cpp
下用于启动 zygote 的 do_class_start函数将被执行。
1-2)builtins.cpp
会调用service.cpp
的 StartIfNotDisabled方法,最终调用Start方法,创建子进程。
bool Service::Start() {
....
//创建子进程
pid_t pid = fork();
if (pid == 0) {
...
//执行对应 service 对应的执行文件,args_[0].c_str() 就是执行路径
if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
}
_exit(127);
}
....
return true;
}
1-3)接着init.zygotexx.rc的zygote服务调用/system/bin/app_processXX
程序,最终zygote进程在frameworks/base/cmds/app_process/app_main.cpp
中被启动。
0 条评论