Init 进程 (Android 中的第一个用户进程)
当我们按下电源键时, 引导 芯片会加载运行引导程序, 引导 程序又启动 Linux 内核,在 Linux内核 加载 完成后,第一件事就是要启动 init 进程。
我们在Android中输入 ps -A | grep init ,就可以看到,init进程的PID为1
(pid=0,linux启动的第一个进程,swapper/idle进程;pid=1,init进程;pid=2,kthreadd进程)
Linux Kernel启动后,会调用init.cpp的main方法。
init进程的源码在/system/core/init/init.cpp (Android11 中 main函数被放在了/system/core/init/main.cpp)
通过阅读源码,我们可以发现init进程有两个阶段,分为 first-stage 和 second-stage
first-stage
源码位于/system/core/init/first_stage_init.cpp
主要功能不详细分析
有兴趣的看Link
- 挂载及创建基本的文件系统,并设置合适的访问权限
- 关闭默认控制台输出,并初始化内核级log。
- 挂载 system、cache、data 等系统分区
second-stage
在 selinux 初始化完成后就立即重新执行main函数,进入第二阶段 second-stage,也就是将 init 进程从内核态转化为用户态执行。
对于second-stage,其也会做一些first-stage的一些工作,但是其主要做的是:初始化和启动属性服务,解析 init.rc 文件,并按顺序先后执行触发器: on early-init -> init -> late-init
低版本中直接通过init_parse_config_file(“/init.rc”); 去对init.rc进行解析,高版本则通过LoadBootScripts去解析*.rc文件,其中就包括后面zygote进程的 init.zygote.rc
加载init.rc后
又会导入init.zygotexx.rc
/system/etc/init/hw/init/init.{ro.zygote}.rc 是手机设备上的路径,和源码中的 system/core/rootdir/init.{ro.zygote}.rc是同一个文件。
init进程在解析完init.rc文件后,会依次执行触发器:on early-init -> init -> late-init。在late-init触发时,就会启动类 main 管理的服务,也就是会启动 zygote。
通过一个死循环,来保证init出来的程序的存活,所以我们如果在kill 一个 init的子进程的时候,会发现这个进程又复活了。
LoadBootScripts(am,sm),这个方法解析了一个init.rc文件,并将这些命令写到了am与sm中,在while循环里通过ExecuteOneCommand去执行这些命令
Zygote
Zygote是Java世界的创造者,Android中的所有Java进程都由Zygote进程fork而来。
Zygote本身也是由Linux系统中的init进程通过解析init.rc脚本启动的,Zygote本身其实就是app_process程序(system/bin/app_process)。
init.zygote32/64.rc(system/core/rootdir/init.zygote32/64.rc)
Service是一些在系统初始化时就启动或者退出时需要重启的程序。
其中Service用于通知init进程创建名zygote的进程,这个zygote进程执行程序的路径为/system/bin/app_process64,后面的则是要传给app_process64的参数。class main指的是zygote的class name为main。
评论区