一、简介
OpenWRT提供了一套系统升级机制,可以通过命令行方式也可以通过网页方式,本文主要想介绍一下OpenWRT下sysupgrade常见的操作用法和sysupgrade升级流程,这里主要介绍了整个升级过程涉及到的进程,有了这个宏观上的升级流程后在深入到各个进程中去查看对应的功能,这么一套组合拳下来,相信大家会对OpenWRT的升级流程有更深的理解。
二、sysupgrade升级操作流程
系统升级的主要入口是/sbin/sysupgrade,它是OpenWrt系统自带的一个升级脚本。下图展示了sysupgrade的常用用法介绍。
升级操作流程如下:
1)上传sysupgrade固件包到设备(可以存放在RAM,如/tmp目录,也可以存放在Flash,如/data目录等)
# adb push sysupgrade.bin /tmp
# adb push sysupgrade.bin /data
2)执行sysupgrade命令启动升级
NOTICES:启动固件升级后,adb shell会退出,因为sysupgrade升级程序会关闭除upgrade进程外的其他进程.
3)升级完成后模块自动重启
三、sysupgrade备份还原机制
sysupgrade升级默认是会备份指定好的文件,然后在升级完成后自动还原,这些需要保存的文件在openwrt/target/linux/<BOARD>/<PROJECT>/base-files/etc/sysupgrade.conf中设定。
3.1、备份机制代码流程
1)执行sysupgrade /tmp/sysupgrade.bin命令后,模块内部默认开始执行备份操作,SAVE_CONFIG默认是1,只有在配置-n选项的情况下,它才会被设置为0,所以,默认是自动执行备份操作。

2)执行到升级的第二阶段do_stage2时会将备份文件拷贝到/data目录


3.2、还原机制流程
系统启动后执行到1restore脚本后开始自动解压之前备份在/data目录下的sysupgrade.tgz数据。

四、sysupgrade升级流程剖析
下图描述了整个sysupgrade升级过程中进程转换的流程图,这里体现了进程之间的变化和关键动作,下面会从各个进程入手,逐步的来分析各进程的功能。
4.1、/bin/sh /sbin/sysupgrade
首先执行的sysupgrade进程位于openwrt/package/base-files/files/sbin/sysupgrade,它本质上是一个shell脚本,它的主要功能有:
1)解析参数
2)校验固件合法性
3)检验sysupgrade压缩包是否正常,然后检查升级包是否在/tmp目录,不在的话则会拷贝到/tmp目录
4)从sysupgrade中解压出vendor_info文件,然后用于ENDC的校验
这里是通过发送QKENDC命令获取当前的ENDC信息,然后和vendor_info文件中的信息对比来检验。
5)保存config配置文件,并打包成一个压缩包
默认的SAVE_CONFIG为1,即默认要保存配置文件
6)ubus call system sysupgrade
这里会往procd进程发送消息来继续执行system_methods下面的sysupgrade操作。
该进程其实是/bin/ash的子进程,正常情况下,它会在/lib/upgrade/stage2进程中被强制删除掉。
4.2、/sbin/procd
1)sysupgrade_exec_upgraded()
该函数位于openwrt/build_dir/target-aarch64_cortex-a55+neon-vfpv4_musl/procd-default/procd-2021-03-08-2cfc26f8/sysupgrade.c,主要功能是在执行完execvp("/sbin/upgraded", argv)后,PID=1的procd进程就会被替换成/sbin/upgraded进程了。
4.3、/sbin/upgraded
该进程的实现位于openwrt/build_dir/target-aarch64_cortex-a55+neon-vfpv4_musl/procd-default/procd-2021-03-08-2cfc26f8/upgraded/upgraded.c中,在sysupgrade函数中会通过fork/execvp创建子进程用于执行/lib/upgrade/stage2。
4.4、/lib/upgrade/stage2
该进程位于openwrt/target/linux/gem6xxx/evb6990_cpe_mt7990_emmc/base-files/lib/upgrade/stage2,它其实是个shell脚本,主要功能是:
1)设置LED的闪烁逻辑来指示升级状态
2)关闭除本进程和子进程外的其他进程
3)切换到ramfs,这里会拷贝相关命令到/tmp/root目录下,同时在/tmp/root目录下构建一个临时文件系统
4)执行exec /bin/busybox ash -c "/lib/upgrade/do_stage2"命令后,当前进程会被替换成/lib/upgrade/do_stage2进程继续执行
4.5、/lib/upgrade/do_stage2
该进程位于openwrt/package/base-files/files/lib/upgrade/do_stage2,其实也是一个shell脚本,这里是升级处理的核心部分,主要功能:
1)执行升级动作 - platform_do_upgrade
2)若有实现platform_copy_config,则执行
3)输出升级完成的日志
4)重启设备用于启动到升级分区
到这里我们不仅从整体上对升级流程有了整体框架的概念,这个流程图很关键,同时对里面的细节进行了解后,这样我们在处理升级相关的问题就没什么大的问题了,另外,一般来说,升级过程会和系统启动过程强关联,比如目前接触的项目是AB双系统,在升级重启后启动也有很多相关的处理逻辑,这个和平台是强相关的,这里也就不在展开说了。