Rockchip RK3588 - Rockchip Linux Recovery updateEngine测试
----------------------------------------------------------------------------------------------------------------------------
开发板 :ArmSoM-Sige7
开发板
eMMC
:64GB
LPDDR4
:8GB
显示屏 :15.6
英寸HDMI
接口显示屏
u-boot
:2017.09
linux
:5.10
----------------------------------------------------------------------------------------------------------------------------
在《Rockchip RK3588 - Rockchip Linux Recovery updateEngine
源码分析》中我们已经对updateEngine
源码的来龙去脉做了详细的介绍,本节将会介绍如何使用updateEngine
进行固件的升级。
一、制作系统镜像
首先我们需要将我们制作的统一固件update.img
(这里以buildroot
系统为例)烧录到开发板eMMC
中,具体烧录步骤可以参考《Rockchip RK3588 - Rockchip Linux SDK
编译》。
制作统一固件update.img
有多种方式:
- 采用
./build.sh all
进行一键全自动编译(包含了uboot
、kernel
等): - 按模块进行编译;
由于《Rockchip RK3588 - Rockchip Linux SDK
编译》中我们已经编译了uboot
、kernel
、rootfs
等模块,因此在这里我们采用按模块编译的方式重新编译rootfs
,recovery
,具体步骤如下文所述。
1.1 buildroot
编译
这里我们使用buildroot
系统,在SDK
根目录下执行如下命令重新编译生成rootfs.ext2
:
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo ./build.sh buildroot
编译使用的配置项是rockchip_rk3588_defconfig
的配置,其配置项远远多余rockchip_rk3588_recovery_defconfig
的配置;
#include "base/base.config"
#include "chips/rk3588_aarch64.config"
#include "font/chinese.config"
#include "fs/exfat.config"
#include "fs/ntfs.config"
#include "fs/vfat.config"
#include "gpu/gpu.config"
#include "multimedia/audio.config"
#include "multimedia/camera.config"
#include "multimedia/gst/audio.config"
#include "multimedia/gst/camera.config"
#include "multimedia/gst/rtsp.config"
#include "multimedia/gst/video.config"
#include "multimedia/mpp.config"
#include "wifibt/bt.config"
#include "wifibt/wireless.config"
#include "benchmark.config"
#include "chromium.config"
#include "debug.config"
#include "npu2.config"
#include "powermanager.config"
#include "test.config"
#include "weston.config"
编译后在buildroot/output/rockchip_rk3588/images
下生成不同格式的镜像, 默认使用rootfs.ext2
文件;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot$ ll output/rockchip_rk3588/images/
-rw-r--r-- 1 root root 615688192 6月 25 00:51 rootfs.cpio
-rw-r--r-- 1 root root 273879343 6月 25 00:52 rootfs.cpio.gz
-rw-r--r-- 1 root root 761266176 6月 25 00:52 rootfs.ext2
lrwxrwxrwx 1 root root 11 6月 25 00:52 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root 275013632 6月 25 00:52 rootfs.squashfs
-rw-r--r-- 1 root root 624496640 6月 25 00:52 rootfs.tar
可以看到编译出来的rootfs.ext2
有700M+
。
编译出来的rootfs.ext2
仅仅包含updateEngine
可执行文件。
1.2 recovery
编译
在SDK
根目录下执行如下命令重新编译生成recovery.img
:
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo ./build.sh recovery
编译后在buildroot/output/rockchip_rk3588_recovery/images/
目录下生成recovery.img
;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot$ ll output/rockchip_rk3588_recovery/images/
-rw-r--r-- 1 root root 44336128 6月 18 01:48 recovery.img
-rw-r--r-- 1 root root 15856640 6月 18 01:48 rootfs.cpio
-rw-r--r-- 1 root root 6713449 6月 18 01:48 rootfs.cpio.gz
-rw-r--r-- 1 root root 43342848 6月 18 01:48 rootfs.ext2
lrwxrwxrwx 1 root root 11 6月 18 01:48 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root 6676480 6月 18 01:48 rootfs.squashfs
-rw-r--r-- 1 root root 16947200 6月 18 01:48 rootfs.tar
可以看到编译出来的recovery.img
有40M+
。
编译出来的recovery.img
包含用于升级的updateEngine
、rkupdate
可执行文件;
1.3 打包
1.3.1 打包分区镜像
执行以下命令更新output/firmware/
下各个分区镜像;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ sudo ./build.sh firmware
如果recovery.img
文件不存在,创建recovery.img
链接文件指向buildroot/output/rockchip_rk3588_recovery/images/recovery.img
。
如果rootfs.img
文件不存在,创建recovery.img
链接文件指向buildroot/output/rockchip_rk3588_recovery/images/rootfs.ext2
。
1.3.2 打包统一固件
执行如下命令重新生成统一固件;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ sudo ./build.sh updateimg
编译会生成统一镜像update.img
,位于output/update/update
目录.
如果output/firmware/update.img
文件不存在,创建output/firmware/update.img
链接文件指向output/update/Image/update.img
。
1.4 烧录测试
将统一固件update.img
烧录到开发板中,系统启动后,我们查看文件系统中的updateEngine
;
root@rk3588-buildroot:~# ls /usr/bin/updateEngine -l
-rwxr-xr-x 1 root root 3100260 6月 9 12:58 buildroot/output/rockchip_rk3588/target/usr/bin/updateEngine
如果你研究过rockchip_rk3588_defconfig
,你会发现builroot
编译的板载配置rockchip_rk3588_defconfig
并没有配置updateEngine
/rkupdate
升级方式,那这些文件是哪里来的呢?
这个是由./build.sh buildroot
脚本实现的,其从device/rockchip/common/tools/armhf/
位置将updateEngine
拷贝到buildroot/output/rockchip_rk3588/target/usr/bin
目录下,该文件采用的是静态链接方式(其原因是buildroot
系统并没有安装该程序运行所依赖的动态库)。
这里我们可以使用官方提供的updateEngine
(需要注意的是官方提供的并不会输出日志信息),当然在一些场景下我们可能需要自己编译updateEngine
。
1.4.1 使用recovery.img
中的updateEngine
我们将recovery
编译得到的updateEngine
复制到/work/tftpwork
目录下:
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ cp buildroot/output/rockchip_rk3588_recovery/target/usr/bin/updateEngine /work/tftpboot/
系统运行后, 这里我们将updateEngine
替换成我们编译的updateEngine
;
root@rk3588-buildroot:/userdata# tftp -g -l updateEngine 192.168.0.200
root@rk3588-buildroot:/userdata# chmod +x updateEngine
root@rk3588-buildroot:/userdata# mv updateEngine /usr/bin
root@rk3588-buildroot:/userdata# updateEngine --h
./updateEngine: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory
可以看到该程序是无法直接运行了,因为其依赖了curl
等库,在buildroot
编译并没有安装安装相关依赖。
1.4.2 重新编译updateEngine
我们直接进入updateEngine
源码所在路径,复制一份源码命名为recovery_bak
;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external$ sudo cp -r recovery recovery_bak
创建文件recovery_autogenerate.h
;
#define GIT_COMMIT_INFO -g28f720bc5-240524-dirty
修改Makefile
:
%.o: %.c recovery_version
$(CC) -c $< -o $@ $(CFLAGS)
# 修改为
%.o: %.c # recovery_version
$(CC) -c $< -o $@ $(CFLAGS)
执行如下代码;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/recovery_bak$ sudo make updateEngine CC="/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/host/bin/aarch64-buildroot-linux-gnu-gcc" CFLAGS="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 -I. -fPIC -lpthread -lcurl -lssl -lcrypto -lbz2 -DUSE_UPDATEENGINE=ON -DSUCCESSFUL_BOOT=ON"
注意:这里关闭了RecoveryNoUi
配置,为了减少一下依赖的库(png
、drm
、bm
等)。此处编译我们采用的是动态链接,当然我们也可以制作libcurl.a
、libbz2.a
静态库,采用静态链接编译updateEngine
程序。
编译完成会在当前路径生成updateEngine
;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/recovery_bak$ file updateEngine
updateEngine: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, not stripped
使用objdump
命令查看库依赖:
zhengyang@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/recovery_bak$ objdump -p updateEngine | grep NEEDED
NEEDED libcurl.so.4 # buildroot系统未安装
NEEDED libssl.so.1.1 # buildroot系统已有
NEEDED libcrypto.so.1.1 # buildroot系统已有
NEEDED libbz2.so.1.0 # buildroot系统未安装
NEEDED libc.so.6 # buildroot系统已有
NEEDED ld-linux-aarch64.so.1 # buildroot系统已有
接下来我们依次安装这些依赖(这些库我们直接从recovery
文件系统查找就好),这里在宿主机开启一个http
服务:
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/target$ python -m http.server 8080
下载动态库到开发板buildroot
系统:
root@rk3588-buildroot:/usr/lib64# cd /usr/lib64
# 安装libcurl.so.4.7.0
root@rk3588-buildroot:/usr/lib64# wget http://192.168.0.200:8080/usr/lib64/libcurl.so.4.7.0
root@rk3588-buildroot:/usr/lib64# ln -s libcurl.so.4.7.0 libcurl.so
root@rk3588-buildroot:/usr/lib64# ln -s libcurl.so.4.7.0 libcurl.so.4
# 安装libbz2.so
root@rk3588-buildroot:/usr/lib64# wget http://192.168.0.200:8080/usr/lib64/libbz2.so.1.0.8
root@rk3588-buildroot:/usr/lib64# ln -s libbz2.so.1.0.8 libbz2.so
root@rk3588-buildroot:/usr/lib64# ln -s libbz2.so.1.0.8 libbz2.so.1.0
# 安装libssl.so
root@rk3588-buildroot:/usr/lib64# wget http://192.168.0.200:8080/usr/lib64/libbz2.so.1.0.8
root@rk3588-buildroot:/usr/lib64# ln -s libbz2.so.1.0.8 libbz2.so
root@rk3588-buildroot:/usr/lib64# ln -s libbz2.so.1.0.8 libbz2.so.1.0
1.4.3 查看帮助命令
我们将重新编译得到的updateEngine
拷贝到userdata
,再次执行updateEngine
程序:
root@rk3588-buildroot:/userdata# updateEngine --h
LOG_INFO: *** update_engine: V1.0.1-g28f720bc5-240524-dirty ***.
LOG_INFO: --misc=now Linux A/B mode: Setting the current partition to bootable.
LOG_INFO: --misc=other Linux A/B mode: Setting another partition to bootable.
LOG_INFO: --misc=update Recovery mode: Setting the partition to be upgraded.
LOG_INFO: --misc=display Display misc info.
LOG_INFO: --misc=wipe_userdata Format data partition.
LOG_INFO: --misc_custom= < op > Operation on misc for custom cmdlineLOG_INFO: op: read Read custom cmdline to /tmp/custom_cmdlineLOG_INFO: write Write /tmp/custom_cmdline to custom areaLOG_INFO: clean clean custom areaLOG_INFO: --update Upgrade mode.
LOG_INFO: --partition=0x3FFC00 Set the partition to be upgraded.(NOTICE: OTA not support upgrade loader and parameter)
LOG_INFO: 0x3FFC00: 0011 1111 1111 1100 0000 0000.
LOG_INFO: uboot trust boot recovery rootfs oem
LOG_INFO: uboot_a uboot_b boot_a boot_b system_a system_b.
LOG_INFO: 100000000000000000000000: Upgrade loader
LOG_INFO: 010000000000000000000000: Upgrade parameter
LOG_INFO: 001000000000000000000000: Upgrade uboot
LOG_INFO: 000100000000000000000000: Upgrade trust
LOG_INFO: 000010000000000000000000: Upgrade boot
LOG_INFO: 000001000000000000000000: Upgrade recovery
LOG_INFO: 000000100000000000000000: Upgrade rootfs
LOG_INFO: 000000010000000000000000: Upgrade oem
LOG_INFO: 000000001000000000000000: Upgrade uboot_a
LOG_INFO: 000000000100000000000000: Upgrade uboot_b
LOG_INFO: 000000000010000000000000: Upgrade boot_a
LOG_INFO: 000000000001000000000000: Upgrade boot_b
LOG_INFO: 000000000000100000000000: Upgrade system_a
LOG_INFO: 000000000000010000000000: Upgrade system_b
LOG_INFO: 000000000000001000000000: Upgrade misc
LOG_INFO: 000000000000000100000000: Upgrade userdata
LOG_INFO: --reboot Restart the machine at the end of the program.
LOG_INFO: --version_url=url The path to the file of version.
LOG_INFO: --image_url=url Path to upgrade firmware.
LOG_INFO: --savepath=url save the update.img to url.
LOG_INFO: --version the version of updateEngine
LOG_INFO: --rkdebug Log output to serial port
LOG_INFO: --ui_rotation UI rotation,has 4 angles(0-3).
可以看到updateEngine
支持的命令参数。
二、 制作升级镜像
按照正常的固件编译流程,制作用于升级的update.img
固件,可以参考《Rockchip RK3588 - Rockchip Linux SDK
编译》。
升级固件不一定要全分区升级,可修改 package-file
文件,将不要升级的分区去掉,这样可以减少升级包的大小。
例如,执行如下命令(可参考文件tools/linux/Linux_Pack_Firmware/rockdev/rk3588-package-file
):
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ sudo ./build.sh edit-package-file
将 backup
的相对路径改为 RESERVED
,这样就不会backup.img
,即不升级backup
分区。
# NAME PATH
package-file package-file
parameter parameter.txt
bootloader MiniLoaderAll.bin
uboot uboot.img
misc misc.img
boot boot.img
recovery recovery.img
backup RESERVED
rootfs rootfs.img
oem oem.img
userdata userdata.img
注意: 若将升级固件放至设备的/userdata/
目录,则不要升级userdata
分区;我们可以不对userdata.img
进行打包,将userdata.img
改为RESERVED
即可。
执行如下命令生成统一固件;
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ sudo ./build.sh updateimg
将制作好的升级固件拷贝到U
盘、TF
卡或者开发版的/userdata/
目录下。
我们可以将统一镜像复制到/work/tftpwork
目录下:
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ cp ./rockdev/update.img /work/tftpboot/
三、buildroot
系统升级
OTA
(Over-the-Air
)即空间下载技术。 OTA
升级是Android
系统提供的标准软件升级方式。它功能强大,可以无损失升级系统,主要通过网络,例如WIFI
、3G/4G/5G
自动下载OTA
升级包、自动升级,也支持通过下载OTA
升级包到SD
卡/U
盘升级,OTA
的升级包非常的小,一般几MB
到十几MB
。
本节主要介绍了使用OTA
技术升级时,本地升级程序updateEngine
/rkupdate
执行升级的流程及技术细节,以便用户在开发过程中了解升级的过程及注意事项。
3.1 updateEngine
升级命令
3.1.1 升级流程
updateEngine
升级流程如下:
- 固件版本比较(
--version_url
); - 下载固件(
--image_url
),并保存到本地(--savepath
); normal
系统下升级recovery
分区;- 重启,进入
recovery
系统,升级其它分区(--partition
); - 升级成功,重启进入
normal
系统。
这里有一点需要补充,如果我们指定了需要升级的分区,并且需要升级的分区中没有recovery
分区,那么会在normal
系统下升级所有分区;换句话说只有需要升级的分区中包含了recovery
分区,那么升级过程才会包含上述步骤的第三部、第四步。
因此在升级指定升级分区时一定要指定recovery
分区,这样才会进入recovery
系统烧录除了recovery
之外的分区;
- 如果没有指定
recovery
分区,那么将会在normal
系统进行烧录,存在诸多风险,比如:升级中断导致normal
系统无法正常启动; - 而在
recovery
系统进行升级能保证升级的完整性,即升级过程被中断,如异常掉电,升级仍然能继续执行;
注意:除此之外,我们还需要注意一点,不可以升级升级固件update.img
存放的分区,因为这样存在覆盖的问题。比如我们如果将升级固件放在/userdata
目录,就不要升级userdata
分区。
3.1.2 升级命令
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了