按下电源 —— 系统启动后加载引导程序 [[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 |