前言
本文是介绍Android系统启动——Init进程。(基于Android 10.0的源码)
目录
Kernel 启动过程会创建 init 进程(pid=1),是用户空间的第一个进程,是所有用户空间进程的鼻祖。init 进程会启动servicemanager(binder服务管家),Zygote 进程(Android中Java进程的鼻祖)。Zygote 进程会创建 system_server 进程以及各种app进程,下图是这几个系统重量级进程之间的层级关系:

init/main.cpp.main
system/core/init/main.cpp
1 | using namespace android::init; |
FirstStageMain
system/core/init/first_stage_init.cpp
FirstStageMain方法主要工作:
- 设置用户组,挂载相关系统文件
- 根据
/force_debuggable文件来判断是否允许adb root指令 - 执行init进程main方法,通过
execv(path,{path,“selinux_setup”,nullptr})进入SetupSelinux
SetupSelinux
system/core/init/selinux.cpp
SetupSelinux方法主要工作:
- 初始化SELinux,然后以在init SELinux上下文中运行。
- 执行init进程main方法,通过
execv(path,{path,“second_stage”,nullptr})进入SecondStageMain
SecondStageMain
system/core/init/init.cpp
SecondStageMain方法主要工作:
- 使用epoll对init进程的子进程(Zygote)的异常退出信号进行监听和处理
- 初始化系统属性,使用mmap共享内存,”/dev/properties/property_info” (重要)
- 开启属性服务,并注册到epoll中(重要)
- 加载系统启动脚本”/init.rc”
- 解析启动脚本,启动相关服务
总结下init里面main方法做的事情:
- first stage 初始化环境变量和各种文件系统目录,klog初始化等
- selinux相关初始化完成,然后切换second stage 重启init进程
- 属性服务初始化,将各种系统属性默认值填充到属性Map中
- 创建epoll描述符结合注册socket监听,处理显示启动进程和挂掉的子进程重启
- 解析init.rc。把各种action、service等解析出来的填充到相应链表容器管理
- 有序将early-init、init等各种cmd加入到执行队列action_queue链表中
- 进入while()循环依次取出执行队列action_queue中的command执行,fork包括app_process在内的各种进程,epoll阻塞监听处理来自挂掉的子进程的消息,根据设定策略restart子进程。
总结
init进程的执行过程,调用init.main()方法:
- 创建和挂载启动所需的文件目录
- 处理子进程的终止(signal信号量方式)
- 初始化和启动属性服务
- 解析init.rc配置文件并启动Zygote进程
引用文章: