2. Snapdragon启动链与分区布局

理解 Snapdragon 平台上的 OTA 升级,不能只盯着“下载差分包、重启、安装”这几个动作,而必须先看清设备从上电到进入 Android 系统之间,究竟有哪些固件阶段在接力,以及这些阶段分别存放在哪些分区里。OTA 升级本质上是在“改写启动链所依赖的存储内容”,因此启动链的每一级、GPT 分区表的每一项、A/B 槽位的每一个后缀,都会直接影响升级能否成功、失败后能否回滚。

一、从上电到 Android:四级启动接力

Snapdragon 的启动过程可以概括为一条逐级验证、逐级加载的信任链:

  • Boot ROM(PBL,Primary Boot Loader):固化在 SoC 内部 ROM 中,上电后最先执行。它读取启动引脚/熔丝配置,确定从 UFS、eMMC 还是 USB 启动,然后从存储的固定位置加载下一级引导程序,并做最基础的签名校验。PBL 不可修改,是整条信任链的根。
  • SBL(Secondary Boot Loader):由 PBL 从存储中加载,负责初始化 DDR、时钟等关键硬件,随后加载 XBL。SBL 通常与 XBL 一起被打包进引导分区,是硬件初始化的关键一环。
  • XBL(eXtensible Boot Loader):基于 UEFI 框架的引导程序,负责更完整的平台初始化、加载 UEFI 驱动、读取 GPT 分区表,并最终加载 ABL。XBL 是启动链中承上启下的核心。
  • ABL(Application Boot Loader):即 Android Bootloader(常见实现为 LK/aboot 或 UEFI 应用),负责选择启动槽位(A 或 B)、校验 boot 镜像、设置 cmdline、进入 fastboot 或直接引导内核。

这四级构成一条“信任链”:PBL 验 SBL,SBL 加载 XBL,XBL 加载 ABL,ABL 再引导 boot。OTA 升级时,如果改动了其中任何一级却没有正确签名或写错分区,设备就可能卡在开机 Logo、进入 EDL(Emergency Download)模式,或反复重启。

Snapdragon 启动链与分区映射 Boot ROM PBL · SoC 内固化 SBL DDR/时钟初始化 XBL UEFI · 读 GPT ABL 选槽 · 引导内核 GPT 分区表(存储布局) xbl_a / xbl_b XBL 镜像 sbl1_a / sbl1_b SBL 镜像 abl_a / abl_b ABL 镜像 boot_a / boot_b 内核 + ramdisk system_a / _b 系统分区 misc 槽位元数据 A/B 槽位与 OTA 升级路径 Slot A(当前运行) system_a · boot_a · xbl_a Slot B(OTA 写入) system_b · boot_b · xbl_b OTA 写入非活动槽 重启后切换活动槽 → 验证 → 成功则保留

二、GPT 分区表:启动链的“地址簿”

XBL 在初始化存储后,会读取 GPT(GUID Partition Table)分区表。GPT 记录了每个分区的名称、起始 LBA、大小和 GUID。启动链的每一级都依赖 GPT 找到自己的下一级:PBL 从固定偏移加载 SBL,XBL 通过 GPT 定位 xbl、abl、boot 等分区,ABL 再通过 GPT 找到 boot 和 system。

在 OTA 语境下,GPT 的重要性体现在两点:第一,分区名必须与升级包中的镜像名严格对应,例如升级包里的 xbl.img 必须写入 xbl_a 或 xbl_b;第二,分区大小必须匹配,如果新固件体积超过原分区容量,写入会失败或截断,导致启动链断裂。因此 OTA 包在制作时会校验分区表版本,必要时先升级 GPT 本身。

三、A/B 分区与 OTA 的关联

A/B(Seamless Update)机制的核心思想是:设备始终有一个“活动槽”在运行,OTA 把新固件写入“非活动槽”,重启后切换到新槽。这样升级过程中设备仍可正常使用,失败也能回滚。

与启动链结合看,A/B 槽位覆盖了从底层到上层的多个分区:

  • sbl1_a / sbl1_b、xbl_a / xbl_b、abl_a / abl_b:引导链各级的 A/B 副本;
  • boot_a / boot_b:内核与 ramdisk;
  • system_a / system_b、vendor_a / vendor_b:Android 系统与厂商分区;
  • misc:存放当前活动槽、启动成功标记等元数据,ABL 读取它决定引导哪个槽。

OTA 升级时,升级客户端(如 Android 的 update_engine)会:

  1. 读取 misc 确定当前活动槽(假设为 A);
  2. 将差分包或全量包写入 B 槽对应的所有分区,包括 xbl_b、abl_b、boot_b、system_b;
  3. 在 misc 中标记“下次从 B 启动”,并设置启动尝试次数;
  4. 重启,ABL 读取 misc,引导 B 槽;
  5. 若 B 槽启动成功,系统将 B 标记为活动槽;若连续失败,ABL 回退到 A 槽。
关键点:引导链分区(sbl1、xbl、abl)的 A/B 副本必须与 boot、system 的槽位保持一致。如果 OTA 只更新了 system_b 却漏写 xbl_b,重启后 B 槽可能因引导链版本不匹配而无法启动。

四、实际升级中的观察与判断

在工程实践中,可以通过以下方式确认启动链与分区状态:

  • 进入 fastboot 后执行 fastboot getvar current-slot,查看当前活动槽;
  • 执行 fastboot getvar slot-count,确认设备是否支持 A/B;
  • 通过 fastboot flash xbl_b xbl.img 手动写入引导分区,验证分区名与镜像匹配;
  • 查看内核日志中 androidboot.slot_suffix 参数,确认系统实际从哪个槽启动。

如果设备在 OTA 后卡在 Boot ROM 之后的阶段(例如黑屏无反应或进入 EDL),通常说明 SBL 或 XBL 写入异常;如果卡在 ABL 之后、内核之前,则更可能是 boot 分区或槽位元数据问题。定位时先确认 GPT 分区表是否完整,再核对 A/B 槽位是否一致,最后检查镜像签名与版本。

注意:Boot ROM 不可升级,也不参与 OTA。任何声称“升级 Boot ROM”的操作都是错误的。OTA 能触及的最底层是 SBL/XBL 所在分区,且必须经过签名校验。

把启动链、GPT 分区表和 A/B 槽位放在一张图里理解,就能看清 OTA 升级的真正边界:它不是在“替换系统文件”,而是在“安全地改写一条逐级验证的启动路径”。只有每一级分区都写对、槽位标记正确、回滚机制有效,升级才算真正完成。