4. Android启动流程详解

Android设备的启动并不是“按下电源键就进入桌面”这么简单,而是一条由硬件信任根逐级向上传递控制权的可信链。每一级都会初始化必要的硬件、校验下一级镜像的完整性,然后把执行权交给下一级。理解这条链路,是理解Android安全启动、AVB校验、dm-verity以及后续可信链集成的基础。

核心思想:启动过程是一条“逐级加载、逐级校验、逐级移交”的链。前一级是后一级的信任源,任何一级被篡改,后续校验都会失败或进入异常状态。

4.1 启动阶段总览

典型Android设备从上电到系统可用的启动阶段可以概括为:BootROM → SPL/Preloader → U-Boot/LK → Kernel → init → Zygote → SystemServer → Launcher。不同芯片平台名称略有差异,例如高通平台常见PBL、XBL、ABL,联发科平台常见BootROM、Preloader、LK,但整体分层思想一致。

Android 启动阶段与可信链传递 BootROM SPL / Preloader U-Boot / LK Kernel init Zygote SystemServer 固化在芯片内,加载并校验SPL,是硬件信任根 校验对象:SPL/Preloader 签名与哈希 初始化DDR、时钟、存储,加载U-Boot/LK 校验对象:bootloader 镜像 加载boot.img,校验AVB元数据,传递cmdline 校验对象:boot、dtbo、vbmeta 解压内核、初始化驱动、挂载根文件系统 校验对象:system/vendor 分区(dm-verity) 解析init.rc,启动属性服务、ueventd、servicemanager 校验对象:SELinux策略、分区挂载 孵化应用进程,预加载类和资源,创建虚拟机 校验对象:Zygote 自身完整性 启动系统服务,注册Binder,拉起Launcher 校验对象:系统服务权限与SELinux域

4.2 各阶段核心原理与职责

BootROM是固化在SoC内部的只读代码,不可修改,因此成为整条信任链的根。它上电后首先初始化最基础的时钟和SRAM,然后从启动介质(eMMC/UFS/SPI Flash)读取SPL或Preloader。在安全启动开启时,BootROM会使用烧录在OTP或efuse中的公钥哈希校验SPL签名,校验失败则停止启动或进入下载模式。

SPL/Preloader运行在片内SRAM中,主要任务是初始化DDR、时钟、电源和存储控制器,为加载更大的Bootloader准备运行环境。它同样需要被校验,并且会校验下一级U-Boot/LK。很多平台在这一级还会检查防回滚版本号,防止攻击者刷入旧版本有漏洞的镜像。

U-Boot/LK是功能更完整的引导程序,负责显示开机logo、读取分区表、加载boot.img和dtbo.img,并根据AVB元数据校验boot分区。校验通过后,它把内核、ramdisk、设备树和启动参数(cmdline)传递给Kernel。如果启用了AVB,vbmeta分区中的哈希树和描述符会在这里被验证。

Kernel启动后完成内存管理、进程调度、驱动初始化和文件系统挂载。对于Android来说,Kernel还会启用dm-verity对system、vendor等只读分区做块级完整性校验,并加载SELinux策略。Kernel启动的最后一步是执行/init,从此进入用户空间。

init是用户空间的第一个进程,PID为1。它解析init.rc及init.<hardware>.rc,启动属性服务、ueventd、servicemanager、vold等关键守护进程,并按照SELinux策略为每个进程设置安全上下文。init还负责挂载分区、设置权限、触发early-init、init、late-init等阶段。

Zygote由init根据rc配置启动,它预加载Android框架类和资源,创建Dalvik/ART虚拟机,并通过socket等待AMS请求。Zygote是应用进程的模板,所有应用进程都由它fork而来,因此Zygote的完整性和安全上下文直接影响整个应用运行时。

SystemServer由Zygote fork出的第一个进程,它启动并注册大量系统服务,例如ActivityManagerService、PackageManagerService、WindowManagerService、Binder机制等。SystemServer完成服务启动后,会通知AMS启动Launcher,最终呈现用户界面。

4.3 关键阶段与校验对象对照

启动阶段 主要职责 校验对象 失败后果
BootROM 初始化基础硬件,加载SPL SPL/Preloader签名 停止启动或进入下载模式
SPL/Preloader 初始化DDR,加载U-Boot Bootloader镜像 无法进入引导程序
U-Boot/LK 加载boot.img,传递参数 boot、dtbo、vbmeta AVB校验失败,红屏/黄屏
Kernel 驱动初始化,挂载根文件系统 system/vendor(dm-verity) 分区校验失败,无法挂载
init 启动守护进程,设置SELinux init.rc、SELinux策略 关键服务无法启动
Zygote 预加载框架,孵化应用进程 Zygote自身完整性 应用进程无法创建
SystemServer 启动系统服务,拉起Launcher 系统服务权限与域 系统服务异常,界面无法显示

4.4 典型场景与排障思路

在实际项目中,启动失败往往表现为黑屏、卡在开机logo、反复重启或进入fastboot。排查时可以按照启动阶段逐级定位:

  • 如果设备完全无反应,优先检查BootROM是否进入下载模式,确认SPL是否被正确烧录。
  • 如果卡在开机logo,通常问题在U-Boot或Kernel阶段,可查看串口日志中AVB校验结果和内核启动参数。
  • 如果反复重启且日志显示dm-verity错误,说明system/vendor分区被修改或哈希树不匹配。
  • 如果init阶段报SELinux denied,需要检查策略文件和文件上下文是否正确。
  • 如果Zygote或SystemServer崩溃,通常与框架层修改、odex不匹配或系统服务权限有关。
调试建议:保留串口日志和last_kmsg,在U-Boot阶段打开AVB详细日志,在init阶段打开ro.debuggable和SELinux permissive进行对比验证,但量产版本必须恢复 enforcing。

4.5 常见误区与复盘

第一个误区是把“解锁Bootloader”等同于“关闭安全启动”。实际上解锁通常只是允许刷入非官方镜像,而AVB和dm-verity是否启用取决于vbmeta和分区标志。第二个误区是认为只要BootROM校验通过就万事大吉,实际上后续每一级都需要独立校验,任何一级缺失都会形成短板。第三个误区是忽略版本防回滚,攻击者可能利用旧版本漏洞降级启动。

复盘时可以用一条命令快速查看当前设备的启动状态:

adb shell getprop ro.boot.verifiedbootstate
adb shell getprop ro.boot.flash.locked
adb shell getprop ro.boot.veritymode
adb shell dmesg | grep -i avb
adb shell dmesg | grep -i dm-verity

其中verifiedbootstate为green表示完整可信启动,yellow表示解锁但校验通过,orange表示校验未通过。结合flash.locked和veritymode,可以快速判断设备当前处于哪种信任状态,为后续可信链集成和问题定位提供依据。