19-Openwrt双固件升级

2023-11-06

在上一章节《Openwrt sysupgrade系统升级》中,我们描述了sysupgrade升级系统的过程,这种升级过程会直接firmware分区进行写入,无法保证系统的安全性,只要在写入过程突然断电就会出现系统写入失败,升级失败无法启动系统的问题。

为了解决该问题一般会使用双固件升级的方式,有一个主分区firmware和一个备份分区firmware_backup,常见的有双固件升级方式有很多种,这边只介绍一种通用方式

1.升级流程

  • 1.根据sysupgrade的过程,将固件进行校验写入,不过写入的时候将升级文件写入到备份分区firmware_backup,不直接写主分区firmware。
  • 2.写完备份分区后,设置备份分区写入完成标志位(一般会开辟一块很小的分区用来写标志位),然后重启系统
  • 3.uboot启动的时候,检测到备份分区标志位被置位,则读取备份分区firmware_backup的固件内容。
  • 4.对firmware_backup的内容进行校验,校验一切正常后,将firmware_backup的内容写入到firmware分区。
  • 5.firmware写入完成后,启动系统,系统启动完成后将备份分区标志位清零,这样下次启动后就不会再次升级系统。

通过双固件的方式就不会出现升级失败系统启动不了的问题。

  • 如果步骤1写入过程被断电也不会出问题,因为主分区正常启动,只是没有升级到最新的分区而已。
  • 如果是步骤4升级过程被断电也不会出问题,再次启动的时候会检测到主分区有问题会被再次写入。

2.修改内容

2.1 sysupgrade写入备份分区

PART_NAME修改位备份分区

PART_NAME=firmware_backup

写入固件完成重启前,设置备份分区标志位

//set backup_flg=1

v "Upgrade completed"
                              
[ -n "$DELAY" ] && sleep "$DELAY" 
v "Rebooting system..."          
upgrade_log_end                  
reboot -f                        
sleep 2                          
force_reboot   

2.2 uboot对双系统的支持

双固件最主要的工作都在uboot下面进行,一些mtk提供的新版本uboot一般会有支持部分双固件功能,位于dual_image.c文件中。

uboot添加双固件支持的配置


CONFIG_MTK_DUAL_IMAGE_SUPPORT=y
CONFIG_MTK_DUAL_IMAGE_PARTNAME_MAIN="firmware"
CONFIG_MTK_DUAL_IMAGE_PARTNAME_BACKUP="firmware_backup"
CONFIG_MTK_DUAL_IMAGE_SQUASHFS_DATA_CHECK=y
# CONFIG_MTK_DUAL_IMAGE_RESTORE_KERNEL_ONLY is not set

CONFIG_MTDPARTS_DEFAULT="mtdparts=raspi:576k(u-boot),7360k(firmware),7360k(firmware_backup)"

dual_image_check()函数里面就是校验firmware合法性的内容。

firmware为kernel+rootfs,所以校验的时候两块都会进行验证

printf("Verifying main image at 0x%llx...\n", image1_off);
ret = verify_image(flash, image1_off, image1_partsize, &image1_size);
if (ret < 0) {
	printf("Dual image checking is bypassed\n");
	return 0;
}

if (ret == 0) {
	ret = verify_rootfs(flash, image1_off + image1_size,
			    image1_partsize - image1_size,
			    &image1_padding_bytes, &rootfs1_size);
}

image1_ok = ret == 0;
2.2.1 kernel校验

kernel的校验有两种格式

  • 一种是老版本的kernel,我们会把它称作LEGACY
  • 另一种是支持最新设备树的Flattened uImage Tree,会把它称作FIT

校验函数位于verify_image

	case IMAGE_FORMAT_LEGACY:
		return verify_legacy_image(flash, offset, maxsize, load_addr,
					   image_size);
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		return verify_fit_image(flash, offset, maxsize, load_addr,
					image_size);
#endif
	default:
		printf("Invalid image format\n");
		return 1;
	}

里面的具体校验内容,查看代码细究,里面对于几种类型的image都有对于的校验函数。

 image-fdt.c
 image-fit.c
 image-sig.c
 image.c
2.2.2 rootfs校验

现在一般使用的都是squashfs文件系统,校验函数为verify_squashfs

static int verify_rootfs(void *flash, uint64_t offset, uint64_t maxsize,
			 size_t *header_prefix_bytes, size_t *rootfs_size)
{
	uint64_t end = offset + maxsize, leading, extra_bytes, tmp;
	int ret;

	ret = verify_squashfs(flash, offset, end, rootfs_size);
	if (!ret) {
		if (header_prefix_bytes)
			*header_prefix_bytes = 0;
		return 0;
	}

	tmp = offset;
	leading = do_div(tmp, mtk_board_get_flash_erase_size(flash));

	if (!leading)
		return 1;

	extra_bytes = mtk_board_get_flash_erase_size(flash) - leading;
	offset += extra_bytes;

	ret = verify_squashfs(flash, offset, end, rootfs_size);
	if (!ret) {
		if (header_prefix_bytes)
			*header_prefix_bytes = extra_bytes;
		return 0;
	}

	printf("No SquashFS found\n");
	return 1;
}

squashfs文件系统头部有专门的结构信息,如下

#define SQUASHFS_MAGIC		0x73717368

struct squashfs_super_block {
	__le32 s_magic;
	__le32 pad0[9];
	__le64 bytes_used;
};

校验内容

if (le32_to_cpu(sb.s_magic) != SQUASHFS_MAGIC)
	return 1;

size = le64_to_cpu(sb.bytes_used);
if (offset + size >= end) {
	printf("RootFS is truncated\n");
	return 1;
}
2.2.3 根据校验结果进行操作
  • 如果两个分区的固件都有问题,则报错
  • 如果主分区和备份分区都没有问题,判断备份分区是否有置位,置位则将备份分区拷贝到主分区;
  • 如果主分区正常,备份分区异常,则将主分区拷贝到备份分区
  • 如果主分区异常,备份分区正常,则将备份分区拷贝到主分区
2.2.4 注意事项

spi flash的块大小为64K,有时候为了节省空间把设置标志位的分区设置成4k,它不是64k的倍数,这样mtd 读写的时候也会报错

Detected w25q128bv with page size 256 Bytes, erase size 64 KiB, total 16 MiB

另外mount的时候,一般要大于64k的5倍,不然也会出现一直挂载不上

2.3 系统标志位清零

系统启动成功后,在init之后的某个脚本处,将标志位清零即可。后面再次启动的时候就不会重复烧录

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

19-Openwrt双固件升级 的相关文章

  • ZeroTierr的moon云服务器搭建和使用

    搭建moon 本质上是在云服务器上建立一个moon服务器 也加入zerotier的Network ID 服务器记录请求路径来做类似于DNS的解析 让设备之间p2p直连 问题是ZeroTier One本身的服务器都在国外访问速度很慢 可以通过
  • [OpenWrt] Flash 由4M改8M(或者16M), openwrt源码的修改

    http www right com cn forum thread 75309 1 1 html trunk tools firmware utils src mktplinkfw c 只修改fw max len为0xfc0000 16M
  • ubuntu18.04编译Openwrt出现的问题解决

    ubuntu18 04编译Openwrt出现的问题解决 问题1 Build dependency Please install Git git core gt 1 6 5 问题2 gdate c 2497 7 error format no
  • Openwrt编译python3时出现错误:No rule to make target `package//host/compile'

    步骤 1 在package目录下添加python3 包含Makefile files和相关patches文件 2 执行make package python3 compile V s make 1 No rule to make targe
  • (N1盒子) Openwrt 下 docker 容器访问互联网故障排除

    环境 硬件 N1盒子 Openwrt版本 openwrt flippy 60 o 情况描述 先是跑了个运行php的docker容器 日志里报错信息为 cURL error 7 Failed to connect to 域名 port 端口号
  • luci的国际化(多语言)

    语言的选择在dispatch函数入口出完成 如果配置文件 etc config luci中配置的lang为auto 则根据浏览器所带的信息选择一个合适的语言 否则就使用lang定义的语言 然后使用i18n lua中的setlanguage设
  • OpenWRT路由器中监控网络服务并重启的脚本

    转载地址 http jamesqi com E5 8D 9A E5 AE A2 OpenWRT E8 B7 AF E7 94 B1 E5 99 A8 E4 B8 AD E7 9B 91 E6 8E A7 E7 BD 91 E7 BB 9C
  • OpenWrt系统配置UCI

    UCI简介 UCI Unified Configuration Interface 是 Openwrt 中的统一配置接口 官方文档参考 每一个程序的配置文件都保存在 etc config 目录 可以通过文本编辑器 uci 一个可执行程序 以
  • openwrt--内核编译及生成

    重要文件 在下面的目录中包含了编译过程中调用的makefile 很重要的 root localhost openwrt openwrt trunk include ls autotools mk device table txt bak k
  • openwrt x86 版安装纪实

    1 下载源码 已有编译环境 直接在ubuntu 中 git openwrt 源码 https dev openwrt org wiki GetSource git clone b chaos calmer git github com op
  • openwrt路由器-timeout while waiting for PADS.

    最近使用openwrt路由器进行PPPoE拨号的时候 经常出现 远程服务器无响应 的错误 log打印日志如下 pppoe Timeout waiting for PADS packets Unable to complete PPPoE D
  • Openwrt GCC 7.5编译sanitizer_internal_defs.h错误

    GCC 7 5 BINUTILS 2 31 1 报错信息 sanitizer internal defs h 72 error size of array assertion failed is negative 解决方法 修改下列文件 删
  • openwrt中计划任务的设置

    寝室的供网规则为周一到周五零点断网 六点开网 双休日通宵供网 故设置一套计划任务提高路由器使用效率 crontab命令常见于Unix和类Unix的操作系统之中 用于设置周期性被执行的指令 操作符号 在一个区域里填写多个数值的方法 逗号 分开
  • 红米ac2100 刷openwrt以及刷回记录

    redmiac2100 刷机 参考 手动升级漏洞固件 https wwx lanzoux com i6iqxhqp98f 或者百度网盘链接 https pan baidu com s 1H355Ym9p TLrVOux2w2b7Q 提取码
  • 编写 LuCI CBI 模型

    编写 LuCI CBI 模型 CBI模型是描述UCI配置文件结构的Lua文件 并且CBI解析器将lua文件转为HTML呈现给用户 所有 CBI 模型文件都必须返回类型为luci cbi Map的对象 CBI 模型文件的范围由 luci cb
  • OpenWRT添加模块(一)Makefile和Config.in

    第一次接触到openwrt 真是被毁三观啊 不要说makefile 连源代码在哪里都找不到 知道嵌入式系统水深 没想到迈出第一步就没过了脖子 好在旁边有人指点 直接在芯片厂商提供的既有代码上做二次开发 项目进展倒也完全满足了前期计划的目标
  • 1-OpenWrt编译过程-2

    前言 接触 op 已达四年 今年开始梳理整体所学 具体还参考了佐大的视频 对 op 缺乏系统知识的可以尝试 总体而言官方文档和源码是最好的教程 文章目录 编译OpenWrt 概述 1 更新安装所有可选的软件包 2 编译设置 make men
  • 第一次 openwrt源码下载编译

    openwrt 学习记录 第一次 openwrt源码下载编译 MT7620开发板 安装虚拟机VMware 安装Ubnutu 先进入root账户 topeet ubuntu su 输入密码 1 搭建编译环境 参考 https blog csd
  • UCI提供给shell和lua使用的配置接口

    转自 http m blog csdn net article details id 47989493 1 uci提供给shell使用的配置借口有两套 1 config get用来读取一个config值 命令格式如下 config getv
  • 刷新完固件后opkg update报错的解决方法

    刷新完固件后opkg update报错的解决方法 一 更改设备ip 当你使用lan口接入局域网后 如果你ping不通局域网上的其他设备ip 那么需要更改ip vim etc config network 修改lan口的ip为局域网下同一网段

随机推荐

  • 剑指 Offer 57. 和为s的两个数字--双指针问题

    这道题有点像之前一道用hashmap做的乱序数组求两数之和等于指定数的问题 两数相加 时间复杂度小于 O n2 而今天这道题 用hashmap也可以做出 但是空间复杂度实在太大 又因为它是排序好的数组 所以二分法或者双指针法比较简单 双指针
  • DRF视图组件

    目录 视图 APIView APIView与View的不同之处 GenericAPIView 通用视图类 类属性 类方法 基于APIView写五个接口 基于GenericAPIVIew写5个接口 五个视图扩展类 ListModelMixin
  • c/c++位字段

    位字段 定义 位字段是C语言中一种存储结构 不同于一般结构体的是它在定义成员的时候需要指定成员所占的位数 所有基础的数据类型 最大的也不过 10 个字节 我们可以自定义的数据类型 struct 通过把若干类型组合在一起 让一种类型可以大很多
  • linux自动安装trojan客户端的shell脚本

    bin bash 安装Trojan客户端 echo 开始安装Trojan客户端 curl O https github com trojan gfw trojan releases download v1 17 0 trojan 1 17
  • Headless Browser Testing With Xvfb

    Jan 09 15 javascripttesting These days when the phrase headless browser is mentioned you immediately think of PhantomJS
  • 【Python基础】用Cython优化Python代码性能

    Cython是一个编程语言 它结合了Python的简洁性和C语言的性能 本文将深入探讨Cython的基本原理 如何将其应用于Python项目 以及如何使用Cython优化Python代码的性能 文章目录 1 Cython简介 2 Cytho
  • getopt使用样本/模板

    this is the sample of use of getopt funtion include
  • python可以进行软件开发吗,python可以做软件开发吗

    本篇文章给大家谈谈python可以进行软件开发吗 以及python可以做软件开发吗 希望对各位有所帮助 不要忘了收藏本站喔 1 python可以开发什么软件 主要可以做小程序 爬虫程序 用于系统编程等等还是很广泛的 Python的应用领域分
  • element-ui中el-table的错位问题解决,以及新的错位问题的出现(与el-tabs相关)

    element ui的表格错位问题 只出现在带有设置了fixed的列的el table中 这是一个渲染机制的问题 通过调用一遍doLayout方法就可以解决 但是套在el tabs里的el table 就是另一种情况了 简单错位 这是我瞎起
  • vr设备的服务器性能指标,让我们一起聊聊VR眼镜技术参数

    时下最炙手可热的数码产品无疑就是VR眼镜了 而作为影响VR体验的重要一部分 VR眼镜技术参数也成为了很多人讨论的焦点 目前市面上的VR设备良莠不齐 具体什么样的VR眼镜技术参数规格才是优秀的产品 而这些VR眼镜技术参数对用户们的体验来说 又
  • 同步代码块synchronized的使用与解析

    Java 同步块 synchronized block 用来标记方法或者代码块是同步的 Java同步块用来避免竞争 本文介绍以下内容 Java同步关键字 synchronzied 实例方法同步 静态方法同步 实例方法中同步块 静态方法中同步
  • 量化择时——平均K线图双均线策略(第1部分—策略效果测算)

    文章目录 平均K线图概述 OHLC的计算方式 K线图走势对比 平均K线图阴阳线交易策略 交易规则 测算结论 双均线策略测算 测算规则 测算结论 平均K线图概述 平均K线图是蜡烛图的一种分支 在日本 Heikin意味着 平均 Ashi意味着
  • python root:code for hash md5 was not found.错误

    可能还会伴随一大堆其他错误 ERROR root code for hash md5 was not found Traceback most recent call last File usr local Cellar python 2
  • qt 怎么检测鼠标在不在某个控件上

    方式一 推荐 感觉这种事件过滤器的方法捕捉比较敏感 记得安装事件过滤器 this gt installEventFilter this protected bool eventFilter QObject obj QEvent event
  • k8s 配置 glusterFS 动态供给

    部署环境 Host IP k8s 版本 glusterFS版本 heketi版本 heketi client 版本 k8s master1 192 168 10 1 1 20 0 9 5 1 el7 heketi 8 0 0 1 heket
  • 短 URL 服务的设计与实现

    转载 https mp weixin qq com s DJM7KFFfgZ2AgfrrYHXSzQ 短url的好处有 短 短信和许多平台 微博 有字数限制 太长的链接加进去都没有办法写正文了 好看 比起一大堆不知所以的参数 短链接更加简洁
  • 如何查看端口是被哪个程序占用的

    一 开始 gt 运行 gt cmd 或者是window R组合键 调出命令窗口 二 输入命令 netstat ano 列出所有端口的情况 在列表中我们观察被占用的端口 比如是8080 首先找到它 三 查看被占用端口对应的PID 输入命令 n
  • C语言中输入输出重定,freopen()妙用。

    使用的理由 范围 如果输入数据很庞大 需要一次又一次的重新输入和调试时可采用本函数 freopen 函数 1 格式 FILE freopen const char filename const char mode FILE stream 2
  • window如何实时刷新日志文件

    1 安装windows git 下载地址 Git Downloading Package git scm com 2 打开git bash 输入tail exe f 日志文件路径
  • 19-Openwrt双固件升级

    在上一章节 Openwrt sysupgrade系统升级 中 我们描述了sysupgrade升级系统的过程 这种升级过程会直接firmware分区进行写入 无法保证系统的安全性 只要在写入过程突然断电就会出现系统写入失败 升级失败无法启动系