Android 7系统休眠唤醒(二)开机全链路—Boot ROM到Launcher
系列目录:第一篇:电源管理架构全景图 |第二篇:开机全链路—BootROM到Launcher| 第三篇:关机/重启全链路—ShutdownThread到kernel_power_off | 第四篇:休眠唤醒与开关机—核心差异深度对比 | 第五篇:休眠全链路—PMS到Kernel Suspend | 第六篇:唤醒全链路—Kernel Resume到屏幕点亮 | 第七篇:内核层—wakelock与autosleep机制 | 第八篇:内核层—Alarm定时唤醒与硬件唤醒源 | 第九篇:Native层—libsuspend与Power HAL | 第十篇:实战调试与问题排查
一、为什么要理解开机流程
要理解休眠唤醒为什么快,必须先理解正常开机有多慢。开机流程是一套"从零开始重建整个世界"的完整链路,涵盖硬件初始化、内核启动、用户空间进程孵化、系统服务启动、应用启动等六大阶段。
当你遇到以下问题时,理解开机流程是关键:
- “为什么开机要 30 秒以上?”——
ZygoteInit.preloadClasses()需要从/system/etc/preloaded-classes预加载数千个类,这是最耗时的单步操作 - “为什么某些系统服务在开机后不可用?”——该服务可能在
startBootstrapServices阶段创建但在systemReady()阶段才完全就绪 - “为什么 BOOT_COMPLETED 广播收到时某些服务还没初始化完?”——
BOOT_COMPLETED在AMS.systemReady()中发送,但startOtherServices中的服务可能尚未完成systemReady()
二、开机流程全景概览
Android 开机可划分为六个阶段,每个阶段依赖于前一阶段的完成,形成严格的串行依赖链:
BootROM → BootLoader → Linux Kernel → init → Zygote → SystemServer → Launcher (硬件) (硬件) (内核) (init) (Java孵化) (框架服务) (桌面)三、阶段一:BootROM — 芯片上电的第一段代码
BootROM 是固化在 SoC 内部 ROM 中的代码,不可修改,上电后由硬件自动执行。它的职责非常单一:
- 初始化最基本的硬件(时钟、栈指针、少量 SRAM)
- 从预设的存储介质(eMMC / UFS / NAND)中加载 BootLoader 的第一阶段(SPL,Secondary Program Loader)到内部 SRAM
- 验证 SPL 的签名(secure boot 使能时)
- 跳转到 SPL 执行
BootROM 代码由芯片厂商提供,不在 AOSP 开源范围内。不同 SoC 厂商实现差异很大,但职责相同。
四、阶段二:BootLoader — 板级初始化与内核加载
4.1 LK (Little Kernel) 与 U-Boot
Android 设备常见的 BootLoader 有两种:
- LK (Little Kernel):高通、MTK 等多数厂商使用
- U-Boot:部分芯片厂商或开发板使用
以 LK 为例:
源码路径:bootable/bootloader/lk/
LK 的核心启动路径:
_start (arch/arm/crt0.S) → kmain() (kernel/main.c) → platform_early_init() — 板级早期初始化(时钟、DDR、UART) → apps_init() — 启动 LK 内建应用 → aboot_init() (app/aboot/aboot.c) → boot_linux() — 加载并启动 Linux 内核4.2 boot.img 的结构
BootLoader 需要从存储分区中读取boot.img。Android 的boot.img包含三部分:
+-----------------+ | boot header | 页大小、kernel大小、ramdisk大小等元信息 +-----------------+ | kernel | 压缩后的 Linux 内核镜像 (Image.gz) +-----------------+ | ramdisk | cpio/gzip 压缩的初始根文件系统 +-----------------+ | dtb (可选) | Device Tree Blob,硬件描述信息 +-----------------+源码路径:system/core/mkbootimg/mkbootimg.c
4.3 加载内核
LK 的boot_linux()函数完成:
- 将 kernel 解压到内存指定位置
- 将 ramdisk 加载到内存
- 设置内核启动参数(cmdline),如
console=ttyMSM0、androidboot.hardware=qcom等 - 设置 ATAGs 或 Device Tree
- 跳转到内核入口点,交出控制权
五、阶段三:Linux Kernel 启动
5.1 内核启动流程
内核入口为架构相关的汇编代码:arch/arm/kernel/head.S(ARM32)或arch/arm64/kernel/head.S(ARM64)。
核心 C 入口:
源码路径:init/main.c
start_kernel() → setup_arch() — 架构相关初始化,解析 Device Tree → mm_init() — 内存管理子系统初始化 → sched_init() — 调度器初始化 → init_IRQ() — 中断子系统初始化 → console_init() — 控制台初始化 → rest_init() → kernel_thread(kernel_init) — 创建 init 内核线程 → kernel_thread(kthreadd) — 创建内核守护线程 → cpu_startup_entry() — 进入 idle loop5.2 kernel_init — 挂载根文件系统并启动 init
kernel_init()的核心工作:
do_basic_setup()— 初始化设备驱动模型、加载内建驱动- 挂载根文件系统(通常是从 ramdisk 挂载)
- 执行
/init——这是用户空间的第一个进程,PID = 1
关键:
kernel_init启动/init后,控制权正式从内核态转移到用户态。此时内核已完成全部初始化,但用户空间的进程、服务、ART 虚拟机都还未创建。
六、阶段四:init 进程 — 用户空间的"创世进程"
6.1 init 入口
源码路径:system/core/init/init.cpp
init 进程的核心职责:
- 挂载基础文件系统:
/proc、/sys、/dev、/dev/pts - 创建
/dev/kmsg并重定向标准输入输出 - 初始化属性服务(property_service)
- 解析
init.rc配置文件 - 按阶段执行
on early-init/on init/on late-init/on boot - 进入事件循环,监听 property 变化、子进程退出等
6.2 init.rc — 系统初始化的"剧本"
源码路径:system/core/rootdir/init.rc
init.rc使用 Android Init Language(AIL)编写,定义了系统启动的完整蓝图:
on early-init— 设置内核参数、启动 ueventd
on init— 创建目录结构、设置文件权限和 SELinux 上下文、挂载文件系统
on late-init— 串行触发:
trigger early-fs— 挂载早期文件系统trigger fs— 挂载主要文件系统trigger post-fs— 文件系统就绪后的初始化trigger post-fs-data— /data 分区可写后的初始化trigger load_system_props_action— 加载系统属性trigger boot— 进入 boot 阶段
on boot— 启动核心守护进程:servicemanager、vold、surfaceflinger、netd、logd、healthd、installd、mediaserver等
6.3 属性服务
属性系统是 Android 进程间共享配置的关键机制:
源码路径:system/core/init/property_service.cpp
- 属性以 key-value 形式存储,key 前缀决定权限(
ro.只读,persist.持久化) - 属性变更可触发 init.rc 中的触发器
- 关键属性示例:
ro.boot.hardware(硬件平台)、sys.boot_completed(启动完成标志)、ro.build.version.sdk(SDK 版本)
七、阶段五:Zygote — Java 世界的孵化器
7.1 Zygote 的设计思想
Zygote 是 Android 中几乎所有 Java 进程的父进程。它先预加载常用类和资源,然后通过 fork 创建新进程。利用 COW(Copy-on-Write)机制,子进程共享预加载的内存页,大幅减少启动开销。
7.2 Zygote 启动
Zygote 在 init.rc 中定义:
源码路径:system/core/rootdir/init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverapp_process入口:
源码路径:frameworks/base/cmds/app_process/app_main.cpp
intmain(intargc,char*constargv[]){AppRuntimeruntime(argv[0],computeArgBlockSize(argc,argv));if(strcmp(arg,"--zygote")==0){runtime.start("com.android.internal.os.ZygoteInit",args,zygote);}}关键设计:
AppRuntime继承自AndroidRuntime,runtime.start()内部启动 ART 虚拟机,然后通过 JNI 回调到 Java 层的ZygoteInit.main()——这是 C++ 到 Java 世界的关键跨越点。
AndroidRuntime.start()启动 ART 虚拟机并调用ZygoteInit.main():
源码路径:frameworks/base/core/jni/AndroidRuntime.cpp
7.3 ZygoteInit.main() — 核心初始化
源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
publicclassZygoteInit{publicstaticvoidmain(String[]argv){// 1. 创建 zygote socket,监听 AMS 的 fork 请求registerZygoteSocket(socketName);// 2. 预加载(最耗时的阶段)preloadClasses();// 从 /system/etc/preloaded-classes 加载数千个类preloadResources();// 系统资源:主题、颜色、字符串preloadOpenGL();// EGL/OpenGL 共享库// 3. fork SystemServer 进程if(argv[1].equals("start-system-server")){startSystemServer(abiList,socketName);}// 4. 进入事件循环,等待 AMS 的 fork 请求runSelectLoop(abiList);}}关键设计:
preloadClasses()是最耗时的单步操作——它需要加载数千个 Java 类。但正是因为 Zygote 在 fork 前完成预加载,每个 App 进程启动时无需重复这个过程,利用 COW 机制共享内存页,启动时间从数秒降至数百毫秒。
八、阶段六:SystemServer — 框架服务的"总管家"
8.1 fork SystemServer
源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Zygote 通过Zygote.forkSystemServer()创建 SystemServer 进程,子进程执行handleSystemServerProcess(),最终调用SystemServer.main()。
8.2 SystemServer.run() — 三阶段启动
源码路径:frameworks/base/services/java/com/android/server/SystemServer.java
publicfinalclassSystemServer{privatevoidrun(){Looper.prepareMainLooper();System.loadLibrary("android_servers");createSystemContext();startBootstrapServices();// 第一阶段:引导服务startCoreServices();// 第二阶段:核心服务startOtherServices();// 第三阶段:其他服务Looper.loop();}}关键设计:三阶段启动确保服务间的依赖关系——
startBootstrapServices创建 AMS/PMS/PKMS 等基础服务,startCoreServices创建依赖它们的服务,startOtherServices创建所有剩余服务。任何阶段的服务创建失败都会导致后续阶段无法启动。
8.3 startBootstrapServices() — 引导服务
最基础的服务,后续服务依赖它们:
| 服务 | 功能 | 源码路径 |
|---|---|---|
| Installer | 与 installd 通信,负责 APK 安装 | frameworks/base/services/core/java/com/android/server/pm/Installer.java |
| ActivityManagerService | 四大组件管理、进程管理 | frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java |
| PowerManagerService | 功耗管理、休眠唤醒状态机 | frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java |
| LightsService | 通知灯、背光灯控制 | frameworks/base/services/core/java/com/android/server/lights/LightsService.java |
| DisplayManagerService | 显示设备管理 | frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java |
| PackageManagerService | 包管理、权限管理 | frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java |
| UserManagerService | 多用户管理 | frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java |
AMS 和 PKMS 此时创建但尚未完全就绪,systemReady()在第三阶段调用。
8.4 startCoreServices() — 核心服务
| 服务 | 功能 | 源码路径 |
|---|---|---|
| BatteryService | 电池状态监测 | frameworks/base/services/core/java/com/android/server/BatteryService.java |
| UsageStatsService | 应用使用统计 | frameworks/base/services/core/java/com/android/server/usage/UsageStatsService.java |
| WebViewUpdateService | WebView 组件更新 | frameworks/base/services/core/java/com/android/server/webkit/WebViewUpdateService.java |
8.5 startOtherServices() — 其他服务
所有剩余服务在此阶段启动,主要包括:
| 服务 | 功能 | 源码路径 |
|---|---|---|
| WindowManagerService | 窗口管理、输入事件分发 | frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java |
| ConnectivityService | 网络连接管理 | frameworks/base/services/core/java/com/android/server/ConnectivityService.java |
| AlarmManagerService | Alarm 定时器管理 | frameworks/base/services/core/java/com/android/server/AlarmManagerService.java |
| NotificationManagerService | 通知管理 | frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java |
| BluetoothService | 蓝牙管理 | frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java |
| InputMethodManagerService | 输入法管理 | frameworks/base/services/core/java/com/android/server/InputMethodManagerService.java |
| AudioService | 音频管理 | frameworks/base/services/core/java/com/android/server/audio/AudioService.java |
8.6 systemReady() 回调链
所有服务创建后,依次调用systemReady():
- AMS.systemReady()— 启动 Launcher、恢复栈顶 Activity、发送
BOOT_COMPLETED广播 - PKMS.systemReady()— 完成待处理的包操作
- WMS.systemReady()— 显示系统 UI
- PMS.systemReady()— 初始化完成,启用自动休眠
九、Launcher 启动 — 用户可见的第一屏
源码路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
AMS 在systemReady()中调用startHomeActivityLocked()启动 Launcher:
booleanstartHomeActivityLocked(intuserId,Stringreason){Intentintent=getHomeIntent();// 构造 Intent.CATEGORY_HOMEActivityInfoaInfo=resolveActivityInfo(intent,...);// 启动 Launcher 的 main ActivitymActivityStarter.startHomeActivityLocked(intent,aInfo,reason);}Launcher 启动后,AMS 发送Intent.ACTION_BOOT_COMPLETED广播——这是 App 开发者可接收的"开机完成"信号。
关键设计:
BOOT_COMPLETED广播在 Launcher 启动后才发送,但此时startOtherServices中的部分服务可能尚未完成systemReady()。对于需要在开机后立即执行的任务,注册BOOT_COMPLETED广播是最可靠的时机,而非依赖 Launcher 的可见性。
十、开机流程完整时序图
时间 → BootROM (硬编码,上电自动执行) │ ▼ BootLoader (LK/U-Boot) │ 初始化 DDR、UART、存储 │ 加载 boot.img → kernel + ramdisk │ ▼ Linux Kernel (start_kernel) │ 架构初始化、内存管理、调度器、中断 │ 挂载 ramdisk → 执行 /init │ ▼ init 进程 (PID 1) │ 解析 init.rc,按阶段执行 │ 启动 servicemanager、vold、surfaceflinger 等守护进程 │ ▼ Zygote (app_process) │ 启动 ART,预加载类/资源/共享库 │ fork SystemServer 进程 │ ▼ SystemServer │ startBootstrapServices → AMS, PMS, PKMS... │ startCoreServices → BatteryService... │ startOtherServices → WMS, Bluetooth, Telephony... │ systemReady() → 启动 Launcher │ ▼ Launcher 启动 → BOOT_COMPLETED 广播 → 用户可操作十一、关键源码文件索引
| 文件 | 路径 | 本文涉及内容 |
|---|---|---|
init.cpp | system/core/init/ | init 进程入口、属性服务 |
init.rc | system/core/rootdir/ | 系统初始化脚本 |
app_main.cpp | frameworks/base/cmds/app_process/ | Zygote 入口 |
ZygoteInit.java | frameworks/base/core/java/com/android/internal/os/ | 预加载类、fork SystemServer |
SystemServer.java | frameworks/base/services/java/com/android/server/ | 三阶段服务启动 |
ActivityManagerService.java | frameworks/base/services/core/java/com/android/server/am/ | Launcher 启动、BOOT_COMPLETED |
十二、小结
开机流程本质上是一个"全量初始化"的过程。从 BootROM 的第一条指令到 Launcher 显示桌面,中间经历了多层抽象、数十个进程的创建、上百个系统服务的初始化。
| 阶段 | 核心工作 | 耗时占比 |
|---|---|---|
| BootROM → BootLoader | 硬件初始化、加载内核 | ~5% |
| Kernel 启动 | 架构初始化、驱动加载 | ~10% |
| init 进程 | 解析 init.rc、启动守护进程 | ~10% |
| Zygote | 预加载类/资源(最耗时) | ~30% |
| SystemServer | 启动上百个系统服务 | ~40% |
| Launcher | 启动桌面 | ~5% |
这一过程之所以漫长,核心原因在于状态必须从零开始重建——每一个数据结构、每一个内存映射、每一个服务状态都必须从配置文件或持久化存储中重新加载并初始化。
理解这一点之后,再看休眠唤醒就会发现:休眠唤醒的"快"本质上是因为跳过了这整个重建过程——内核保持初始化完成的状态、进程只被冻结而非杀死、ART 虚拟机堆内存完整保留、系统服务无需重新启动。
下一篇:Android 7系统休眠唤醒(三)关机/重启全链路—ShutdownThread到kernel_power_off — 如果开机是"从零开始重建世界",关机就是"有秩序地拆除这个世界"。关机流程与开机形成镜像,完成"全量销毁"的闭环。
