3. Android分区与启动流程
Android 设备的启动并不是“按下电源键就进入系统”这么简单,而是一条由多个分区、多个引导阶段逐级接力完成的信任链。理解这条链,是后续做 OTA 升级、A/B 回滚、故障恢复的前提。因为一旦升级失败,能否回滚、回滚到哪个分区、由谁决定启动哪一份镜像,答案都藏在这条启动链里。
一、核心原理:分区是启动链的“接力棒”
Android 设备通常把 eMMC/UFS 划分为若干逻辑分区,每个分区承担明确职责。启动时,芯片上电后先执行固化在 ROM 中的 BootROM 代码,它只做最小初始化,然后加载 Bootloader。Bootloader 负责校验并加载 boot 分区中的内核与 ramdisk,内核启动后挂载 system、vendor 等分区,最终交给 init 启动 Android 用户空间。
关键分区的作用如下:
- Bootloader(如 abl/xbl):启动链的第一环,负责硬件初始化、选择启动槽位(A/B)、校验 boot/dtbo/vbmeta,并决定进入系统还是 recovery/fastboot。
- boot:包含 Linux 内核(kernel)和通用 ramdisk,是系统启动的核心镜像。
- system:Android 框架与系统应用,包含 /system 下的核心库、服务与 API。
- vendor:芯片与硬件厂商提供的 HAL、驱动与专有库,与 system 通过 VINTF 接口协作。
- dtbo:设备树叠加层(Device Tree Overlay),描述具体硬件配置,内核据此识别屏幕、传感器等外设。
- vbmeta:Android Verified Boot 的元数据,保存各分区哈希与签名,用于校验启动链完整性。
这些分区不是孤立的,而是通过 vbmeta 的哈希链形成“信任根 → Bootloader → boot/dtbo → system/vendor”的逐级校验关系。任何一环被篡改或损坏,启动都会在对应阶段失败。
二、方法流程:启动链的关键阶段
把启动链拆成阶段,便于定位故障。典型流程如下:
- 上电与 BootROM:芯片从固定地址加载 Bootloader,验证其签名。
- Bootloader 阶段:初始化 DDR、存储与显示,读取 misc 分区中的启动命令与 A/B 槽位信息,决定进入 normal、recovery 还是 fastboot。
- AVB 校验:Bootloader 读取 vbmeta,校验 boot、dtbo、system、vendor 的哈希与签名。若校验失败,根据 vbmeta 中的 flag 决定是警告、降级还是直接拒绝启动。
- 内核启动:加载 boot 中的 kernel 与 ramdisk,应用 dtbo 描述硬件,挂载 system/vendor。
- init 与用户空间:init 解析 rc 文件,启动 Zygote、SystemServer,最终进入 Launcher。
关键点:vbmeta 是启动链的“总校验单”。它不直接包含镜像,而是保存各分区的哈希与签名描述符。升级时若只更新 boot 而忘记同步 vbmeta,Bootloader 会因哈希不匹配而拒绝启动,表现为“卡在开机 logo 或直接进 fastboot”。
三、案例/场景:一次 OTA 升级后的启动失败
某设备通过 A/B 无缝升级,升级包写入了 slot B 的 boot_b、system_b、vendor_b 和 vbmeta_b。重启后设备卡在开机动画,随后自动回滚到 slot A。排查日志发现:
avb_slot_verify: ERROR: vbmeta_b: hash mismatch for boot_b
avb_slot_verify: ERROR: boot_b verification failed
bootloader: slot B marked unbootable, falling back to slot A
原因是升级脚本只刷写了 boot_b,却未同步更新 vbmeta_b 中的 boot 哈希。Bootloader 校验失败后,将 slot B 标记为不可启动,并依据 A/B 回滚机制切回 slot A。这个案例说明:升级必须保证 boot、dtbo、vbmeta 等分区版本一致,否则信任链断裂。
四、误区与复盘
- 误区一:只关注 system,忽略 vbmeta。很多启动失败并非系统镜像损坏,而是 vbmeta 与 boot/dtbo 不匹配。
- 误区二:认为 vendor 与 system 可以随意混搭。vendor 与 system 通过 VINTF 约束版本,跨版本混用可能导致 HAL 无法加载。
- 误区三:忽略 dtbo。dtbo 错误会导致内核无法识别屏幕、触摸或存储,表现为黑屏或无法挂载分区。
- 复盘建议:升级前记录各分区版本与哈希;升级后先校验 vbmeta;保留可回滚的 A/B 槽位;在 fastboot 下用
fastboot getvar current-slot确认活动槽。
| 分区 | 主要作用 | 启动阶段 | 升级/回滚关注点 |
|---|---|---|---|
| Bootloader | 硬件初始化、选槽、校验 | 最早 | 一般随整包升级,回滚风险高 |
| boot | 内核与 ramdisk | Bootloader 之后 | 需与 vbmeta、dtbo 同步 |
| dtbo | 设备树叠加,硬件描述 | 内核启动时 | 与硬件版本绑定,不可错配 |
| vbmeta | AVB 哈希与签名 | 校验阶段 | 必须覆盖所有被校验分区 |
| system | 框架与系统应用 | 内核挂载后 | 与 vendor 版本匹配 |
| vendor | HAL、驱动、专有库 | 内核挂载后 | 受 VINTF 约束 |
记忆口诀:BootROM 找 Bootloader,Bootloader 看 vbmeta,vbmeta 校验 boot/dtbo,内核挂 system/vendor,init 拉起 Android。掌握这条链,升级回滚时就能快速判断“卡在哪一环、该回滚哪个分区”。