2. Qualcomm车载平台软件架构与FOTA落点
在Qualcomm车载平台(SA8155、SA8295等)上做FOTA,第一步不是写升级脚本,而是搞清楚“软件到底被放在哪里、由谁加载、哪些区域可以被安全改写”。如果对启动链和分区布局没有清晰认识,很容易出现“升级包写进去了但设备起不来”“A/B切换后版本回退”“刷写越界破坏校准数据”等问题。本节围绕启动链、分区布局、A/B槽位和FOTA可操作对象四个层面展开,帮助建立可落地的平台认知。
一、从上电到Android:启动链的层级关系
SA8155/SA8295属于Qualcomm Snapdragon Ride/座舱平台,其启动过程是典型的多级引导结构。上电后,最先运行的是芯片内部ROM中的PBL(Primary Boot Loader),它从启动介质(通常是UFS)的固定位置读取XBL(eXtensible Boot Loader)。XBL完成DDR初始化、时钟配置后,继续加载后续镜像。整体链路可以概括为:
PBL → XBL(含XBL_SEC、XBL_LOADER)→ ABL(Application Boot Loader)→ HLOS(Linux Kernel / Android)
其中ABL是关键分水岭:它负责读取分区表、决定从A槽还是B槽启动、校验镜像签名,并把控制权交给Linux内核。对于智驾平台,还会涉及QNX或安全OS的并行加载。理解这条链的意义在于:FOTA能改写的对象,必须落在启动链能够识别并校验的范围内。例如XBL本身通常不参与常规FOTA,而ABL、boot、system、vendor等分区才是升级的主要目标。
二、分区布局:UFS上的软件地图
SA8155/SA8295使用UFS作为主存储,分区表通常由GPT(GUID Partition Table)描述。一个典型的座舱平台分区布局包含以下几类:
- 引导类分区:xbl_a/xbl_b、abl_a/abl_b、boot_a/boot_b。其中xbl通常不参与常规FOTA,abl和boot是升级常客。
- 系统类分区:system_a/system_b、vendor_a/vendor_b、product_a/product_b。Android的框架层、HAL层、应用层分别落在这些分区。
- 通信类分区:modem_a/modem_b、bluetooth、adsp等。基带和DSP固件升级需要与模组厂商协同。
- 数据类分区:persist、userdata、misc。persist存放传感器校准、射频校准等关键数据,绝不能被FOTA覆盖;misc用于记录启动槽位和升级状态。
在实操中,可以通过ls -l /dev/block/by-name/查看分区映射,或用sgdisk -p /dev/ufs0读取GPT表。判断一个分区是否可FOTA,核心看三点:是否属于A/B双槽、是否有签名校验、是否被ABL在启动时读取。
三、A/B槽位机制:无缝升级的基础
A/B(Seamless Update)机制的核心思想是:设备始终有一个“当前可启动槽位”,升级时把新镜像写入另一个“备用槽位”,写入完成后通过misc分区标记切换,下次重启由ABL读取标记并从新槽位启动。如果新槽位启动失败,bootloader可以自动回退到旧槽位。
以SA8155为例,A/B槽位的元数据通常记录在misc分区中,包含:当前活动槽位(active slot)、成功标记(successful boot)、重试计数(retry count)。升级流程可以简化为:
# 示例:查看当前槽位(Android侧)
getprop ro.boot.slot_suffix
# 输出 _a 或 _b
# 示例:写入新镜像到备用槽位
dd if=boot.img of=/dev/block/by-name/boot_b
# 标记备用槽位为可启动
bootctl set-active-boot-slot 1
需要特别注意的是,A/B槽位并不是所有分区都成对存在。persist、userdata、misc通常只有单份,升级时必须跳过。此外,ABL在切换槽位前会校验新槽位镜像的签名,如果签名不匹配,切换会被拒绝,设备继续从旧槽位启动。
四、FOTA可操作对象的边界
综合启动链和分区布局,可以把FOTA可操作对象分为三个层级:
| 层级 | 典型分区 | 升级方式 | 风险等级 |
|---|---|---|---|
| 应用/框架层 | system、vendor、product | 块差分或文件级 | 低,可回退 |
| 内核/引导层 | boot、abl | 整镜像写入备用槽 | 中,需签名校验 |
| 固件/校准层 | modem、adsp、persist | 专用协议或只读保护 | 高,persist禁止覆盖 |
在实际项目中,建议先通过fastboot getvar all或平台文档确认分区清单,再结合OTA包中的payload.bin或update.zip内容,明确每个分区的写入目标和校验方式。只有把“启动链—分区—槽位—可操作对象”这条链路对齐,后续的升级包制作、签名、回滚策略才有可靠的基础。