【翻译】解析OpenWRT中uImage和sysupgrade 的区别
翻译自http://developers-club.com/posts/264843/,有删减
大家都知道,OpenWRT镜像的发布站点目录中存在两种类型的固件------uImage和sysupgrade,比如下面这两个:
openwrt-15.05-rc3-ramips-rt305x-dir-320-b1-initramfs-uImage.bin
openwrt-15.05-rc3-ramips-rt305x-dir-320-b1-squashfs-sysupgrade.bin
官方FAQ非常贪婪的(存疑)写了关于他们的区别:
不同格式的镜像有什么区别?factory镜像是一个给bootloader升级用的
sysupgrade镜像(之前称之为trx镜像)是设计给openwrt自己升级用的。
两者拥有相同的内容,不过一个factory镜像拥有额外的头部信息或者该设备平台所需的任何东西。通常来说,factory镜像是需要刷机工具将它刷到设备上的。除此之外,使用升级镜像。
根据该文档,可以通过原厂固件web界面里的固件升级选项升级,不过得不是包含额外头部信息的factory镜像。
很好,我们来比较一下这两个固件的大小:
openwrt-15.05-rc3-ramips-rt305x-dir-320-b1-initramfs-uImage.bin — 3253035 字节.
openwrt-15.05-rc3-ramips-rt305x-dir-320-b1-squashfs-sysupgrade.bin — 3407876 字节.
sysupgrade差不多比uImage大了140KB,根据他们在文档中解释的关于大小的问题,uImage损失了它的“额外的信息”------似乎损失的有点多。
当然,可以从汇编脚本(存疑)来比较他们的不同点,但是,这是不切实际的。今天我们将会泛泛比较他们(类似黑盒测试?)仿佛我们没有源码一样,在文章的最后我们将会使用汇编脚本来证实我们的猜想。
我们分析固件的主要手段是通过linux下的一个分析工具binwalk。让我们先重命名固件的文件名,使我们更方便地去分析它,我们将开始研究他们。
> binwalk ./uImage.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 uImage header, header size: 64 bytes, header CRC: 0x19DE1499, created: Fri Jul 3 22:16:00 2015, image size: 3252971 bytes, Data Address: 0x80000000, Entry Point: 0x80000000, data CRC: 0x886ADE01, OS: Linux, CPU: IPS, image type: OS Kernel Image, compression type: lzma, image name: "MIPS OpenWrt Linux-3.18.17" 64 0x40 LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 5479932 bytes
似乎整个镜像文件的内容都是uImage——在前64(0x40)字节,它表明其后的数据流采用了LZMA算法,并且大小是3252971字节。让我们将64和3252971相加,我们将会得到3253035字节,这正是我们下载的镜像的大小。因此,除了uImage镜像外,该文件中不包含别的内容。Binwalk可以解压发现的lzma数据流。原则上我们可以手动去解压,但是当我们拥有一个方便的工具的时候为何还累着自己呢?
> binwalk -e ./uImage.bin
让我们看看解压出来的东西
> ls -l ./_uImage.bin.extracted/ итого 8532 -rw-r--r-- 1 user user 5479932 авг 8 23:10 40 -rw-r--r-- 1 user user 3252971 авг 8 23:10 40.7z名为40的那个文件,也可以解压,我们用binwalk来看下:
binwalk ./_uImage.bin.extracted/40 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 2812692 0x2AEB14 Linux kernel version "3.18.17 (buildbot@builder1) (gcc version 4.8.3 (OpenWrt/Linaro c version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r46018) ) #2 Fr" 2932132 0x2CBDA4 LZMA compressed data, properties: 0x5D, dictionary size: 16777216 bytes, missing uncompressed size 2936592 0x2CCF10 xz compressed data 3400392 0x33E2C8 LZMA compressed data, properties: 0x6D, dictionary size: 1048576 bytes, uncompressed size: -1 bytes
我们已经得到了一下东西,还不是很明晰——binwalk已经在0x2AEB14发现了linux内核并且有3个压缩包数据流在内核后面。(省略) 根据常识,linux内核地址从shift 0开始,并且后面跟随一个(只有一个)压缩后的数据流叫做initramfs——初始化最初的文件系统到内存中。内核文档中也这么说: 什么是initramfs? ——所有的2.6内核包含了一个gzip压缩过的“cpio”格式的档案,当内核启动的时候它将被解压到根文件系统。解压之后,内核检查跟文件系统中是否存在“init”文件,并且它是否以PID 1运行
进一步的
2.6内核构造程序总是创建一个gzip压缩过的cpio格式的档案并且将它链接到已存在的内核二进制文件(存疑)。默认情况下,这个档案是空的(在x86体系结构下占用134字节)。
这就是提到的CPIO格式
让我们看看binwalk能否将它提取出来:
binwalk -e ./_uImage.bin.extracted/40 ls -l ./_uImage.bin.extracted/_40.extracted/ итого 14028 -rw-r--r-- 1 user user 2547808 авг 8 23:25 2CBDA4.7z -rw-r--r-- 1 user user 2543340 авг 8 23:25 2CCF10.tar -rw-r--r-- 1 user user 7186944 авг 8 23:25 33E2C8 -rw-r--r-- 1 user user 2079540 авг 8 23:25 33E2C8.7z那么,只有在33E2C8的那个压缩文件被成功解压了,如果所有人都操作对了,它应该是一个被CPIO包裹着的文件系统:
binwalk _uImage.bin.extracted/_40.extracted/33E2C8 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 ASCII cpio archive (SVR4 with no CRC), file name: "dev", file name length: "0x00000004", file size: "0x00000000" 116 0x74 ASCII cpio archive (SVR4 with no CRC), file name: "dev/console", file name length: "0x0000000C", file size: "0x00000000" 240 0xF0 ASCII cpio archive (SVR4 with no CRC), file name: "lib", file name length: "0x00000004", file size: "0x00000000" 356 0x164 ASCII cpio archive (SVR4 with no CRC), file name: "lib/netifd", file name length: "0x0000000B", file size: "0x00000000" 480 0x1E0 ASCII cpio archive (SVR4 with no CRC), file name: "lib/netifd/netifd-wireless.sh", file name length: "0x0000001E", file size: "0x00001638" ***********Куча файлов*********** 7186416 0x6DA7F0 ASCII cpio archive (SVR4 with no CRC), file name: "dev/urandom", file name length: "0x0000000C", file size: "0x00000000" 7186540 0x6DA86C ASCII cpio archive (SVR4 with no CRC), file name: "dev/pts", file name length: "0x00000008", file size: "0x00000000" 7186660 0x6DA8E4 ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
在该档案的结尾我们看见一个名字为TRAILER!!!的文件,根据文档,他是一个档案文件的尾部标志。
意味着,一个initramfs-uImage固件的结构如下:

现在我们开始squashfs-sysupgrade的分析。从文件名来看,该镜像包含了(除去内核)squashfs文件系统,让我们来看看是否如此。
binwalk -e ./sysupgrade.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 uImage header, header size: 64 bytes, header CRC: 0x66CC90D2, created: Mon Jul 6 21:54:35 2015, image size: 1142606 bytes, Data Address: 0x80000000, Entry Point: 0x80000000, data CRC: 0x91B77696, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "MIPS OpenWrt Linux-3.18.17" 64 0x40 LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 3396940 bytes 1142670 0x116F8E Squashfs filesystem, little endian, version 4.0, compression:lzma (non-standard type definition), size: 2221946 bytes, 1132 inodes, blocksize: 262144 bytes, created: Mon Jul 6 21:54:02 201564 + 1142606 (镜像大小) = 1142670,刚好等于squashfs镜像的起始地址,而且它结束于1142670 + 2221946 = 3364616。整个bin的大小是3407876字节,有3407876-3364616=43260字节是binwalk所未能识别的。让我们使用hexdump看看那个位置。
hexdump -s 3364616 ./sysupgrade.bin 0335708 ffff ffff ffff ffff ffff ffff ffff ffff * 0335ff8 ffff ffff ffff ffff adde dec0 ffff ffff 0336008 ffff ffff ffff ffff ffff ffff ffff ffff * 0337ff8 ffff ffff ffff ffff adde dec0 ffff ffff 0338008 ffff ffff ffff ffff ffff ffff ffff ffff * 033fff8 ffff ffff ffff ffff adde dec0 0340004
此处很明显有一些存根(存疑),我们待会再回到这里。
我们先进入用binwalk解压操作所创建的目录
ls -l _sysupgrade.bin.extracted/ итого 8820 -rw-r--r-- 1 user user 2221946 авг 8 23:40 116F8E.squashfs -rw-r--r-- 1 user user 3396940 авг 8 23:40 40 -rw-r--r-- 1 user user 3407812 авг 8 23:40 40.7z
解压文件“40”
binwalk -e _sysupgrade.bin.extracted/40 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 2812644 0x2AEAE4 Linux kernel version "3.18.17 (buildbot@builder1) (gcc version 4.8.3 (OpenWrt/Linaro c version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r46018) ) #1 Fr" 2932068 0x2CBD64 LZMA compressed data, properties: 0x5D, dictionary size: 16777216 bytes, missing uncompressed size 2936444 0x2CCE7C xz compressed data 3396424 0x33D348 ASCII cpio archive (SVR4 with no CRC), file name: "dev", file name length: "0x00000004", file size: "0x00000000" 3396540 0x33D3BC ASCII cpio archive (SVR4 with no CRC), file name: "dev/console", file name length: "0x0000000C", file size: "0x00000000" 3396664 0x33D438 ASCII cpio archive (SVR4 with no CRC), file name: "root", file name length: "0x00000005", file size: "0x00000000" 3396780 0x33D4AC ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
我们得到了linux内核和小型的initramfs-image(只包含4个文件),其余的也许都移动到了squashfs镜像里了。
unsquashfs -i ./_sysupgrade.bin.extracted/116F8E.squashfs Parallel unsquashfs: Using 4 processors 1033 inodes (1034 blocks) to write squashfs-root squashfs-root/bin squashfs-root/bin/ash squashfs-root/bin/board_detect squashfs-root/bin/busybox ***********Куча файлов*********** squashfs-root/www/luci-static/resources/load.svg squashfs-root/www/luci-static/resources/wifirate.svg squashfs-root/www/luci-static/resources/wireless.svg squashfs-root/www/luci-static/resources/xhr.js created 848 files created 99 directories created 184 symlinks created 0 devices created 0 fifos
果然,主要的文件系统都被包含进squashfs镜像了
...(英语捉急,翻译不下去了,感兴趣的请直接查看原文。。。)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架