当前位置: 首页 > news >正文

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模式:

  1. uboot读取misc分区
  2. 镜像的crc校验
  3. 比较优先级
  4. 当系统A优先级最高时,同时tries_remaining>0,tries_remaining减一
  5. 开始引导系统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博客

http://www.dtcms.com/a/313016.html

相关文章:

  • 在微信小程序中使用本地存储的方法
  • 《volatile 与 synchronized 底层实现与性能比较》
  • ubuntu syslog中appindicator报错解决
  • 深入理解C++缺省参数:从基础用法到最佳实践
  • 8-verilog-串口接收与发送模块
  • Python切片命名技术详解:提升代码可读性与维护性的专业实践
  • linux下jvm之jstack的使用
  • 洛谷——P1048 [NOIP 2005 普及组] 采药
  • 【openlayers框架学习】九:openlayers中的交互类(select和draw)
  • GaussDB SQL执行计划详解
  • Rust: 获取 MAC 地址方法大全
  • Zama的使命
  • 【读论文】KAG-Thinker:升级版RAG 框架
  • 推荐系统学习笔记(九)曝光过滤 Bloom Filter
  • 【DL学习笔记】感受野(Receptive Field)
  • 映射网络驱动器后,重启映射就没了
  • 王之凝视 免安中文 离线运行版
  • 【Bluetooth】【Transport层篇】第四章 基于基础UART的蓝牙硬件发送协议 UART H4 Transport详解
  • wordpress登陆前登陆后显示不同的顶部菜单
  • 前后端交流
  • Go语言声明变量
  • mybatis实现固定三层树形结构的嵌套查询
  • 怎么修改论文格式呢?提供一份论文格式模板
  • 【ProtoBuf】初识ProtoBuf
  • 【UE5医学影像可视化】读取本地Dicom生成VolumeTexture,实现2D显示和自动翻页
  • 关于记录一下“bug”,在做图片上传的时候出现的小问题
  • B3953 [GESP202403 一级] 找因数
  • 大模型智能体(Agent)技术全景:架构演进、协作范式与应用前沿
  • Python Dash 全面讲解
  • 使用 Vuepress + GitHub Pages 搭建项目文档