【翻譯】解析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 2015
64 + 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鏡像了

...(英語捉急,翻譯不下去了,感興趣的請直接查看原文。。。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM