程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

Rockchip RK3588 - Rockchip Linux Recovery updateEngine测试

----------------------------------------------------------------------------------------------------------------------------

开发板 :ArmSoM-Sige7开发板
eMMC64GB
LPDDR48GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2017.09
linux5.10
----------------------------------------------------------------------------------------------------------------------------

在《Rockchip RK3588 - Rockchip Linux Recovery updateEngine源码分析》中我们已经对updateEngine源码的来龙去脉做了详细的介绍,本节将会介绍如何使用updateEngine进行固件的升级。

一、制作系统镜像

首先我们需要将我们制作的统一固件update.img(这里以buildroot系统为例)烧录到开发板eMMC中,具体烧录步骤可以参考《Rockchip RK3588 - Rockchip Linux SDK编译》。

制作统一固件update.img有多种方式:

  • 采用 ./build.sh all进行一键全自动编译(包含了ubootkernel等):
  • 按模块进行编译;

由于《Rockchip RK3588 - Rockchip Linux SDK编译》中我们已经编译了ubootkernelrootfs等模块,因此在这里我们采用按模块编译的方式重新编译rootfsrecovery,具体步骤如下文所述。

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.ext2700M+

编译出来的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.img40M+

编译出来的recovery.img包含用于升级的updateEnginerkupdate可执行文件;

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配置,为了减少一下依赖的库(pngdrmbm等)。此处编译我们采用的是动态链接,当然我们也可以制作libcurl.alibbz2.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系统升级

OTAOver-the-Air)即空间下载技术。 OTA升级是Android系统提供的标准软件升级方式。它功能强大,可以无损失升级系统,主要通过网络,例如WIFI3G/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-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
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-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(923)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示