swupdate是一个基于嵌入式的Linux平台的升级服务框架程序,它提供了分区升级,文件升级,差分升级(补丁应用)功能,并提供了开放接口,方便用户添加自定义升级处理函数。
swupdate提供了故障安全的升级方案。支持Recovery方案和A/B系统方案来保证断电等异常情况下能保证升级正常。它提供了完整性,签名验证,固件加密等功能,保证了升级固件的安全性和私密性。
说明文档路径:https://sbabic.github.io/swupdate/overview.html
代码路径:https://github.com/sbabic/swupdate.git
swupdate 采用cpio的方式进行归档,第一文件是描述文件,默认名称为sw-description。该文件描述了升级包归档文件中的文件信息和升级信息。
第二个文件sw-description.sig该文件是对sw-description的签名文件。保证了sw-description的完整性和授权属性。下面的文件就是各个固件文件了。
如果我们要编译一个全功能的swupdate,需要依赖下列这些库。本次为技术预研,为加快进度,依赖库就不一一去移植了。直接使用buildroot去编译,让buildroot去处理依赖关系。依赖库如下:
mtd-utils: internally, mtd-utils generates libmtd and libubi. They are commonly not exported and not installed,
but they are linked by SWUpdate to reuse the same functions for upgrading MTD and UBI volumes.
openssl / wolfssl / mbedtls (optional) for cryptographic operations
p11-kit & wolfssl (optional) for PKCS#11 support
Lua: liblua and the development headers.
libz is always linked.
libconfig (optional) for the default parser
libarchive (optional) for archive handler
librsync (optional) for support to apply rdiff patches
libjson (optional) for JSON parser and hawkBit
libubootenv (optional) if support for U-Boot is enabled
libebgenv (optional) if support for EFI Boot Guard is enabled
libcurl used to communicate with network
在buildroot中,我们搜索swupdate,然后选中我们选中swupdate。本次我们需要验证swupdate的基础功能如下:
1)基础web升级。
2)镜像升级功能,文件升级功能,安装脚本功能。
3)升级文件完整性验证。
4)升级文件签名验证。
5)升级文件加解密功能。
6)差分升级(delta升级)功能。
7)包压缩功能。
8)硬件兼容性检测
9)swupdate ipc功能
首先使用一较新的buildroot, 至少是较新的swupdate。我当前使用的swupdate是2017年的比较旧。我使用新的buildroot里的swupdate包进行了替换,替换后的版本swupdate 2022。我们修改buildroot下swupdate的配置文件,以支持我们上述的测试需求。修改的文件为
buildroot/package/swupdate/swupdate.config
CONFIG_HW_COMPATIBILITY=y
CONFIG_SSL_IMPL_OPENSSL=y
CONFIG_HASH_VERIFY=y
CONFIG_SIGNED_IMAGES=y
CONFIG_SIGALG_RAWRSA=y
CONFIG_ENCRYPTED_IMAGES=y
CONFIG_GUNZIP=y
CONFIG_DELTA=y
CONFIG_RDIFFHANDLER=y
CONFIG_SHELLSCRIPTHANDLER=y
这里有个小技巧,下载swupdate源码,使用源码进行make menuconfig选中需要的功能,然后diff .config .config.old就能找出需要新加的配置选项了。
编译完成后,去到编译路径下,buildroot/output/rockchip_rk3568/build/swupdate-2022.12,查看一下.config文件中的配置是否符合预期。如果不符合预期多半是依赖库没有选上。
我出现了 SHELLSCRIPTHANDLER 功能被覆盖成 is not set。应该是librsync没有选上导致的。我们可以看一下buildroot/package/swupdate/Config.in文件,能发现一些线索。
当我们选上librsync和修改完成配置后,在buildroot中进行编译。
rm buildroot/output/rockchip_rk3568/build/swupdate-* -rf
make swupdate
编译完成后,在buildroot下的安装目录下(x/target/)将swupdate进行打包。打包命令如下,虽然将.h等文件也打包进去了,有点粗鲁,但是简单又快。
文档说要使用zchunk来作为增量升级的方式。zchunk分块压缩看起来比较复杂。。
find ./ -name "*swupdat*" -print0 \
-o -name "libconfig*" -print0 \
-o -name "librsync*" -print0 \
-o -name "libbz2*" -print0 | tar -cvf swupdate.tar --null -T -
在目标板(aarch64)中进行解压,加压命令
tar -xvf swupdate.tar -C /
等以后有时间了,再一点一点移植库,因为我们固件不是使用builtroot构建的。
我们先测试一下命令是否能正常运行。测试 swupdate,swupdate-progress,swupdate-client,swupdate-ipc。当帮助信息能打印时说明命令移植正常。但不确保功能都支持了。
swupdate -h
能正常打印help信息,有 -w,-k,-K信息说明验签,加密都使能了。下面是查看版本信息
# swupdate --version
SWUpdate v2022.12 (Buildroot 2018.02-rc3-g7e95a20c-dirty)
# swupdate-progress -h
swupdate-progress (compiled Jun 19 2023)
Usage swupdate-progress [OPTION]
-c, --color : Use colors to show results
-e, --exec