「OpenWRTでUpvel UR-313N4Gルーターをアップグレードする」という記事へのコメントで、謙虚なサーバントと尊敬されている
Maysoftの間で、uImageとsysupgrade OpenWRTファームウェアイメージの構造の違いについて紛争が生じました。
Maysoftに問題を解決
することを約束し
ました 。この記事はあなたの前にあります。
ご存じのように、OpenWRTダウンロードディレクトリでは、ほとんどの場合、uImageとsysupgradeの2種類のファームウェアを使用できます。
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は、両者の違いについて非常に控えめに書いています:
異なる画像形式の違いは何ですか?
工場出荷時のイメージは、ブートローダーフラッシャーまたはストックソフトウェアフラッシャー用に構築されたものです。
sysupgradeイメージ(以前の名前はtrxイメージ)は、openwrt自体からフラッシュされるように設計されています
この2つのコンテンツは同じですが、ファクトリイメージには追加のヘッダー情報またはプラットフォームが必要とするものが含まれます。 一般的に、工場出荷時のイメージは、デバイスをOpenWrtに変換するために、OEM GUIまたはOEMフラッシュユーティリティで使用されます。 その後、sysupgradeイメージを使用します。
ドキュメントによると、工場出荷時のイメージに追加のヘッダーがあり、元のファームウェアのWebインターフェースを介してこのイメージをフラッシュできることを除いて、イメージの内容は同じです。
すばらしい、ファームウェアのサイズを比較してください:
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よりもほぼ140 KB大きく、ドキュメントによると、ほぼ同じサイズである必要があり、この「余分なヘッダー情報」によるuImageは少し大きくなります。
もちろん、uImageとsysupgradeのイメージの違いを理解するには、アセンブリスクリプトを調べるだけで十分ですが、これはスポーツマンらしくないことを認めなければなりません。 今日は、ソースがないようにファームウェアの「額」を分析し、最後にアセンブリスクリプトを見て推測を確認します。
現時点でファームウェアを分析するための主要なツールは、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ストリームを解凍できます。 原則として、ファイルから最初の64バイトを手動で切り取り、lzma -dコマンドを使用して残りをアンパックできますが、なぜ便利なツールがあるのはなぜですか?
> 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は、Linuxカーネルがオフセット0x2AEB14で、カーネルに続く3つの圧縮データストリームを発見しました。 実際、binwalkは分析にヒューリスティックを使用し、それが出力するのは最終的な真実ではなく、検討のための情報です。
常識的には、カーネルはオフセット0から開始し、圧縮ストリームは1で、initramfs(RAMにロードされる初期ファイルシステム)を含む必要があります。 コア
ドキュメントには同じことが
記載されてい
ます 。
initramfsとは何ですか?
-すべての2.6 Linuxカーネルには、gzip圧縮された「cpio」形式のアーカイブが含まれています。これは、カーネルの起動時にrootfsに抽出されます。 抽出後、カーネルはrootfsにファイル「init」が含まれているかどうかを確認し、含まれている場合はPID 1として実行します。
さらに
initramfsの設定:
-2.6カーネルビルドプロセスは、常にgzip圧縮されたcpio形式のinitramfsアーカイブを作成し、結果のカーネルバイナリにリンクします。 デフォルトでは、このアーカイブは空です(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で終了します。一方、画像のサイズは3407876バイトであり、3407876バイトあります。 -3364616 = 43260バイトの身元不明情報。 そこに何があるか見てみましょう、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
明らかにある種のスタブがあります。 後で彼女に戻ってきます。
展開された画像があるディレクトリにあるものを見てみましょう:
> 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
LZMAストリームをオフセット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カーネルと4つのファイルを持つ小さなinitramfsイメージがあります。 残りは明らかに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イメージに含まれています。
次に、画像の最後にあるスタブを扱います。 sysupgradeイメージがフラッシュされてからdmesgにロードされると、次の行が表示されるため、何らかの形でJFFS2 FSに関連している疑いがあります。
[ 29.550000] jffs2_scan_eraseblock(): End of filesystem marker found at 0x0 [ 29.580000] jffs2_build_filesystem(): unlocking the mtd device... done. [ 29.590000] jffs2_build_filesystem(): erasing all blocks after the end marker...
また、uImageイメージをフラッシュしてロードするとき、これらの行はそうではありません。 これらの行を「バニラ」カーネルで検索しても何も得られませんが、
OpenWRTソースツリーには次のような行があります。
ええ、これが0xDEADCODEスタブです。 JFFS2ドライバーはこのタグを見つけると、それを前のファイルシステムの終わりと見なし、タグのゼロバイトからドライブの終わりまでをすべて消去します。 したがって、ラベル自体も上書きされます。
その後、ドライバーはこの場所にJFFS2の新しいインスタンスを作成します。
したがって、次の画像構造が取得されます。

このように:
- uImageにはOpenWRTを実行するために最低限必要な機能が含まれているため、元のファームウェアのWebインターフェイスで検証チェックに合格するように、その構造を簡単に変更できます。
- Sysupgradeはより複雑で、Linux固有のツールであるSquashFSおよびJFFS2を使用します。
- どちらのタイプのイメージにもブートローダーが含まれていません(含まれてはなりません)。
- (UARTまたは災害復旧を介して)ブートローダーを介してフラッシュする場合、すぐにsysupradeを縫うことができます。
- mtd_writeを介してフラッシュするときに、公式ファームウェアからtelnetを介してこのユーティリティを使用できる場合、sysupgradeをすぐにフラッシュすることもできます。
結論として、OpenWRTビルドスクリプトを見て、結論を確認してください。 ファイル
/ target / linux / ramips / Makefileから始めましょう。 しかし、これが通常のGNU Makefileであると思われる場合は、そうではありません。 開発者自身
が改善されたMakefileをどのように説明するかを以下に示します。
パッケージmakefileの1つを見ると、それをmakefileとして認識することはほとんどありません。 従来のmake形式の露骨な無視と濫用としか言いようのないものを通して、makefileは試練全体を単純化するオブジェクト指向テンプレートに変換されました。
イメージビルドは564行で実行されるようです。
Image/Build/Profile/DIR-320-B1=$(call BuildFirmware/Default8M/$(1),$(1),dir-320-b1,DIR-320-B1)
BuildFirmware / Default8Mの目的は、行195および196で説明されています。
BuildFirmware/Default8M/squashfs=$(call BuildFirmware/OF,$(1),$(2),$(3),$(ralink_default_fw_size_8M),$(4)) BuildFirmware/Default8M/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3),$(4))
これは、squashfsとinitramfsの2つの位置で構成されています。 BuildFirmware / OFおよびBuildFirmware / OF / initramfsの目標は、上記の同じファイルに記載されています。
149
そして
169
ターゲットMkImageLzmaDtbの名前から、DTSファイルの説明からuImageイメージが作成されると推測できます。 BuildFirmware / OF / initramfsの目的で、メインファイルシステムを含むinitramfsセクションがこのイメージに追加され、その後、イメージが出力ディレクトリにコピーされます。 BuildFirmware / OFターゲットの場合、ソースイメージはMkImageSysupgrade関数によって処理されます。この関数は、「cat」コマンドを使用して、squashfsセクションをアタッチし、
image.mkファイルで定義されたprepare_generic_squashfs関数を呼び出します。
また、
Cで
記述されたpadjffs2ユーティリティは、イメージファイルの最後に0xDEADCODEマークを書き込みます。
static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; *** static unsigned char *pad = eof_mark; *** t = write(fd, pad, pad_len); if (t != pad_len) { ERRS("Unable to write to %s", name); goto close; }
一般に、OpenWRTの世界は美しく、特に次のようなコメントがすばらしいです。
#これらのテンプレート内で本当の魔法が発生します
または
/ *元のドライバーからのvodoo * /
結論として、OpenWRTをソースからビルドする場合、ビルド環境に注意を払う必要があります。たとえば、Debian 8 + Sidの
このリポジトリでは、クロスコンパイル用のツールセットもビルドされません。 しかし、Debian 7では、初期設定を編集しない限り、このすべての富は驚くべきものになります。 修正すると、アセンブリスクリプトがソースコードをダウンロードするWebソースの一部が既に「腐敗」しており、新しいソースを探したり、スクリプトを修正したりする必要がある場合があります。