0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_44130326 来源:Linux1024 作者:Linux1024 2026-01-20 07:07 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式系统(尤其是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启动核心流程图

wKgZPGluucuACMd5AAEAMsHxd54329.png

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

对于嵌入式开发者(尤其是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无缝更新落地的基础。


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

    关注

    12

    文章

    4021

    浏览量

    133744
  • 嵌入式系统
    +关注

    关注

    41

    文章

    3739

    浏览量

    133518
  • 代码
    +关注

    关注

    30

    文章

    4965

    浏览量

    73758
  • spl
    spl
    +关注

    关注

    0

    文章

    22

    浏览量

    16732
  • Rockchip
    +关注

    关注

    0

    文章

    90

    浏览量

    19546
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Microchip 93XX66A/B/C系列4Kbit低电压串行EEPROM深度解析

    Microchip 93XX66A/B/C系列4Kbit低电压串行EEPROM深度解析 在电子设计领域,串行EEPROM是不可或缺的存储元件
    的头像 发表于 02-10 15:35 84次阅读

    PCA9545A/45B/45C:4通道I2C总线开关的深度解析

    PCA9545A/45B/45C:4通道I2C总线开关的深度解析 在电子工程师的日常设计工作中,
    的头像 发表于 02-10 11:50 222次阅读

    U-Boot SPL核心文件spl.c深度解析:从启动流程到调试优化

    解析 U-Boot 中 spl.c 文件的功能与作用,探讨其在系统调试和优化中的价值,并通过流程图和脑图帮助开发者快速掌握核心要点。
    的头像 发表于 02-05 14:08 77次阅读
    U-Boot <b class='flag-5'>SPL</b>核心文件<b class='flag-5'>spl.c</b><b class='flag-5'>深度</b><b class='flag-5'>解析</b>:从<b class='flag-5'>启动</b>流程到调试优化

    深入解析U-Boot TPL代码:嵌入式启动的“第一棒”背后的秘密

    在嵌入式系统启动过程中,从按下电源键到操作系统开始运行,中间藏着一系列精密的初始化步骤。今天我们就来拆解 Rockchip 平台 U-Boot 中的 TPL(Tiny Program Loader)阶段核心
    的头像 发表于 02-05 14:07 915次阅读
    深入<b class='flag-5'>解析</b>U-Boot TPL<b class='flag-5'>代码</b>:嵌入式<b class='flag-5'>启动</b>的“第一棒”背后的秘密

    全新VisionFive 2无法启动怎么解决?

    大家好。我刚刚从淘宝购买了一台 VisionFive 2(以下简称 VF2)。当我收到 VF2 时,盒子是完全密封的,没有任何东西被篡改的迹象。但是,当我尝试从 SD 卡启动最新的 debian
    发表于 02-04 07:41

    深入解析rk平台Android Bootloader核心代码:从启动流程到AVB验证

    下android_bootloader.c的核心代码,带你读懂Android设备从Bootloader到内核的完整启动逻辑,以及开发者关注这些代码的核心价值。 一、
    的头像 发表于 01-22 07:06 127次阅读
    深入<b class='flag-5'>解析</b>rk平台Android Bootloader核心<b class='flag-5'>代码</b>:从<b class='flag-5'>启动</b>流程到AVB验证

    德州仪器LM5100A/B/C和LM5101A/B/C系列高压栅极驱动器的深度解析

    德州仪器LM5100A/B/C和LM5101A/B/C系列高压栅极驱动器的
    的头像 发表于 01-11 18:05 1032次阅读

    Texas Instruments LM5100A/B/C和LM5101A/B/C高压栅极驱动器深度解析

    Texas Instruments LM5100A/B/C和LM5101A/B/C高压栅极驱动器
    的头像 发表于 01-11 17:45 1036次阅读

    深度剖析LM5100A/B/C与LM5101A/B/C高压栅极驱动器

    深度剖析LM5100A/B/C与LM5101A/B/C
    的头像 发表于 01-11 17:45 1033次阅读

    d1哪吒开发板的启动流程分析

    的介质中读取SPL,然后放到SRAM中执行,同时也通过FEL运行环境。 3.启动SPL 当BROM启动完成后,接下来要去存储介质中寻找SPL
    发表于 10-29 06:44

    国产!志T113-i 双核Cortex-A7@1.2GHz 工业开发板—eMMC配置核心板使用说明(二)

    本文为创龙科技eMMC 配置核心板官方使用指南,聚焦 Linux 系统在该核心板上的应用。主要内容包括启动卡与 “量产卡” 制作、两种 eMMC 固化方式、分区与 OTA 升级说明、量及局部镜像编译、eMMC 读写性能测试,以
    的头像 发表于 09-10 10:55 555次阅读
    国产!<b class='flag-5'>全</b>志T113-i 双核Cortex-<b class='flag-5'>A</b>7@1.2GHz 工业开发板—eMMC配置核心板使用说明(二)

    fn_u-boot-spl.bin和u-boot-spl.bin区别是什么?请问如何从u-boot-spl.bin生成fn_u-boot-spl.bin?

    fn_u-boot-spl.bin = bootrom头 + u-boot-spl.bin ;生成过程见后面代码片段; bootrom头(格式详见) + u-boot-spl.bin(
    发表于 07-11 07:58

    求助,关于K230启动流程疑问求解

    打印,正常在启动的时候是uboot-spl 启动opensbi,opensbi 启动uboot proper, 然后再启动linux内核,但
    发表于 07-11 06:42

    十种主流电机拆解解析:内部结构大揭秘!

    点击附件查看全文*附件:十种主流电机拆解解析:内部结构大揭秘!.doc (免责声明:本文系网络转载,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请第一时间告知,删除内容!)
    发表于 04-01 14:25

    i.mx8m如何在u-boot SPL阶段启用pwm?

    () 差异 --git a/board/toradex/verdin-imx8mm/spl.c b/board/toradex/verdin-imx8mm/spl.c 索引 2106
    发表于 03-21 07:51