按下电源 —— 系统启动后加载引导程序 [[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-initfspost-fspost-fs-datalate-initboot,每一级都可能 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.cppinit.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之前?

  1. Binder 体系的“根服务”
    servicemanagerBindercontext manager(“0 号节点”)。后面所有 Java / Native 服务(包含 SystemServer 本身)都要先连接它,才能注册或查询 Binder 接口。如果它没先起来,zygote → SystemServer 注册服务会直接失败。

  2. SystemServer 要“汇报”
    SystemServer 启动后会把 ActivityManagerPackageManager 等几十个系统服务注册到 “已启动的 servicemanager” 上去。官方博客也特地提到 “SystemServer 会把服务注册到 previously started Service Manager 上”codecentric AG

  3. 崩溃自恢复机制
    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 和同组里其他早期守护(ueventdlogdvold 等)。

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