一、Android 启动流程概括
按下电源键触发开机,从 ROM 加载引导程序 BootLoader 到 RAM 中,BootLoader 执行启动 Linux kernel,然后启动第一个用户进程 init,init 进程的工作包括挂载文件、创建文件目录、设置 selinux 安全策略,解析 init.rc 脚本等。随后 init 进程会启动 Zygote 进程,Zygote 进程做一些资源预加载的工作,并启动 SystemServer 进程。SystemServer 进程作为 Socket 服务端,启动包括 AMS、WMS、PMS 等 90 多个服务在内的系统服务。在众多服务启动完毕后,AMS 会打开 Launcher 应用的 Home Activity,进入手机桌面。
附:kernel 的初始化流程(详细代码自行下载 linux kernel 源码)
传统的加载器包含两个文件
init.s:初始化堆栈,调用 main.c 的 main() 函数
main.c:初始化硬件(主板、闹钟等),创建 linux 标签
当内核完成系统设置后,会在系统文件中寻找 init 文件。
Dir:kernel/common/init/main.c
(1)执行 kernel_init() 函数
(2)启动 /bin/init 文件:try_to_run_init_process("/bin/init");
(3)try_to_run_init_process() ---> run_init_process()--->kernel_execve()
init/android.bp 中指明了 init 的入口函数:init/main.cpp,随后会执行 main.cpp 中的 main 方法
二、init 进程的启动流程
Dir:system/core/init/main.cpp ---> main() 方法
FirstStageMain() ---- SetupSelinux() ---- SecondStageMain()
第一阶段
FirstStageMain()
1、mount()--挂载文件、mkdir()--创建文件目录
2、SetStdioToDevNull()--重定向标准输入输出
3、InitKernelLogging()--初始化内核日志
4、启动 setupSelinux
SetupSelinux()
配置安全策略 -- 对应安卓的权限策略
第二阶段
SecondStageMain()
1、初始化属性系统
PropertyInit()
2、监听子进程的终止信号,释放资源,防止僵尸进程
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
StartPropertyService(&property_fd);
3、匹配 linux 命令和实际执行函数之间的关系
GetBuiltinFunctionMap()
4、解析 init.rc
LoadBootScripts(am, sm)
-->CreateParser() //创建解析器
-->//添加 rc 文件的解析组件 service、on、import
parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
-->//解析 rc 文件