按下电源 —— 系统启动后加载引导程序 [[BootLoader]] —— 引导程序启动该Linux内核 —— 在系统文件中寻找init.rc 文件 —— 启动 init 进程。
[[第1-5天:Android 启动流程与底层机制]]
init 的启动过程
init 时序图
| 区域 | 关键点 |
|---|---|
| stage-1 | 只干三件事:加载 SELinux policy、挂最基本的伪文件系统、然后 execve 自身进入 2 nd stage。 |
| stage-2 | 解析所有 init*.rc ,建好 Action/Service 拓扑,启动属性服务和若干守护进程。 |
| Action 阶梯 | early-init → fs → post-fs → post-fs-data → late-init → boot,每一级都可能 start/执行服务或脚本。 |
| 关键守护 | servicemanager 是 Binder 0;logd 统一日志管道;lmkd 负责内存回收;watchdogd 负责系统级看门狗。 |
init.cpp
init.cpp里执行的固定顺序为: early-init → init → late-init → boot
int SecondStageMain(int argc, char** argv) {
ActionManager& am = ActionManager::GetInstance();
am.QueueEventTrigger("early-init");
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");
}
init.rc
在 init.rc 里可以看到 on init 里执行了 start servicemanager (init.cpp 和 init.rc 的关系可以看这篇文档 init.rc 介绍 ) :
on init
# Start logd before any other services run to ensure we capture all of their logs.
start logd
# Start essential services.
start servicemanager
start hwservicemanager
start vndservicemanager
on late-init
# Now we can start zygote.
trigger zygote-start
trigger early-boot
trigger boot
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
exec_start update_verifier
start statsd
start zygote
start zygote_secondary
on boot
# Start standard binderized HAL daemons
class_start hal
class_start core
on nonencrypted
class_start main
class_start late_start
✅ 顺序铁律:队列先入先执行,
所以 init → late-init → zygote-start → boot → nonencrypted
| 时刻 | 发生的动作 | 代表进程 | 结果 |
|---|---|---|---|
| T0 | on init |
start servicemanager |
Binder 0 就位 |
| T1 | on init 同批 |
start hwservicemanager / vndservicemanager |
HIDL/VINTF 管理器就位 |
| T2 | on late-init |
trigger zygote-start |
把 zygote-start 丢进队列 |
| T3 | on zygote-start |
start zygote / zygote_secondary |
Java 世界起点 |
| T4 | on boot |
class_start core & hal |
拉起其余早期 native 守护(logd 已在 T0 启动,servicemanager 已存在因此跳过) |
| T5 | on nonencrypted |
class_start main & late_start |
继续拉起 SystemServer、Bluetooth、SurfaceFlinger… |
init.zygote.rc
service zygote ......
class main
zygote 的服务行里写的是 class main,只有 class_start main 之后才启动。而 class_start main 可以看到在 init.rc 里在 on boot 的 .
当 on init 里的 start servicemanager 执行之后,稍后在 on boot 执行的 class_start core 会把同属 core 的其它早期守护(logd、vold、ueventd …)全部拉起;若 servicemanager 已在运行,init 只会略过,不会重复启动。
servicemanager
在官方代码库搜索关键词的正确方式 servicemanager.rc 代码详解
frameworks/native/cmds/servicemanager/servicemanager.rc :
service servicemanager /system/bin/servicemanager
class core animation
user system
onrestart class_restart --only-enabled main // 重启 main 类中所有【已启用】 服务
为什么servicemanager在zygote之前?
-
Binder 体系的“根服务”
servicemanager是Binder的 context manager(“0 号节点”)。后面所有 Java / Native 服务(包含 SystemServer 本身)都要先连接它,才能注册或查询 Binder 接口。如果它没先起来,zygote → SystemServer注册服务会直接失败。 -
SystemServer 要“汇报”
SystemServer启动后会把ActivityManager、PackageManager等几十个系统服务注册到 “已启动的 servicemanager” 上去。官方博客也特地提到 “SystemServer 会把服务注册到 previously started Service Manager 上” codecentric AG。 -
崩溃自恢复机制
servicemanager.rc里还能看到:onrestart class_restart --only-enabled main # 重启 main 类中所有【已启用】 服务zygote 属于
class main,所以 间接 被一起重启。system/core/rootdir/init.zygote64.rc:service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main # ← 所属 main——如果 servicemanager 挂掉,init 会强制重启 zygote(以及 media、surfaceflinger 等),反向保证系统一致性。要做到这点,就必须“先有 servicemanager,再有 zygote”。
servicemanager 是 Binder 世界的“地基”,必须在 zygote 之前就绪;时序图与 AOSP 代码完全对应,你看到的顺序确实是对的 ✅
怎么确认 servicemanager 属于 core class?
在上述代码里有一行:
class core animation
把 servicemanager 收进了 core 组;
当 class_start core 执行时,init 会同时 fork-exec servicemanager 和同组里其他早期守护(ueventd、logd、vold 等)。
servicemanager 为何既在 core,又要手动 start?
-
service servicemanager … class core──归属 core,让它符合分层语义。 -
手动
start servicemanager──确保在任何 class 批处理之前就起,
这样zygote / SystemServer连接Binder时必定能成功。
当 T4 执行 class_start core 时,init 发现 servicemanager 已经 running,
只会 略过,不会再 fork 一次。
为什么要“servicemanager 挂了就拉 zygote / main 全家”?
-
servicemanager = Binder 体系的 0 号节点。
一旦它被重启,内部的「名字→句柄」映射表会清空。 -
Java 世界(zygote → SystemServer → 各系统服务)得重新 re-register 才能继续被客户端发现。
-
用 onrestart class_restart main 能一次性把 zygote、SystemServer 以及所有 Java 服务统统重启,自动完成重新注册。
总结
| 文件 | 作用 | 执行/触发点 |
|---|---|---|
rootdir/init.rc |
通用顶级脚本:挂载、目录创建、触发后续阶段 | on init / late-init / boot … |
init.cpp |
C++ 主程序;解析 .rc、排队 Action、发事件 | 进程 PID 1,贯穿始终 |
拆分 .rc(import 机制) |
import /{system,vendor,…}/etc/init 递归解析,次序固定按目录字典序 (Chromium Git Repositories) |
|
servicemanager.rc |
定义 Binder 0 守护 | 被 start servicemanager(on init)直接拉起;若崩溃 → 重启 class main(含 zygote) |
init.zygote*.rc |
定义 zygote 服务 | 由 trigger zygote-start 调用 start zygote |
