RK3568 AB分区+OTA升级(Linux)
文章目录
- 1、前言
- 2、概念理清
- 3、Rockchip Linux A/B
- 4、实践
- 4.1、替换分区表
- 4.2、uboot配置
- 4.3、buildroot配置
- 4.4、编译打包镜像
- 4.5、生成OTA镜像
- 4.6、OTA升级
- 4.7、验证
- 5、AB系统升级流程的详细介绍
- 5.1、数据结构
- 5.2、引导流程
- 6、总结
1、前言
硬件:飞凌ok3568-c开发板
软件:原厂rk356x sdk(Linux)
2、概念理清
前段时间发布了一个基于uboot的镜像更新菜单:https://github.com/Cohen0415/USUM,可以通过uboot菜单来更新镜像。但这种方式在更新镜像时,整个系统是不可被使用的,必须升级完后才可使用,我们将这种更新称为“离线更新”。
而AB分区概念的诞生,是为了实现“在线更新”,即镜像更新过程中,不影响当前系统的正常运行。
3、Rockchip Linux A/B
这里简单介绍下原理,文章结尾会再着重介绍。
目前只对 boot 和 system 进⾏了双分区:
其实就是为内核和rootfs多弄了一个分区。届时uboot根据misc分区的一些标志位来决定引导那个分区。
4、实践
4.1、替换分区表
sdk中提供了AB分区的分区表parameter-buildroot-fit-ab.txt
:
FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3568
MACHINE_ID: 007
MANUFACTURER: RK3568
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
GROW_ALIGN: 0
CMDLINE: mtdparts=:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot_a),0x00020000@0x00028000(boot_b),0x00010000@0x00048000(backup),0x00c00000@0x00058000(system_a),0x00c00000@0x00c58000(system_b),0x00040000@0x01858000(oem),-@0x01898000(userdata:grow)
将方案中的分区表换成parameter-buildroot-fit-ab.txt
,以便于后续打包生成的镜像是支持AB分区的:
4.2、uboot配置
uboot需开启以下配置:
CONFIG_AVB_LIBAVB=y
CONFIG_AVB_LIBAVB_AB=y
CONFIG_AVB_LIBAVB_ATX=y
CONFIG_AVB_LIBAVB_USER=y
CONFIG_RK_AVB_LIBAVB_USER=y
CONFIG_ANDROID_AB=y # 启用 A/B 引导槽机制(核心)
4.3、buildroot配置
buildroot开启以下配置后,系统会多出一个工具叫updateEngine
,该工具由rk实现,后续将使用该工具完成镜像的更新操作。
BR2_PACKAGE_RECOVERY=y # 开启升级功能
BR2_PACKAGE_RECOVERY_BOOTCONTROL=y # 开启引导控制脚本
BR2_PACKAGE_RECOVERY_RETRY=y # 引导⽅式为retry模式,不配置则默认为successful_boot模式
BR2_PACKAGE_RECOVERY_USE_UPDATEENGINE=y # 使⽤新升级程序
BR2_PACKAGE_RECOVERY_UPDATEENGINEBIN=y # 编译新升级程序
BR2_PACKAGE_RECOVERY_NO_UI=y # 关掉UI
这个工具倒不是必须的,你也可以自己实现镜像的更新操作。
4.4、编译打包镜像
至此,编译打包镜像,并更新到板卡,以确保系统镜像是支持AB分区的:
./build.sh
进入系统后,在根目录下创建一个文件,用于验证后续rootfs是否更新成功:
echo 666 > flag.txt
4.5、生成OTA镜像
我们需要生成一个专门用于AB系统的ota镜像,在sdk根目录下执行:
./build.sh ota-updateimg
ota镜像位于:
<sdk>/output/update-ota/update.img
将update.img拷贝至板卡。
4.6、OTA升级
使用updateEngine
工具进行本地ota升级:
# 后台运行,不影响目前系统正常工作
updateEngine --image_url=/mnt/udisk/update.img --update --reboot &# 如果想网络升级
# updateEngine --image_url=http://172.16.21.110:8080/linuxab/update.img --update --reboot &
4.7、验证
更新完后,系统会自动重启,此时观察根目录已经不存在flag.txt
文件,说明系统在线更新成功。
5、AB系统升级流程的详细介绍
5.1、数据结构
misc分区的2k偏移处存放了如下结构体,用于存放 slot_a 和 slot_b 的引导信息:
// Rockchip A/B 分区信息结构(存放于 misc 分区偏移 2048 处,共 32 字节)
typedef struct AvbABData { uint8_t magic[4]; // 结构体头部魔术字:"\0AB0"uint8_t version_major; // 主版本号uint8_t version_minor; // 次版本号uint8_t reserved1[2]; // 保留字节(对齐)// A/B 分区引导槽状态(两个槽)struct SlotData { uint8_t priority; // 启动优先级,0~15,0 表示禁用uint8_t tries_remaining; // 剩余启动尝试次数(最多 7 次)uint8_t successful_boot; // 1 表示已成功启动过uint8_t is_update; // 1 表示升级成功,后 7 位为保留(或平台自定义)} slots[2]; // slot_a、slot_b,共 8 字节uint8_t last_boot; // 上次成功启动的槽:0 表示 slot_a,1 表示 slot_buint8_t reserved2[11]; // 保留字节(填充到 32 字节)uint32_t crc32; // 结构体 CRC 校验(覆盖前 28 字节)
} AvbABData;
整个AvbAbData
结构体大小为32Byte,存储在misc分区的2KByte偏移处。可以通过dd命令查看其数据,如下是第一次烧录镜像后的misc分区数据:
root@rk3568-buildroot:/# dd if=/dev/mmcblk0p2 bs=1 skip=2048 count=32 | hexdump -C
00000000 00 41 42 30 01 00 00 00 0f 07 00 00 0e 07 00 00 |.AB0............|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 79 f1 e5 bf |............y...|
解析后得到结论如下:
字段 值 含义
magic 00 41 42 30 "\0AB0",结构有效
version 1.0 A/B 数据结构版本
slot_a.priority 15 启动优先级
slot_a.tries_remaining 7 剩余启动尝试次数
slot_a.successful_boot 0 未标记成功启动(Successful boot模式才有用)
slot_a.is_update 0 表示升级是否成功(可选,平台自定义)
slot_b.priority 14 启动优先级
slot_b.tries_remaining 7 剩余启动尝试次数
slot_b.successful_boot 0 未标记成功启动(Successful boot模式才有用)
slot_b.is_update 0 表示升级是否成功(可选,平台自定义)
last_boot 0 上次引导的是 slot_a
crc32 0x79f1e5bf CRC 校验值
5.2、引导流程
引导⽅式分为 successful_boot 和 reset retry。 两种模式的对⽐如下:
下图为引导流程图:
例如现在我们使用的是reset retry模式:
- uboot读取misc分区
- 镜像的crc校验
- 比较优先级
- 当系统A优先级最高时,同时tries_remaining>0,tries_remaining减一
- 开始引导系统A,引导失败重回第一步。引导成功后,通过bootcontrol设置misc
这里最后一步中的通过bootcontrol设置misc,其实就是通过/etc/init.d/S99_bootcontrol
脚本,将tries_remaining设置为7,last_boot设置为0。
若此时通过updateEngine
升级镜像,升级的就是系统B。升级结束后会将系统B的优先级设置为15,系统A的优先级设置为14。下次重启,将引导的是系统B,流程和上述一样。
6、总结
参考文章:
《Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf》
rk3568 A/B系统 OAT升级 实践_ok3568-c配置ab分区-CSDN博客