深度解析SPL阶段A/B分区启动:spl_ab.c代码全拆解

电子说

1.4w人已加入

描述

在嵌入式系统(尤其是Rockchip平台Android设备)中,A/BSeamless Update)无缝更新是保障系统更新不丢数据、更新失败可回滚的核心机制。而SPLSecondary Program Loader,二级程序加载器)作为系统启动的早期阶段,负责初始化硬件、选择启动分区,spl_ab.c正是SPL层处理A/B分区启动的核心代码。本文将从函数解析、核心流程、开发意义三个维度,彻底拆解这段代码。

 

 

一、A/B分区与SPL的核心作用

 

 

A/B分区将系统分为两个独立的槽位(Slot A/Slot B),更新时先更新非当前启动的槽位,更新完成后切换槽位启动;若启动失败,自动回退到原槽位。

 

 

SPLBootLoader的早期阶段,执行优先级最高,spl_ab.c的核心目标是:读取A/B元数据、判断槽位可启动性、选择最优启动槽位、处理启动失败后的尝试次数递减与系统重置

 

 

二、核心函数分类解析

 

 

代码中的函数可分为7大类,覆盖基础工具元数据处理槽位管理启动流程全链路,以下是关键函数的作用拆解:

 

 

1. 基础工具函数:解决通用问题

 

 

函数名

 

 

核心作用

 

 

safe_memcmp

 

 

安全的内存比较,无数据依赖分支(避免侧信道攻击),返回两内存区域是否不相等(0=相等,非0=不等)

 

 

htobe32

 

 

主机字节序大端字节序转换(A/B元数据存储为大端)

 

 

be32toh

 

 

大端字节序主机字节序转换(读取元数据后适配本地CPU

 

 

2. A/B元数据处理:校验/更新/初始化

 

 

A/B元数据(AvbABData)存储在misc分区,包含槽位优先级、剩余尝试次数、启动成功标记等关键信息,这组函数是元数据操作的核心:

 

 

函数名

 

 

核心作用

 

 

spl_ab_data_verify_and_byteswap

 

 

校验元数据合法性:
1. 
检查魔术字(
AVB_AB_MAGIC)是否正确;
2. 
转换CRC32为主机序;
3. 
检查版本兼容性(主版本不超过支持值);
4. 
校验CRC32(排除元数据损坏);
校验通过则拷贝并转换字节序到目标结构体

 

 

spl_ab_data_update_crc_and_byteswap

 

 

更新元数据的CRC32:先拷贝数据,再计算CRC32并转换为大端序(用于写入存储)

 

 

spl_ab_data_init

 

 

初始化默认元数据:
魔术字、版本号初始化;
- Slot A
优先级最高,Slot B次之;
两槽位剩余尝试次数设为最大值,启动成功标记置0

 

 

3. 元数据读写:对接存储层

 

 

函数名

 

 

核心作用

 

 

spl_read_ab_metadata

 

 

misc分区指定偏移读取元数据到内存(单次读512字节,适配块设备读写粒度)

 

 

spl_write_ab_metadata

 

 

将内存中的元数据写入misc分区指定偏移

 

 

spl_ab_data_read

 

 

封装读取+校验:读取失败/校验失败时,初始化新元数据并写入misc分区

 

 

spl_ab_data_write

 

 

封装更新CRC+写入:先更新CRC32,再写入存储

 

 

4. 槽位选择:核心决策逻辑

 

 

函数名

 

 

核心作用

 

 

spl_slot_is_bootable

 

 

判断槽位是否可启动:优先级>0 且(已成功启动 或 剩余尝试次数>0

 

 

spl_get_lastboot

 

 

获取上次启动的槽位索引(0=A1=B

 

 

spl_get_current_slot

 

 

选择当前要启动的槽位(核心函数):
1. 
优先使用缓存的
last_slot_index(避免重复计算);
2. 
读取并校验元数据;
3. 
按规则选槽位:
 
  
两槽位都可启动:选优先级高的(同优先级选A);
 
  
仅一个可启动:选该槽位;
 
  
都不可启动:回退到上次启动的槽位;
4. 
缓存结果并返回槽位后缀(_a/_b

 

 

5. 分区名处理:适配槽位后缀

 

 

函数名

 

 

核心作用

 

 

spl_ab_append_part_slot

 

 

给分区名追加槽位后缀(如bootboot_a);misc分区例外(无后缀);获取槽位失败时直接返回原分区名

 

 

6. 槽位状态管理:处理启动失败

 

 

函数名

 

 

核心作用

 

 

spl_slot_set_unbootable

 

 

标记槽位为不可启动:优先级、剩余尝试次数、启动成功标记全置0

 

 

spl_slot_normalize

 

 

规范化槽位状态(处理非法场景):
优先级>0但尝试次数=0且未成功置为不可启动;
优先级>0但尝试次数>0且已成功置为不可启动;
优先级≤0→直接置为不可启动

 

 

spl_ab_decrease_tries

 

 

启动失败时减少当前槽位尝试次数:
1. 
获取当前槽位;
2. 
读取并规范化两槽位状态;
3. 
若当前槽位未成功且有剩余尝试次数,减1
4. 
元数据变化则写入
misc分区

 

 

spl_ab_decrease_reset

 

 

启动失败后重置系统:
1. 
检查是否有可启动槽位;
2. 
调用
spl_ab_decrease_tries减尝试次数;
3. 
仍有可启动槽位则执行系统重置,无则返回错误

 

 

7. 启动参数传递:对接内核

 

 

函数名

 

 

核心作用

 

 

spl_ab_bootargs_append_slot

 

 

给设备树(FDT)的启动参数(bootargs)追加槽位后缀(如android.slot_suffix=_a),让内核感知当前启动槽位

 

 

三、SPL阶段A/B启动核心流程图

 

 

Rockchip

四、开发者关注这段代码的核心意义

 

 

对于嵌入式开发者(尤其是Rockchip/Android BootLoader开发者),理解spl_ab.c是保障A/B启动稳定的关键,核心价值体现在5个方面:

 

 

1. 快速定位启动故障

 

 

当设备出现“A/B启动失败、卡在SPL阶段、槽位切换异常时,可通过代码日志(如“CRC32 does not match”“No bootable slots found”)定位根因:

 

 

元数据CRC不匹配:misc分区损坏,spl_ab_data_read会自动初始化元数据;

 

 

无可用槽位:两槽位尝试次数耗尽,需手动重置元数据;

 

 

槽位被标记为不可启动:检查spl_slot_normalize是否触发了非法状态处理。

 

 

2. 定制A/B更新策略

 

 

默认逻辑可根据产品需求调整:

 

 

调整默认优先级/尝试次数:修改spl_ab_data_init中的AVB_AB_MAX_PRIORITY/AVB_AB_MAX_TRIES_REMAINING

 

 

自定义槽位选择规则:修改spl_get_current_slot(如优先级相同时选上次启动的槽位,而非默认的Slot A);

 

 

调整启动失败后的行为:修改spl_ab_decrease_reset(如增加重试次数阈值,或取消自动重置)。

 

 

3. 适配不同硬件平台

 

 

不同存储设备(eMMC/NAND/SD卡)的块设备读写(blk_dread/blk_dwrite)逻辑有差异,需确保spl_read/write_ab_metadata适配硬件;不同CPU架构的字节序可能不同,需验证htobe32/be32toh的正确性。

 

 

4. 提升系统稳定性

 

 

safe_memcmp避免侧信道攻击,提升元数据比较的安全性;

 

 

spl_save_metadata_if_changed仅在元数据变化时写入存储,减少misc分区的写操作,延长存储寿命;

 

 

spl_slot_normalize处理非法状态,避免因元数据异常导致的启动逻辑崩溃。

 

 

5. 适配Android无缝更新标准

 

 

Android A/B无缝更新的核心是槽位管理,这段代码是SPL层对接Android A/B规范的关键,确保更新后能正确切换槽位启动,失败时自动回滚,符合GoogleA/B更新标准。

 

 

五、总结

 

 

spl_ab.cSPL阶段A/B分区启动的大脑,从元数据读写、槽位决策到启动失败处理,覆盖了A/B启动的全核心流程。对于嵌入式开发者而言,理解这段代码不仅能快速定位启动故障,还能根据产品需求定制更新策略,保障设备在无缝更新场景下的稳定性与兼容性。

 

 

无论是调试A/B启动问题,还是适配新硬件平台,spl_ab.c都是必须深入掌握的核心模块——它是连接硬件初始化与系统启动的关键桥梁,也是保障Android无缝更新落地的基础。


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分