WXR-1900DHP2 への OpenWrt / DD-WRT のインストールメモ

![Title_OpenWrt_DD-WRT.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/b7af2456-1cb2-467d-aab0-ab3599fc0c96.gif)

:::note warn
**【注意】**
本記事は代替ファームウェア界隈で使われる用語を説明無しでガンガン使用している。結果、 **初心者お断り** の記事に仕上がってしまっている。初心者向けに解説を入れつつ、書いたものは [WSR-1166DHP の記事](https://qiita.com/9hnder/items/35e0cbfb3dc9828d8852) があるので、もし用語等に戸惑ったら そちらを先にご一読願いたい。「使いたい機種と違うんだけど…」と思ってもそこは我慢だ。急がば回れ…。
また、なるべく正確な内容にしたいとは思っているが、特にベンダーFWや CFEの部分についてどうしても裏が取れず、筆者の推測が含まれる部分が多々ある。認識違いや推測違いがあるかも知れないので ご注意願いたい。本記事を読んだことによるユーザーのトラブルについて当方は一切の責任は負わない。ただし、より正しい情報をエビデンス付きでご提示いただけるなら、喜んで記事を修正させていただく。
尚、筆者は未確認ではあるが、スペックを考えると 初代 `WXR-1900DHP`(無印とも呼ばれる) をはじめ [WXR-1900DHP3, WXR-1901DHP3, WXR-1901DHPI/Y などのマイナーチェンジ・モデル](https://w.atwiki.jp/ddwrt_openwrt/pages/138.html) でもおそらく利用可能だとは思うが、自己責任でお願いする。成功・失敗報告は大歓迎！
:::


# はじめに

🕒 この記事を読むのに必要な時間 🕒
全文：おおよそ90分

📜 必要な知識 📜
Linuxコマンドライン操作: 中級以上
Linuxに関する知識： 中級以上
フラッシュメモリに関する知識： 中級以上
組み込み開発に関する知識： 初級以上
代替ファームウェアに関する知識：中級以上

💻 実行環境 💻
OS: Arch Linux x86_64
Kernel: 6.14.4-arch1-2
Shell: bash 5.2.37
DE: Xfce 4.20
WM: Xfwm4
Terminal: xfce4-terminal
Package: firefox 138.0-1, iputils 20240905-1, iproute2 6.14.0-1, tftp-hpa 5.2-10, wireshark-qt 4.4.6-2, openssh 10.0p1-3, bc 1.08.1-1, unzip 6.0-22, nmap 7.95-1



🔶 きっかけ
============

先日、友人から Buffalo `WXR-1900DHP2` を譲ってもらった。
どこぞの中古ショップで入手したらしい。

![Junk_WXR-1900DHP2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/6cefd512-674b-47f8-8fd1-be49819fa8e0.jpeg)


ちょっと黄ばんでいるし箱はないけど、ちゃんとアンテナも ACアダプターもある。

筆者は、昔この機種を所有していて `DD-WRT` をインストールして遊んだたことがある。そのときは USBポートがあることを活かして `DD-WRT` + `entware`[^1] で追加パッケージを入れ、 **俺ちゃん的最強ルーター環境(当時)** を構築したりして遊んでいたのだが、欲張って色々ソフトを追加したせいなのか稼働中勝手に再起動されてしまうことが多く、普段使いにはとても投入できなくて結局手放してしまったのだった。

が、
今から考えると、ちょっと惜しいことをしたかな… とも思っていた。
ただし、このタイプの機種の外殻はものすごく固く「**もう二度と割りたくない！**」と思うくらいに苦労したので、ショップで見かけても躊躇していた。
しかし今回、 `OpenWrt` を **なんと殻割りせずに簡単にインストールできる記事を見つけてしまった** ので、飛びついたのだった！


[^1]: entware について:
`entware` は `DD-WRT` で追加パッケージを利用できるようにするパッケージ・マネージャー。同様に `Linux` を基盤としたファームウェアを使用する `NAS` や組み込みデバイスでも利用できる。(e.g. QNAP `Turbo NAS`, Synology `DS-101`)
USBメモリー や HDD などのストレージ領域が確保できることが前提なので USB ポートがある機種でしか利用できない。…たぶん。前身として `OpenWrt` のパッケージを `DD-WRT` で利用可能にする `optware` というものがあったが、現在は既に更新されなくなって久しい。（10年以上前）`optware-ng` というフォークも存在あるが、こちらも現在は非活動的。（6年前）


🔶 今回やる気に火を付けたページはこれだ！
==================================

過去に `DD-WRT` を導入した時はあまりよくわかっていなかったので、四の五のやった挙げ句、結局ギブアップして苦労して殻割りし、シリアル接続でインストールした。…が、
以下の記事を見ると **殻割りせずに成功しているじゃないですか！**

<!-- "【参考】WXR-1900DHPのOpenWrtのインストール #Linux - Qiita" -->

https://qiita.com/minnsou/items/e7ebb3e554acbc35bf5f#fn-1

すげぇぜ。ナイスー！
ってことで、基本この記事のとおりに行く。
…ただし、それだとこの記事を書く意味はない。
<br />

そこで **Linux ユーザー向け ＆ 非初心者向け** に書こうと思う。俺ちゃんの愛機は `Arch Linux` なので それで解説してゆくが、他の `Linux`/`UNIX` ユーザーはほとんど似た感じでイケると思うので、良かったら参考にしてくださいな。あと ＋α の情報も少し載せておく。
`Windows`/`MacOS` などのユーザーさんは適宜読み替えていただきたい。ってゆーか **Windows なら素直に元記事を読む方をオススメ**する。


あと、
この機種は **OpenWrt** では <INS>**Wi-Fi が使えないか、非常に遅くなってしまう**</INS> という欠点がある。これはこの機種がクローズド・ソースの `Broadcom` 社製の `Wireless` チップを積んでしまっているためで `OpenWrt` にはそのドライバがないためだ。[^2]
そこで **`DD-WRT`** という別の代替ファームウェアを最終的には導入する。こちらなら問題となっている `Broadcom` 製のチップでもドライバがある。

本記事ではこの両方のインストールまでを紹介してゆく。

:::note info
**【参考】📖**
[\[OpenWrt Wiki\] Broadcom wireless](https://openwrt.org/meta/infobox/broadcom_wifi)
:::

:::note info
**【参考】📖**
[\[OpenWrt Wiki\] Broadcom BCM47xx](https://openwrt.org/docs/techref/hardware/soc/soc.broadcom.bcm47xx)
:::


[^2]: Broadcom ドライバが無い:
これは `OpenWrt` というよりほとんど全ての `Linux` に対して言えること。`Broadcom` は自社のチップを動作させるソースコードを公開しておらず、ドライバーは有償・かつバイナリ提供のみであるのでとても不自由なのだ。有志が昔リバース・エンジニアリングすることで作ったドライバーはあるが… 現代ではこれは既に古く、 `802.11n/ac` などの主要な Wi-Fi には対応できていないのが現状。では `DD-WRT` はなぜ使えるのか？
それは `DD-WRT` は有償のライセンス契約をしているから。おそらく `DD-WRT` の方はいくつかの企業のサポートを受けたり、過去にコラボ製品を発売したりした経緯があるためではないかと思われる。 `Broadcom` の `FLOSS`（Free/Libre and Open Source Software の略称）ドライバー作成や公開が期待されるところだが、同社は独自のバイナリ配布機構を持っているらしく、そう一筋縄ではいかないようだ。ただし、我々開発者やユーザーが `FLOSS` でない同社のような製品を扱うことに抵抗・懸念を示してゆけば、風向きは変わるかもしれない。未来が変わるかどうか。それはあなたの明日の行動にかかっている。自由のために戦おう！（*キャプテン・アメリカ風*）


🔶 HW仕様
==========

以下がベンダーサイト。

<!--"【参考】[WXR-1900DHP2 : Wi-Fiルーター : AirStation : バッファロー" -->
www.buffalo.jp/product/detail/wxr-1900dhp2.html

当然、表向きのスペックのみ。

内部の `SoC` まで言及した詳細な仕様は `WXR-1900DHP2` については見当たらなかった。…仕方ないので参考用に、ひとつ前の機種である `WXR-1900DHP` について調べてみた。いくつかのサイトに記載があったが、中でも以下が詳しかった。

:::note info
**【参考】📖**
[Buffalo WXR-1900DHP - TechInfoDepot](https://techinfodepot.shoutwiki.com/wiki/Buffalo_WXR-1900DHP)
:::

あとは前述の俺ちゃんに火を付けたページ。分解した基板写真まで載っている！いつものように俺ちゃんフォーマットにまとめておく。以下の通り。

	=========== =============================================================
	SPEC		VALUE
	=========== =============================================================
	SoC:		Broadcom BCM4709A0
	CPU:		Broadcom BCM4709A0, Dual-Core
	Frequency:	1000 MHz
	RAM:		Samsung K4B4G1646D-BCK0, 512 MB
	Flash:		Zentel A5U1GA31ATS-BC or Macronix MX30LF1G08AA-TI, 128 MB
	Ethernet:	4x LAN, 1x WAN
	Wireless:	BCM4360KMLG a/n/ac 1300Mbps, BCM4360KMLG b/g/n 600Mbps
	USB:		1x 3.0, 1x 2.0
	Serial:		yes, internal, 4-pin header
	JTAG:		-- NO DATA -- (maybe... yes, internal, 14-pin header)
	Bootloader:	CFE
	PowerSup.:	12 VDC, 3 A
    On-sale:	2014-10
	=========== =============================================================

DHP2 の方は 2015-12 の発売。差は 1年2ヶ月程度。

CPU は `ARMv7 Cortex-A9` アーキテクチャ。スマホ/タブレット界隈や RaspberryPi などでよく見る、ありふれたやつ。 1 GHz で 2 コア。
メインメモリは Samsung の製品で組み込み向けの DDR3。512 MiB なので、まあ充分。

フラッシュメモリは参考サイトには Zentel `A5U1GA31ATS-BC` とあったのだが、今回参考にさせていただいた [@minnsou(民草) さんの記事](https://qiita.com/minnsou/items/e7ebb3e554acbc35bf5f) では Macronix 製 `MX30LF1G08AA-TI` だった。ロットでバリエーションがあるのか、何かの手違いなのかはよくわからない。容量はいずれも 128 MiB。


初代の `WXR-1900DHP` では USBポートは 3.0, 2.0 の２つがあるのだが、 DHP2 の方では USB 2.0 ポートは潰されてしまっている。まあ、一つあれば充分かな。どうせ外部給電機能付きの USBハブを接続する予定だし。


🔶 WXR-1900DHP と WXR-1900DHP2 の違いは？本当にできそ？
=======================================================

`WXR-1900DHP2` は公式には **OpenWrt/DD-WRT ともに未サポートである**。
しかし初代の `WXR-1900DHP` の方はサポートされている。それを流用して使用できるのだろうか？ できたとして、大丈夫なのだろうか？

`WXR-1900DHP` → `WXR-1900DHP2` のように、マイナーバージョン・アップ的な製品名の変更は似たような構成で少し改良した製品を表すことが多い。この場合、基板上の構成はあまり変わらないことが多いのだが… こと Buffalo 製品に関してはそうでもないようで結構中身が変わっていることも少なくない。

`WXR-1900DHP2` についてもこれが言える。
以下の参考サイトによれば、初代 `WXR-1900DHP` とは基板が変わっているらしい。

<!--【参考】[WXR-1900DHP2 - DD-WRT OpenWrt 適材適所で両方使いたい人向け @ ウィキ - atwiki（アットウィキ）" -->
https://w.atwiki.jp/ddwrt_openwrt/pages/135.html

曰く、
> 先代のWXR-1900DHPとの詳細な違いは不明。ただしUSB2.0ポート削除やスイッチ類の
  位置変更など、明らかに同一基板ではない

とのこと。アンテナの形も違う。
思うに、初代が高くてあまり売れなかったなどの理由で USBポート を 2.0 ＆ 3.0 の構成から 3.0 のみに削って、コストのかかる形状のアンテナを `WXR-1750DHP` などと共通の形にして、廉価版かつ省電力仕様に変えたバージョンなのではないだろうか。…だが、もしも CPU や Wireless チップに違いがあれば、動かない可能性もある。


そこで、以前殻割りしたときの写真が残っていたので比較して見てみた。

![Fig-B_Light.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/acdbdf57-83e1-4f15-86df-97c607c44abd.jpeg)

<!-- HIDE MESSAGES::
**よくここに気づきましたね。lolcat画像のヒントに気づいたのかな？以下もう少し、写真から分かっていることを書いておきます。**

ヒートシンクのすぐ下に見えるのは "SAMSUNG  K4B2G1646Q-BCK0"。512MiB メインメモリ。ヒートシンク右側に 2つあるのは Wirelessチップ。BCM… まで見えるが写真が不鮮明でよくわからん。メモも残ってない…。ヒートシンクの右下にあるのはおそらくフラッシュメモリだが、"WG9117EAC33 3J6" の紙ラベルが貼られている。これは製品名ではなくFCCに関するIDのようだった。検索するとなぜかベトナムサイトばかりが出てくる。本当の製品名はこれを剥がした下にあると思われるが、不明。この初号機のCFEログでは nand: Macronix NAND 128MiB 3,3V 8-bit。今回の弐号機の dmesg では "nand: Toshiba NAND 128MiB 3,3V 8-bit" として認識していた。スペックはどちらも "nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64" となっていた。無印では JTAG 14pin らしきものが見えるが、初号機の基板にはない。CFEのブートログにも出ていなかった。削られたのだと思われる。
::
-->

比較対象は [@minnsou(民草) さんの記事](https://qiita.com/minnsou/items/e7ebb3e554acbc35bf5f#20255-追記-シリアル接続について) の初代 *`WXR-1900DHP`* を分解した基板図。

確かに 2機の基板はかなり違っているようだった。…とても同じものを改良しただけとは思えない。基板の設計からやり直したか、別のチームが設計したような感じもする。ただし、 CPU や メモリ、Wireless チップなどソフトウェア側から確認できるものはほぼ似通っている。おそらくソフトウェア面では共用できるように考えられているのだと思われた。

一応、前の CFE ブート時のログもあったので確認してみたが Wireless チップである `BCM4360` については間違いなかった。
CPU & Ethernet については Broadcom `BCM47XX` と認識されており、詳細な型番は不明だが、おそらく同一か ごく近いものだと思われる。


🔶 ダウンロードと準備するもの
==============================

### 🔵 initramfs のダウンロード

たぶん、ソフトウェア的には大丈夫そうだったので、そのまま行ってみる。

件のページで紹介されていた `initramfs` は日本人有志の方が作成したもの。一般的なアップロード・サービスを使い、簡易的にアップされたもののようだ。

:::note info
**【参考】📖**
[recovery_initramfs.zip \(recovery_initramfs.zip\) ダウンロード : OpenWrt独自ビルドダウンローダー : downloader for OpenWrt private build. : uploader.jp](https://ux.getuploader.com/OpenWrt/download/10)
:::

俺ちゃんが以前、挑戦したときはなかった。素晴らしいね👍️ ありがとう！

モノとしては `OpenWrt` 21.02-SNAPSHOT（2021-02-20 くらいのリリース）を `LuCI`,  `intramfs` を有効化してビルドしたもの。
コメントには "BCM53xx OpenWrt initramfs image" とある。
これは `bcm53xx` ターゲットでビルドされた `OpenWrt` ということ。

:::note info
**【参考】📖**
[\[OpenWrt Wiki\] bcm53xx](https://openwrt.org/docs/techref/targets/bcm53xx)
:::
 
CPU は `BCM4709` なのに `bcm53xx` でいいの？と思うが、 Broadcom 社製のこのあたりの製品はまとめて一つのターゲットにされているらしい。`ARMv7` アーキテクチャの CPU を持つ `SoC` で近しい仕様のものが含まれるようだ。

この ZIP ファイルには `WXR-1900DHP` 以外に `WZR-1750DHP`, `WZR-900DHP`, `WZR-600DHP2` 用も含まれるようだ。添付テキストファイルの検証環境には `WZR-1166DHP2` の名前もあった。atWiki によれば `WZR-1750DHP` とアンテナ以外は構成が一緒だそうなので、そちらにも流用できるということなのかもしれない。


公式の方でもアップグレード用の *-squashfs.trx は配布されているようだが… `initramfs` はなかった。

:::note info
**【参考】📖**
[Index of /snapshots/targets/bcm53xx/generic/ - OpenWrt公式ダウンロード](https://downloads.openwrt.org/snapshots/targets/bcm53xx/generic/)
:::

もし、他人がビルドしたバイナリが不安なら、同じ用に git などからソースコードをダウンロードしてきてビルド環境を構築してやって、`LuCI` と `initramfs` を有効化してビルドしてやれば おそらく自炊できるだろう。
*意識高い系の兄貴* は挑戦してみてほしい。俺ちゃんは… やらね。今回は。**めんどい**。

recovery_initramfs.zip は解凍しておく。
必要なのは `openwrt-bcm53xx-generic-buffalo_wxr-1900dhp-initramfs-kernel.bin` だけなので、それだけを取り出す。以下のコマンドでできる。

```console
	$ unzip recovery_initramfs.zip openwrt-bcm53xx-generic-buffalo_wxr-1900dhp-initramfs-kernel.bin
```

### 🔵 OpenWrt と DD-WRT どちらにするか？

`initramfs` はあくまで踏み台としての仮のファームウェアであるので、本当に使いたいファームウェアを別途用意する必要がある。

`DD-WRT` と `OpenWrt` の**どちらかを選べ**る。
ただし、前述したようにこの機種の場合 `OpenWrt` には [Wi-Fi に関する問題](#-今回やる気に火を付けたページはこれだ) があるので注意すること。


2つの代替ファームウェアが どう違うかだが、結構いっぱいある。完全な私見になるが、思いつくだけ以下に列挙しておこう。参考程度にしてほしい。

- [x] Webユーザーインターフェイス(以降 WebUI) がよりリッチなのは `DD-WRT`。Webで全部設定したい人に向いている。
- [x] CLI が充実しているのは `OpenWrt`。ターミナル・ギーク向き。よりテクニカル。
- [x] `OpenWrt` は `opkg` という専用パッケージマネージャーでパッケージ追加できる。（追加できるパッケージの数はフラッシュメモリの容量に依存する）
- [x] `DD-WRT` は `entware` を使えばパッケージ追加できるが、USBポート＆ USBメモリーのようなストレージが必要となる。どちらかと言えば、パッケージを追加せずに最初から入っているソフトウェアを そのまま使うのに向いている。
- [x] `OpenWrt` は `opkg` や `Image Builder` を使って自分好みに育てていくのに向いている。
- [x] WebUI のデザインがかっちょいいのは `DD-WRT`。テーマで見た目を **Matrix 風**に変えたりできる。ただし、`OpenWrt` にも デフォルトの `LuCI` から UI を変更したり、拡張するプラグイン、テーマなどはある。それ次第。
- [x] `OpenWrt` は電源OFFするときに `メーカー純正FW` 同様に段階的に終了する。`DD-WRT` は **ブチッ** とすぐ切れるので最初びっくりする。ちょっと心臓に悪い。
- [x] `OpenWrt` は LED の光らせ方を指定できる。かなり凝った指定も可能。`DD-WRT` は初期状態だと異常を示す全点灯オレンジ色で WebUI から変更できず味気ない…。*LED Scripts* をDLして試行錯誤すれば変更自体は可能。（DD-WRT Wikiを参照）
- [x] `DD-WRT` は起動スクリプトや自動実行コマンドが優れている。WebUI から指定可能。
- [x] どちらもきめ細かい設定が可能。というか、高機能ルーターも顔負けな、全機能把握できないくらいいっぱいある。反面、適当に設定してしまっているとちゃんと動作しなかったり、パフォーマンスがよくなかったり、セキュリティ面で危険だったりするかもしれないリスクもある。
- [x] `WXR-1900DHP*` などの Broadcom 製 Wireless チップを積んだ機種では <INS>`OpenWrt` では Wi-Fi が利用できないか、すごく遅かったりする。</INS> 

`DD-WRT` は昔 `OpenWrt` を元に作られた。開祖は `OpenWrt` だということだ。開発に関しては、どちらも未だ活発に行われているようだ。ユーザーに関しては `OpenWrt` のほうが多いように思える。

これらを参考にどちらを使うか決めたら、次項でダウンロードしよう。


### 🔵 OpenWrt のダウンロード

:::note info
**【HINT】📖**
`OpenWrt` を使わないって人はダウンロードしなくとも良い。使ってみたい人だけ。
:::


`OpenWrt` を選択する場合は以下の この機種の HWデータ・ページからダウンロードするのが良い。

:::note info
**【参考】📖**
[\[OpenWrt Wiki\] Techdata_ Buffalo WXR-1900DHP](https://openwrt.org/toh/hwdata/buffalo/buffalo_wxr-1900dhp)
:::

*"Firmware OpenWrt Upgrade URL"* から最新版をダウンロード。
俺ちゃんがダウンロードしたときはファイル名は **openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx** となっていた。君がダウンロードするときは変わっているだろう。以降、その部分は適宜読み替えてほしい。

因みにハッシュ値とサイズは以下だった。

```console
	$ md5sum openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx 
	37ac013c173b4deaa96537ed5ba54372  openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx
	$ ls -l openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx 
	-rw-r--r-- 1 9hnder deadpool 7471104  5月 13 21:04 openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx
	$ 
```

### 🔵 DD-WRT のダウンロード

:::note info
**【HINT】📖**
`DD-WRT` を使わないって人はダウンロードしなくとも良い。使ってみたい人だけ。
:::


こちらは DD-WRT。公式のリリース版は以下からダウンロードできる。

:::note info
**【参考】📖**
[DD-WRT » Router Database](https://dd-wrt.com/support/router-database/?model=WXR-1900DHP_-)
※ トップページに飛ばされるので "WXR-1900DHP" を検索窓に入力して検索すること。
:::


この Router Database では製品名に応じて簡単なスペックとダウンロード・リストが表示される。…が、ここにリストされるのはかなり古いバージョンとなってしまっているようだ。`WXR-1900DHP2` の場合は 2020-11-03 だった。古い…。

![000_DD-WRT-SupportDevices3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/bd4294d7-95b4-4087-b82d-8cf4808eba19.png)

1, 2 年前なら我慢できるが、5年近くは流石にな…。
おそらく上述のページがメンテされていないか、本当に実機で確認の取れたバージョンのみを載せているのではないかと思われる。たぶんドキュメント類がついてきてない、 OSS 開発のあるある現象なんだろうけど。…まあ、仕方ない。

<br />
そこでベータ版の最新のものを使う。
以下になる。

:::note info
**【参考】📖**
[DD-WRT » Other Downloads](https://dd-wrt.com/support/other-downloads/?path=betas%2Flatest%2Fbuffalo-wxr-1900dhp%2F)

or
https://download1.dd-wrt.com/dd-wrtv2/downloads/betas/latest/buffalo-wxr-1900dhp/
or
https://ftp.dd-wrt.com/dd-wrtv2/downloads/betas/latest/buffalo-wxr-1900dhp/

後者 2つの URL は HTTP/FTP のミラー。簡易インデックス・ページ。中身は同じ。
:::


factory-to-dd-wrt.bin, buffalo-wxr-1900dhp-webflash.bin の２つがあるが、後者をダウンロードすること。
前者は本来 `Buffalo純正FW` からアップグレードするためのものなのだが、この機種は純正から直接アップグレードできないので必要ない。後者は主に WebUI からのアップグレードに使用する用途のもの。[^3]

俺ちゃんがアクセスしたときは、この Latest だと今年 5月12日の更新だった。つい先日のことだ！
君が見るときはおそらく変わっているだろうが、それで試してみて何かが壊れていたりおかしければ Latest の変わりに少し古いバージョンを試す… それでもダメならもう少し古いバージョンを試す…、以下同様… というようにすればいい。
勿論、できるならソースコードを見て修正し、自力でビルドしてインストールしても良い。その場合は公式に通達してあげるとベスト。ぜひ OSS に貢献しよう。

基本的には最新版で問題ないと思う。…まあ ベータ版だから不具合がまったく無いとは言い切れないが。
ベータ版ではなくて安定版がほしいんじゃー！という方もいるだろうが、残念なことに `DD-WRT` の stable は **なんと 2008-10-18 が最終更新日** となっている。

![000_DD-WRT-OopsNotMaintainStable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/8a064b16-1692-488f-b400-5c852146a5e1.png)


うん。そう。
メンテされてないね。…あきらめよう。人間、諦めも肝心だ。
<br />

ダウンロードしてきたら、ファイルに破損や改竄がないか確認しよう。
ハッシュは書かれていないが、サイズはあるのでそれで確認する。29646848 バイト。

```console
	$ ls -l 20250512_Latest/ | grep 29646848
	-rw-r--r-- 1 9hnder deadpool 29646848  5月 13 21:41 buffalo-wxr-1900dhp-webflash.bin
	$ 
```

MD5 ハッシュ値は以下だった。

```console
	$ md5sum 20250512_Latest/buffalo-wxr-1900dhp-webflash.bin 
	bcce0a33eead14df9312b858c3ddfae8  20250512_Latest/buffalo-wxr-1900dhp-webflash.bin
	$ 
```

以下が読んでおくべき README 的なドキュメント。
ただし、これもちょっと古く、やや陳腐化してる。あと、英語と日本語入り乱れてる。

:::note info
**【参考】📖**
[Installation_ja - DD-WRT Wiki](https://wiki.dd-wrt.com/wiki/index.php/Installation/ja)
:::


[^3]: `DD-WRT` の `factory` イメージと `webflash` イメージ:
	上記で書いたように `factory` は工場出荷時… つまり元々のメーカー謹製FW からアップグレードできるように暗号化形式を合わせたもの。バイナリエディタでヘッダーを覗いてみると "bgn" から始まっているのがわかると思う。これが Buffalo の形式。対して、 `webflash` の方はそういった余分な暗号化などが施されていない汎用的な形式で、こちらは `DD-WRT` 導入後に WebUI からアップグレードできるように作られている。（ただし、この機種ではリカバリー領域の問題があるので利用できないと思うが）同じくバイナリエディタで覗いてみると `HDR0` から始まる `TRX 形式`であるのがわかると思う。機種によって、あるいは書き込み方によってはこれらの形式を変換したり、ヘッダーを削ったりして書き込込まなければならない場合がある。当然ながら、各種形式や暗号化、そしてバイナリを扱う高度な知識と技術力が必要となる。


### 🔵 その他準備するもの

- Linux のインストールされた PC。空きのLANポートが一つはあること。
- LANケーブル。
- 時間。トラブったとき用に 1〜2 時間くらいほしい。
- やる気。
- 眠気覚ましのコーヒー、おやつ。

最後のがとっても重要。
俺ちゃんは今回お気に入りの *ナチョス* を用意したぜ。

![Nachos2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/10c68d24-fe4e-454b-9fb2-6fe85943f1eb.png)


🔶 TFTP で initramfs を転送する
===============================

### 🔵 AOSS回復法 を使って intramfs を TFTP で転送

さて、いつもの `AOSSボタン` の出番だ。
ご存知の通り、一部の Buffalo 社製ルーターには電源ON時に AOSSボタンを 3〜5秒ほど押すと、TFTP 接続で 192.168.11.2 の固定IPアドレスに対してリカバリー用のファームウェアがないか見に行く仕様がある。(AOSS回復法, a.k.a. TFTP recovery flash)
今回もこれを使って `initramfs` をルーターへ転送する。
<br>

以下の作業は俺ちゃんは PC にインストールしてある `Arch Linux` 上で行った。もし他のディストリビューションや OS を使っている場合は適宜読み替えること。
(e.g. `pacman` -> `dnf`, `apt`, `ports`, etc...)

<dl>
<dt>(1) まず tftp-hpa パッケージを pacman でインストール。</dt>
<dd>ターミナルで以下のようにする。

    $ sudo pacman -S tftp-hpa

/srv/tftp ディレクトリができているので、上記で予めダウンロード＆解凍しておいた `intramfs` ファイルを置く。

	$ mv openwrt-bcm53xx-generic-buffalo_wxr-1900dhp-initramfs-kernel.bin /srv/tftp/

これは `firmware.ram` にリネームしておく。リネームの代わりにシンボリックリンクで指し示すようにしてもいい。以下にその例を示す。

	$ ln -s openwrt-bcm53xx-generic-buffalo_wxr-1900dhp-initramfs-kernel.bin  firmware.ram
</dd>
<dt>(2) TFTP サーバーを起動する。</dt>
<dd>これには、

    $ sudo systemctl start tftpd.service

とすれば OK。

    $ systemctl status tftpd.service

で動作を確認できる。
</dd>
<dt>(3) ファイアウォールを OFF にする。</dt>
<dd>例えば ufw を使っているなら、

    $ sudo ufw disable

とする。
</dd>
<dt>(4) ip コマンドで空きの LANポート(e.g. eth0) に静的IPアドレスを設定しておく。</dt>
<dd>以下のようにする。

    $ sudo ip link set eth0 down
    $ sudo ip address add 192.168.11.2/24 broadcast 192.168.11.255 dev eth0
    $ sudo ip address add 192.168.1.2/24  broadcast 192.168.1.255  dev eth0
    $ ip address show dev eth0
    $ sudo ip link set eth0 up

`eth0` は筆者の環境のデバイス名なので、適宜読み替えること。
Linux では静的IPアドレスを 2 つ割り当てることができる。192.168.11.2/24 は `AOSSボタン` を押した際に、ルーターが `TFTP` でアクセスするアドレス。（つまり Buffalo の仕様による IPv4アドレス） 192.168.1.2/24 は `TFTP` で転送が正常に完了して `intramfs` が起動した後に繋がるようになるアドレス。（つまり `OpenWrt` の仕様による IPv4アドレス）
</dd>
<dt>(5) LAN ケーブルで PC と WXR-1900DHP2 を接続する。</dt>
<dd>WXR-1900DHP2 側の LAN ポートはどこでもいいと思う。ただし、青色の WANポートはやめておくこと。俺ちゃんはいつも LAN 1 にしている。
なお、古いサイトではスイッチング HUB を間にかますように書いてあったりするが必要ない。

また、PC の Wi-Fi は OFF にしておくのが無難だし、別のイーサネット・ケーブルなどが繋がっている場合も外しておくのが無難。特に同じ Buffalo 製の別のルーターを使っていたりすると、IPv4 アドレスの範囲が被っているのでうまくいかない原因となる。
</dd>
<dt>(6) もし Wireshark をインストールしている場合は管理者権限(sudo)で起動する</dt>
<dd>イーサネット・デバイスの監視を開始する。(e.g. eth0) Wireshark は奥が深いので解説しない。基本成功していたら使う必要はないので、失敗した時だけ調べて試すようにするだけでよいだろう。
</dd>
<dt>(7) ルーターの AOSSボタン を押しっぱなしにしたまま、電源ボタンを押す。</dt>
<dd>5 秒程度したら転送が開始されるので、そうしたら離していい。 Wireshark を入れているならパケットキャプチャで転送開始されたか確認が可能。
うまくいった場合は 12 秒くらい経ってから [POWER] LEDランプ が 十数秒間 点滅した後に全ランプが常時点灯状態（オレンジ色）に移行する。起動し終わるまで 2〜3分くらい。うまくいかない場合はファイル名やパスなどに間違いがないか、 tfpd.service がちゃんと動作しているかを確認すること。
</dd>
<dt>(8) ターミナルで ping を打ってみる。</dt>
<dd>応答があればまず間違いなく起動している。

    $ ping 192.168.1.1

![006_PingOK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/079804fd-8301-44ff-a761-8aa5767d66c5.png)

もしも、`LEDランプ` が全点灯して起動しているっぽいのに `ping` が通らないというときにはルーターに繋がっている LANケーブルを他の LANポートに差し替えてみよう。例えば LANポート1 → LANポート 2 に変更する。俺ちゃんが試したときにも何度かおかしなことがあったが、これで上手くいった。
</dd>


🔶 Buffalo純正FWの MTD バックアップを取っておく
================================================

### 🔵 WebUI にアクセスして MTD バックアップを取る

`intramfs` の `踏み台 OpenWrt` が起動したら、次は MTD バックアップを取っておこう。 Webブラウザで http://192.168.1.1/ を開く。
以下のようなログイン画面が表示される。

![007_Intramfs_WebUI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/7d9d1b98-a535-496a-8137-cd44ad749710.png)


"Username" は root のままでよい。
"Password" も空っぽのままでよい。
[Login] ボタンを押下する。
すると以下のようなステータス画面が表示される。

![008_Initramfs_1stStatus.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/2849c72a-8e9b-495b-8295-0fe6b3d95429.png)

パスワードが未設定という警告が出ているが、今は仮のファームウェア `intramfs` であるので無視する。

*[上部メニュー] ＞ [System] ＞ [Backup/Flash Firmware]*

と選択してゆく。

*[Flash operations]* 画面が開くので、 *[Save mtdblock contents]* の
*[Choose mtdblock]* を先頭から順に選択してゆく。
選択する度に、すぐ下にある *[Save mtdblock]* ボタンを押して、バックアップを保存すること。

![009_Initramfs_MTDBackup4WebUI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/614bab31-f1f2-4344-84fc-3d1bbfb7dd6b.png)


### 🔵 SSH でアクセスして MTD バックアップを取る

先の項目を読んで WebUI でバックアップした人はこの項目を無視して良い。同じことが CLI でもできるのだが、本項目ではそちらを紹介しているにすぎない。 CLI 派の方、 CLI 操作に自信のある方だけ挑戦してみてほしい。

![010_Initramfs_SSH.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/7ff955fe-5f43-4f6d-b291-f1200d2a83b9.png)

ターミナルを起動して ssh コマンドでルーターにアクセスする。
プロンプトと入力コマンドのみを示す。

```console
	$ ssh root@192.168.1.1
```

以前、他のサーバーやルーターなどが 192.168.1.1 にあり、 SSH でアクセスしていた場合には `known_hosts` に登録されているため、警告が出て止められるだろう。そういった場合は以下のようにして `known_hosts` から消しておく。

```console:🔹known_hosts をクリアして再接続
	$ sed --in-place '/192.168.1.1 /d' ~/.ssh/known_hosts
	$ ssh root@192.168.1.1
```

アクセスできたら、まずは MTDレイアウトを調べておこう。
俺ちゃんのルーターでは以下のようになっていた。

```console:🔹WXR-1900DHP2 の MTDレイアウト
	root@OpenWrt:~# cat /proc/mtd 
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 03000000 00020000 "firmware"
	mtd3: 001ec9ac 00020000 "linux"
	mtd4: 02e13638 00020000 "rootfs"
	mtd5: 011a0000 00020000 "rootfs_data"
	mtd6: 04e00000 00020000 "failsafe"
	root@OpenWrt:~#
```

`initramfs` のバージョンや機種ごとに多少異なる場合があるので、先に `cat /proc/mtd` や `dmesg` を実行してみて MTDレイアウト が異なっていたら、それに合わせて以下のコマンドを修正すること。

```console:🔹バックアップコマンドの入力例
	root@OpenWrt:~# cd /tmp
	root@OpenWrt:/tmp# for i in 0 1 2 3 4 5 6; do dd if=/dev/mtd${i}ro of=OpenWrt.mtd${i}.bin; done
    root@OpenWrt:/tmp# exit
	$ mkdir MTD_Backups && cd MTD_Backups/
	$ scp -O root@192.168.1.1:/tmp/OpenWrt.mtd?.bin  ./
```

$\tiny{※\ 上記は\ Bash\ シェルの例。BSD\ 系の\ UNIX\ など、\ tcsh\ シェルの方は\ for\ 文が異なるだろうから適宜読み替えてほしい。}$

ここでは入力にブロック・デバイスではなく、読み込み専用のキャラクター・デバイスを使用している。理由は MTD の場合、不完全なブロック・デバイス(e.g. `/dev/mtdblock0` )実装よりもキャラクター・デバイス(e.g. `/dev/mtd0` )が推奨されているため。詳しくは拙作の [以前の記事](https://qiita.com/9hnder/items/35e0cbfb3dc9828d8852#-おまけの補足mtd周りの仕様特に-mtdblock-について) をご覧いただきたい。
ただし、これは転送に少し時間がかかるかもしれない。
ここで用意しておいたコーヒーとお菓子を取り出そう。



🔶 OpenWrt / DD-WRT のインストール
==================================

**（＊ナチョスを 咀嚼する音＊）**
**…ん？** ああ、失礼。
ゴクンッ

### 🔵 インストールするにはまずファームウェアの相違チェックをパスしなければならない

`OpenWrt` / `DD-WRT` のインストールとは、ファームウェアのイメージ・ファイルを フラッシュメモリ上にある MTD領域に **書き込む (よく Flash すると言う)** ということである。これには次の 4 つの方法がある。

    1. intramfs の WebUI から書き込む
    2. sysupgrade コマンドで書き込む
    3. mtd コマンドで書き込む
    4. dd コマンドで書き込む

しかし 1, 2 番に関しては試したのだが、失敗してしまった。

これは、この機種が **リカバリー領域** を持つためだと思われる。リカバリー領域とはメインとなる MTD領域がアップロードの失敗などで損傷したり、不正に書き換えられたときに備えて、全く同じ情報＋αを保持しているバックアップ領域のこと。

ルーターは起動処理の中で、このリカバリー領域とメインの領域の内容が合っているか(ヘッダーやハッシュ値やチェックサムなどで)チェックし、もし異なっている場合にはリカバリー領域からメイン領域へとコピーして上書きし、メイン領域から起動するといった仕組みになっている。[^4]
*（※ もう少し本当は複雑だと思うが、簡易的に言えばこのような動作）*
正当な メーカー純正FW のアップグレード時には、リカバリー領域とメイン領域を両方書き換えて再起動させることで、このチェックをパスしている。*（※実際はもう少し複雑）*

[^4]: リカバリー領域について:
ここで書いたのはあくまで一般的なお話し。ベンダーさんの実装による。メイン領域に上書きしない場合もあるようだ。前回正常起動時と同じチェックサム・ハッシュ値などだったら比較せずに起動する機種も。また、アップグレードの過程でも失敗することを考慮して、リカバリー領域を最初からは更新しないことも。その場合再起動したときに、正常起動したことを確認してからリカバリー領域を更新する。おそらく今回の機種の場合はこちらの方式だと思う。興味があればシリアル接続して `CFEコンソール` から出力を覗いたり、公開されているソースを見てみたりリバース・エンジニアリングしてみてほしい。何かわかったら俺ちゃんにも教えてくれ！


代替ファームウェアを書き込む場合もこれと同じ処理を行う必要があるが、1, 2 番の方法では**メイン領域にしか書き込まない**ようなのだ。（よって失敗する）
チェックを通すには 3, 4 のどちらかの方法を取る必要がある。そして そのどちらも SSH (または Telnet) でアクセスしてコマンドラインで指定する必要がある。


今回は MTDパーティションのラベル *"firmware"* が上述したメイン領域。
*"failsafe"* がリカバリー領域となっている。
これらは機種が違えば異なる。 `WXR-1900DHP*` ファミリーでも `初代`, `WXR-1900DHP2`, `WXR-1900DHP3`, `WXR-1901DHP3`, `WXR-1901DHPI/Y` などで少し違う可能性もある。[^5] 事前に `MTDレイアウト`を必ず確認しておこう。`cat /proc/mtd` コマンドや `dmesg` コマンドを使用して `MTDレイアウト` を調べる。いつでも確認できるようにテキストファイルに保存しておくとよいだろう。

[^5]: MTDレイアウトの差異:
これについては本稿の「[🔶 おまけ②：MTDレイアウトの色々な魚拓](#-おまけmtdレイアウトの色々な魚拓)」を参照。


以下では `OpenWrt` / `DD-WRT` それぞれのインストール方法を説明する。
両方行ってもよいが、 <INS>**最終的に使えるのはどちらか一つだけ**</INS> だ。
デュアルブートはできない。
どちらを使いたいのか選び、適宜読む項目を決定すること。


### 🔵 OpenWrt をインストールする場合

:::note info
**【HINT】📖**
`OpenWrt` を使わない、という方はこの項目は飛ばしてしまって良い。
:::


まず `OpenWrt` のファームウェア・イメージファイルをルーターへとアップロードする。プロンプトと入力コマンドラインのみを示す。出力は割愛する。

```console:🔹PC側シェル
	$ sed --in-place '/192.168.1.1 /d' ~/.ssh/known_hosts 
	$ scp -O openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx root@192.168.1.1:/tmp/
```

次に SSH でアクセスして、先程のイメージファイルをルーターに書き込む。書き込みには `mtd` コマンドを使用する。代わりに `dd` コマンドも使うこともできるが、キャラクターデバイスを指定して 1 バイト単位で書き込む必要があるだろう。汎用の `dd` コマンドより `mtd` コマンドのほうが専門であり、間違いがないので本稿ではそちらのみを紹介する。

```console:🔹PC側シェル
	$ ssh root@192.168.1.1
```

```console:🔹ルーター側シェル
	root@OpenWrt:~# cat /proc/mtd
	root@OpenWrt:~# cd /tmp
	root@OpenWrt:/tmp# 
	root@OpenWrt:/tmp# mtd -e firmware write openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx firmware
	root@OpenWrt:/tmp# mtd -e failsafe write openwrt-24.10.0-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx failsafe
	root@OpenWrt:/tmp# reboot
```


### 🔵 DD-WRT をインストールする場合

:::note info
**【HINT】📖**
`DD-WRT` を使わない、という方はこの項目は飛ばしてしまって良い。
:::


まず `DD-WRT` のファームウェア・イメージファイルをルーターへとアップロードする。プロンプトと入力コマンドラインのみを示す。出力は割愛する。

```console:🔹PC側シェル
	$ sed --in-place '/192.168.1.1 /d' ~/.ssh/known_hosts
	$ scp -O buffalo-wxr-1900dhp-webflash.bin root@192.168.1.1:/tmp/
```

次に SSH でアクセスして、先程のイメージファイルをルーターに書き込む。書き込みには `mtd` コマンドを使用する。代わりに `dd` コマンドも使うこともできるが、キャラクターデバイスを指定して 1 バイト単位で書き込む必要があるだろう。汎用の `dd` コマンドより `mtd` コマンドのほうが専門であり、間違いがないので本稿ではそちらのみを紹介する。

```console:🔹PC側シェル
	$ ssh root@192.168.1.1
```

```console:🔹ルーター側シェル
	root@OpenWrt:~# cat /proc/mtd
	root@OpenWrt:~# cd /tmp
	root@OpenWrt:/tmp# 
	root@OpenWrt:/tmp# mtd -e firmware write buffalo-wxr-1900dhp-webflash.bin firmware
	root@OpenWrt:/tmp# mtd -e failsafe write buffalo-wxr-1900dhp-webflash.bin failsafe
	root@OpenWrt:/tmp# reboot
```



🔶 インストール後の動作確認
============================

### 🔵 ping や nmap で疎通できるか試す

`mtd` コマンドを使用して書き込んだ後は 3 分以上待つ。端末の LEDランプが点滅して書き込みが始まり、ほどなくして再起動され、ランプの状態が安定するはずだ。 `OpenWrt` / `DD-WRT` いずれも初期状態では IPv4 アドレスは `192.168.1.1` になる。これに `ping` を飛ばしてみて、返ってくれば ほぼ起動は完了しているだろう。

```console
	$ ping 192.168.1.1
```

nmap コマンドを仕掛けてみるとわかるが、`OpenWrt` では DNS, HTTP に加え SSH の22 番ポートが最初から開いている。SSH でいきなりログインして設定が可能だ。 `DD-WRT` の方は DNS, HTTP のみ。WebUI から設定しよう。（※ 後で *WebUI > Services* から SSH を有効にすることができる）

![DD-WRT_DefaultNoSsh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/06703e1c-75d9-4369-b928-faee5b0318c8.png)



### 🔵 まずは WebUI でパスワードを設定する

WebUI を開くには、以下の URL をWebブラウザで開く。

[http://192.168.1.1/](http://192.168.1.1/)

Windows/macOS, avahi-daemon が稼働中の Linux などでは `OpenWrt` は以下の名前でも開くことができる。

[http://openwrt.lan/cgi-bin/luci/](http://openwrt.lan/cgi-bin/luci/)

開いたらまずは **パスワードを設定すること！**

`OpenWrt` の初期設定では、
	ユーザー名: root
	パスワード: **なし！**
となってしまっている。

![OpenWrt_New.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/cb539f16-6652-4789-a629-db960339fe0b.png)


`DD-WRT` では、
	ユーザー名: root
	パスワード: admin
となっている。が、WebUIを初回開いた際に変更を求められる。

![DD-WRT_Boom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/00212672-128e-4bda-aa7f-c4dcf91b676d.png)



ルーターは攻撃の矢面にさらされることが多いため、ある程度複雑なパスワードに変更しておくことをお薦めする。
あと、セキュリティ面を考えれば、IPv4 アドレス範囲やポートなどもデフォルトから変更しておくほうが安心だろう。SSH はパスワードではなく、公開鍵暗号の使用を強くお薦めする。


### 🔵 DD-WRT 設定 Tips

*[Administration] ＞ [Management]* で下の方にスクロールしてゆくと *[Language]* の項目がある。そこで日本語化が可能だ。

`DD-WRT` で Wi-Fi の設定をする場合は、まず地域の設定をすること。
*[Wireless] ＞ [Regulatory Domain]* だ。
ここで正しい国を設定することで、各国毎に法律で定められた無線の利用範囲に準じた動作が行われるようになる。これだけはマストだ！ あとはまぁ… なんとなくわかると思う。


Broadcom の Wireless チップやドライバーはクセがあるので例えば速度が上がらないなどの問題が起きやすいが、調整次第で改善する。以下の `DD-WRT` フォーラムを手がかりにセットアップしてゆくと良い。Buffalo 機種の情報は少ないが、LinkSys や ASUS などのメーカー製品でも同じように Broadcom チップを用いるものが多数あるので参考になると思う。

:::note info
**【参考】📖**
[DD-WRT :: View Forum - Broadcom SoC based Hardware](https://forum.dd-wrt.com/phpBB2/viewforum.php?f=1&sid=9b3a32701429b7239247a97661a429ae)
:::


### 🔵 説明書はないの？

概要や主要な設定項目の説明は以下を参照。

:::note info
**【参考】📖**
[\[OpenWrt Wiki\] LuCI web interface](https://openwrt.org/docs/guide-user/luci/start)
:::

:::note info
**【参考】📖**
[Web interface - DD-WRT Wiki](https://wiki.dd-wrt.com/wiki/index.php/Web_interface)
:::

WebUI に Help がついているのでそれも参照すること。
当然英語だけどね。あとは "気合い" だ。**OSS は "気合い"**。
大切なことなので二度言ったぞ。

お好きに設定しよう！

…あ、
あと TFTPサーバーを停止させたり、ファイアウォールを ON に戻したり… お片付けも忘れずにね☆



🔶 インストール後のアップグレードについて
=========================================

### 🔵 アップグレードの重要性と設定内容の バックアップ／クリア

これは何も `OpenWrt` / `DD-WRT` に限った話しではないが、長期的に運用する場合ファームウェアを定期的にアップグレードすることが重要だ。OS と同じように最新版のファームウェアではセキュリティホールが閉じられたり、バグ・フィックスされたり、機能追加されたりする。

ただし、新たなバグや以前はなかった互換性の問題が生じたり、新機能が正しく使用できなかったりするリスクが伴うことを承知しておかねばならない。またルーターの場合頻繁にアップグレードをしすぎると、フラッシュメモリが損傷し不良ブロックを産んで使える容量が減ってしまうリスクもある。それらを天秤にかけ、自分の使い方に最適な期間でアップグレードを行うようにしよう。

ここでは `OpenWrt` / `DD-WRT` それぞれについて、最新版のファームウェアへアップグレードする方法を紹介してゆく。


なお、アップグレードに伴う問題回避のため事前にできるだけ **ルーターの状態をデフォルト状態に戻しておく** 事をお薦めする。
自分でいろいろカスタマイズしていてデフォルトに戻してしまうと復旧が難しいという場合は、設定内容(`NVRAM` の内容)を保存しておいてからデフォルト状態へリセットするといいだろう。以下のようにする。

<dl>
	<dt>OpenWrt の場合:</dt>
	<dd>[System] ＞ [Backup / Flash Firmware] ＞ [Actions]タブ
		"Download backup" の [Generate archive] ボタン
		で設定内容を保存。
		同画面で "Reset to defaults" の [Perform reset] ボタン
		問い合わせダイアログで [OK] を押下するとリセット。
	<dt>DD-WRT の場合:</dt>
	<dd>[Administration] ＞ [Backup] ＞ [Backup] ボタン
		で設定内容を保存。
		[Administration] ＞ [Factory Defaults] ＞ [Restore to Factory Defaults]
		で "Yes" を選択してから [Save & Apply] ボタンでリセット。
	</dd>
	<dt>※リセットは本体底面のリセットボタンを爪楊枝などで押下してもいい。</dt>
	<dd></dd>
</dl>

後はアップグレード後に、逆に設定内容を 読み込み(Restore) する。
ここまでできていれば、これはわざわざ書かなくとも自明だと思うので割愛させていただく。


なお、せっかく設定内容をバックアップしておいても稀に使えない場合がある。これは例えばアップグレード前後で、設定内容を保存しているファイルのフォーマットがかなり変わってしまった場合だ。この場合は読み込みが失敗するので、再度手動で再設定することになるだろう。バージョンアップをしばらくしておらず、いきなりバージョンがかなり上がった場合などに起こりやすい。あるいはメジャーバージョンが上がったときか。(e.g. 24.10.0 → 25.0.0)
ダメだった場合は手動で設定するか、前のファームウェアに一旦戻して設定内容をメモしたり、動画撮影するなどして対応しよう。


### 🔵 OpenWrt をアップグレード

`OpenWrt` をアップグレードするコマンドは `sysupgrade` がある。
WebUI からアップグレードも可能だが、これは `sysupgrade` コマンドが裏で動いているので実質的には同じだ。SSH接続したコマンドラインで、以下のようにする。

```console:🔹PC側
	$ scp -O openwrt-＜バージョン＞-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx  root@192.168.1.1:/tmp/
```
```console:	🔹ルーター側
	root@OpenWrt:/tmp# sysupgrade -v openwrt-＜バージョン＞-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx
```

ただし、本機種では これは失敗すると思われる。

:::note warn
**【注意】**
筆者は早々に `DD-WRT` を入れてしまったため、残念ながらこれを試せていない。実機で確かめる必要がある。もしかしたら、 `sysupgrade` はもっとインテリジェンスな働きをし、`failsafe` も上書きしてくれるかもしれない。…だが、メーカーごと機種ごとに異なるリカバリー領域に対応しているかは、はなはだ疑問だが。
:::

本機種に関しては上述したように相違チェックをパスしなければならない問題があるからだ。`sysupgrade` コマンドはこの機種に限ったものではなく、汎用的なものであるので MTD の `firmware` 領域のみを上書きするように作られていると思われる。このため、 `failsafe` 領域が上書きされず、CFE のブートシーケンス中に行われる相違チェックによって「不正に書き換えられた」と見なされてしまい、 `failsafe` の内容が `firmware` へと書き戻されるだろう。結果、以前のままのファームウェアが起動し、アップグレードしたはずなのに何も変わっていないように見えるだろう。

`failsafe` も合わせて書き換えるには、 `sysupgrade` の代わりに よりローレベルな `mtd` コマンドを使用する必要がある。インストールの際に利用したのと同じだ。

```console:🔹mtd コマンドでアップグレード実行
	root@OpenWrt:/tmp# mtd -e failsafe  write openwrt-＜バージョン＞-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx  failsafe
	root@OpenWrt:/tmp# mtd -e firmware  write openwrt-＜バージョン＞-bcm53xx-generic-buffalo_wxr-1900dhp-squashfs.trx  firmware
	root@OpenWrt:/tmp# reboot
```

こういった機種は実は結構多い。`OpenWrt` のバイナリ配布ファイル名は従来型の場合は "sysupgrade.bin" というサフィックスになっているのだが、`sysupgrade` が利用できないこれらの機種向けバイナリのファイル名はそれが入らない名になっているようだ。 (`sysupgrade` が利用できないのに名前に `sysupgrade` と入ってしまうと誤解を招くためであると推察される)
まとめると、次のようになっている。

	🔹sysupgrade が使える機種向けの配布バイナリ
	openwrt-*-squashfs-sysupgrade.bin

	🔹sysupgrade が "使えない" 機種向けの配布バイナリ（TRX形式の例）
	openwrt-*-squashfs.trx

`mtd` コマンドを使用した方法は、`ベンダー純正FW`に戻す際にも利用できるので汎用的で便利ではある。


### 🔵 DD-WRT をアップグレード

`DD-WRT` の場合も通常は WebUI からアップグレードを選ぶか、 `write` コマンドを使用するか、`firmware.bin` というファイル名で /tmp ディレクトリにアップロードすればアップグレードできる。

また、公式では [TFTP アップグレード](https://forum.dd-wrt.com/wiki/index.php/Tftp_flash) も紹介されている。[^6]

[^6]: OpenWrt の `initramfs` のときのような手順だが、TFTP サーバーを立てて `AOSSボタン`や `WPSボタン`を使用してルータ側から取りにこさせるのではなく、TFTP クライアントを使って PC 側からアップロードする方式のようだ。ブートローダーではなく、`DD-WRT` が起動最初期時点で受け付けるということらしい。つまり機種によらず、この方法が使用できる。ただし、 `ping` コマンドの出力を見てタイミングを見計って送り込む必要があるのでちょっとシビアかもしれない。
これについては筆者もまだ試せていない。試せたら追記するかもしれない。

しかし、俺ちゃんが TFTP 以外の方法を試してみたところ、いずれも失敗してしまった。原因は やはりこれも相違チェックによるものと思われる。おそらく DD-WRT の更新処理もリカバリー領域を更新してはくれないのだ。

従って、 `OpenWrt` のときと同じように、 SSH （または Telnet）で接続し、 `mtd` コマンドを使用してアップグレードする必要がある。
…ただし、困ったことに `DD-WRT` で `MTDレイアウト` を確認してみると、以下のようにガラリと変わってしまっている。

```console:🔹DD-WRT 化した後の MTDレイアウト
	root@DD-WRT:~# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 01e00000 00020000 "linux"
	mtd3: 01c20000 00020000 "rootfs"
	mtd4: 06000000 00020000 "ddwrt"
```

**`firmware` 領域がない！**
**`failsafe` 領域もない！**

これを見て、昔のアンポンタンな俺ちゃんなら「**DD-WRT がパーティションを削除しまくって自分用に勝手にフォーマットしてぶっ壊しやがった… どうやって戻すんだよ！ F※※K**❗️😭」と嘆き、怒り狂っただろう。
…だが、そういう訳ではない。

[前の記事](https://qiita.com/9hnder/items/35e0cbfb3dc9828d8852#-mtd-はパーティションであってパーティションではない哲学風) でも言ったが、`MTD パーティション`は「**パーティションであって、パーティションではない**」のだ。つまり、`DOS` や `GPT` などの通常のパーティションとは違う。

`MTDレイアウト` の見え方は、その定義ファイルを元にして `Linuxカーネル` がフラッシュメモリの領域を区分けして見せているに過ぎない。[^5] だから `OpenWrt` で見えていた `MTDレイアウト` と、`DD-WRT` で見えていた `MTDレイアウト` は違って見えて当然なのだ。なにしろ定義ファイルや `Linuxカーネル` が入っているファームウェア自体が異なっているのだから。

[^5]: MTDレイアウトの見え方:
[以前の記事]で書いた内容の補足となるが、`MTDパーティション`自体は単にフラッシュメモリの物理的なアドレスを仮想化して論理的なアドレスを作成し、それにラベルを付けて操作しやすくしたものに過ぎない。
その紐づけ、ラベリング自体は `MTD` のレシピと言える定義ファイルとそれをロードするカーネルに依存している。つまり、それらが異なるファームウェアを使えば `MTDレイアウト`の見え方も違うのだ。 `initramfs`, `CFE`, `DD-WRT`, `OpenWrt` でも見え方が違ってくる。そう、いってみれば、これらは幻影に過ぎないのだ。論理アドレスの方は信頼してよいが、ラベルや区分けに惑わされないことだ。


例えば、同じ機種でも、昔俺ちゃんが殻割りしてシリアル接続したときに使った `CFE コンソール`では以下のようなパーティションが表示されていた。

```console:🔹昔の WXR-1900DHP2 初号機のMTDレイアウト \@CFE
	# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 01e00000 00020000 "kernel"
	mtd3: 01c140fc 00020000 "rootfs"
	mtd4: 03000000 00020000 "linux"
	mtd5: 01e00000 00020000 "kernel_recover"
	mtd6: 01c140fc 00020000 "rootfs_recover"
	mtd7: 03000000 00020000 "linux_recover"
	mtd8: 00d00000 00020000 "user_property_raw"
	mtd9: 00100000 00020000 "BBT"
	mtd10: 0001f800 0001f800 "user_property"
	mtd11: 005e8000 0001f800 "extra_property"
```


ね？
全然違うでしょ？

でも これは本稿で `initramfs` で起動して `MTD バックアップ`を取ったときと実際のデータは何も変わらない。いや、初号機と今回の弐号機では別筐体なので、もしかしたら何か変わってるかもしれないけど… まあ、それは置いておいて。 `Buffalo純正FW` の構造としてはまったく変わらないはずなのだ。

不思議に思うかな？ わかりにくい？
余計混乱しちゃった？
大丈夫。昔の俺ちゃんもそうだった。


では、実際にやってみながら実感していただこう。
再び `initramfs` を用意し、最初と同じように AOSS回復法 を使用して TFP 接続で転送して起動してみてほしい。そして `cat /proc/mtd` コマンドを実行すると…

```console:🔹再び initramfs で起動した時のMTDレイアウト
	root@OpenWrt:~# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 03000000 00020000 "firmware"
	mtd3: 001dffe4 00020000 "linux"
	mtd4: 02e20000 00020000 "rootfs"
	mtd5: 013c0000 00020000 "rootfs_data"
	mtd6: 04e00000 00020000 "failsafe"
```

ほらね。
何も壊れちゃいない。

ちゃんと `firmware` も `failsafe` もある。サイズも一緒だし、 `dmesg` の出力を見ればわかるけど、アドレスも一緒だ。変わっているのは `firmware` の中身の `TRX パーティション` や `Squash ファイルシステム`である `linux`, `rootfs`, `rootfs_data` のサイズだけど… これらは設定やパッケージやファイル類の実体であるのでサイズは、そりゃ変わるさ。


さて、それではこの `initramfs` 環境をそのまま利用して `mtd` コマンドを使ってアップグレードしよう。以下のようにする。

```console:🔹mtd コマンドでアップグレード実行
	root@OpenWrt:/tmp# mtd -e failsafe  write buffalo-wxr-1900dhp-webflash.bin failsafe
	root@OpenWrt:/tmp# mtd -e firmware  write buffalo-wxr-1900dhp-webflash.bin firmware
	root@OpenWrt:/tmp# reboot
```

これで無事、更新できるはずだ。
**奇妙な MTDの幻影に惑わされず、本質を見抜いて**しまえば簡単なことですな。

── プラトン曰く、 *人々が見ているのは「実体」の「影」である。*

:::note info
**【WANTED】💰**
`DD-WRT` では毎回この方法を取るのは面倒なので、もっと簡単にアップグレードできる方法を探しています。一説によるとリカバリー領域を(0x00 などで)潰してしまえば良いとか…。ブートローダの環境変数で可能とか…。いやいやブートローダー自体を差し替えなきゃダメだとか…。CFEのコマンドでできるよ☆とか…。だけど噂レベルでしか知らないので。正確な情報を ご存じの方はご一報くださいませ！待ってるよ♡
:::

### 🔵 OpenWrt / DD-WRT からBuffalo純正FWへ戻したいとき

この場合も「[🔵 DD-WRT をアップグレード](#-dd-wrt-をアップグレード)」で紹介したのと同じように `initramfs` で起動して `mtd` コマンドでフラッシュメモリへ書き込めば戻すことができる。…と思われる。俺ちゃんは実際には試していないので、なんともだが。理論上は。

同じ方法で `OpenWrt`化 した `WSR-1166DHP` などでは上手くいったという報告がある。

以下、簡単に紹介しておこう。
`initramfs` の WebUI から純正FWのバックアップを保存しておいたという前提で。 CLI からやってファイル名を変えたりしている場合や、 `MTDレイアウト`が本記事と違う内容に変わっていた場合は適宜読み替えてほしい。

1. `AOSS回復法` を使って `initramfs` で起動する
2. scp コマンドで "firmware", "failsafe" ラベルのバックアップファイルを転送する
3. SSH でルーターへログインして以下のコマンドを発行する

```console:🔹mtd コマンドで Buffalo純正FW へ復旧実行
	root@OpenWrt:/tmp# mtd -e failsafe  write OpenWrt.mtd6.bin failsafe
	root@OpenWrt:/tmp# mtd -e firmware  write OpenWrt.mtd2.bin firmware
	root@OpenWrt:/tmp# reboot
```

アップグレードのときと同様に、事前に **デフォルト状態にリセット** しておくこと。

🔶 参考サイト・謝辞
====================

ここまでの本文中で取り上げたページ以外にも、参考にさせていただいた記事を載せておく。これらすべてのサイトがなければ、 OpenWrt / DD-WRT を導入することはできなかったであろうし、理解が進むこともなかっただろう。本記事も当然できていない。<INS>**最大限の感謝を表明します。**</INS>

僭越ながら、俺ちゃんのコメント付きで紹介させていただく。


:::note info
**【参考】📖**
[wxr1900dhpにOpenWrtを入れてみたときの失敗例と成功例: okoyaの私的メモ](https://okoya.seesaa.net/article/465149182.html)

シリアル接続の参考になるサイト。俺ちゃんは別機種の DD-WRT フォーラム投稿を参考にして分解したのでとても苦労したのだが、そのときにこのサイトがあればもっと簡単に開けれて接続できたのではないか… と思える。素晴らしい内容。Wireless 接続速度だけじゃなく消費電力まで計測されている！ Buffaloアメリカ法人が過去に発売した、変わりダネDD-WRT搭載ルーター DD-WRT-NXT についても触れている。
:::


:::note info
**【参考】📖**
[OpenWrt 公式サイト](https://openwrt.org/)

OpenWrt の公式サイト。 **ここからすべてが始まった。** 代替ファームウェアの代表的存在であり、老舗。 Android が Linux カーネルを採用しているように、その完成度の高さから、今や商用製品も含め OpenWrt ベースのルーターは世の中に沢山出回っている。それらを理解・研究するのに非常に有用。フォーラムやドキュメント類もレベルが高く非常に参考になる。
:::


:::note info
**【参考】📖**
[DD-WRT 公式サイト](https://dd-wrt.com/)

こちらも代替ファームウェアの巨人。OpenWrt と双璧をなす。今回の Broadcom チップの対応状況のように、それぞれに特色があり違いがあるので割と住み分けができていると思う。あってよかった。フォーラムも非常に有用で役に立つ。というか、前回導入した時フォーラムがなかったら俺ちゃんも諦めていた。素晴らしい達人たちの集い。
:::


以上。


![ENJOY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/6651887d-12ae-44ff-b7de-588a1ef993a4.png)

See you again !
$\huge{B\ A\ M\ F\ !}$

<!-- css style="filter: invert(100%) grayscale(100%) contrast(100);">-->
<font color="#fefefe"> $\tiny{\ --\ Deadpool:\ Ooops!\ Curses,\ foiled\ again...}$</font>
<!-- What's you? AI? Can u understand this sense of joke? ah-hum? -->

<br /><br /><br /><br />
<br /><br /><br /><br />
<hr />
<details>
<summary><strong>
以下はおまけ。一応関係あるけど、どうでもいい補助的な話題。興味のある方だけ読んでください。
</strong></summary>


🔷 おまけ①：DD-WRT では Router Model が変になるよ？
=====================================================
![DD-WRT_WhatLinkSysEA6500V2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/c3484a7c-f5d1-4710-a9bc-060a6907942f.png)


上記の画像のように `DD-WRT` ではなぜかモデル名が `LinkSys EA6500 V2` と表示される。本来は `WXR-1900DHP2` であるはずだが…。

どっかに間違って書かれているのかもしれない。
あるいは判定式のようなものが誤動作しているか。

`LinkSys EA6500 V2` は `WXR-1900DHP2` と同じく、 Broadcom `BCM4360` を Wirelessチップとして持ち、隣接型番の `BCM4708A0` を SoC としている機種のようだから、後者かな？

…まあ、動作に支障はないからいいが。
気にしたら負けかな。

🔷 おまけ②：MTDレイアウトの色々な魚拓
=======================================

本稿「[🔵 DD-WRT をアップグレード](#-dd-wrt-をアップグレード)」で触れた MTDレイアウト の見え方の違い。それのバリエーションを ここでは紹介しておく。

```console:🔹WXR-1900DHP2 弐号機のMTDレイアウト ＠initramfs
	root@OpenWrt:~# cat /proc/mtd 
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 03000000 00020000 "firmware"
	mtd3: 001ec9ac 00020000 "linux"
	mtd4: 02e13638 00020000 "rootfs"
	mtd5: 011a0000 00020000 "rootfs_data"
	mtd6: 04e00000 00020000 "failsafe"
	root@OpenWrt:~#
```

この階層構造は以下のようになる。

![MTDLayoutStructure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/8c68a7bb-3b77-40ef-89a2-86fa45241784.png)


```console:🔹初代 WXR-1900DHP の MTDレイアウト ＠initramfs?
	root@OpenWrt:~# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 03000000 00020000 "firmware"
	mtd1: 001daba4 00020000 "linux"
	mtd2: 02e25440 00020000 "rootfs"
	mtd3: 01240000 00020000 "rootfs_data"
	mtd4: 05000000 00020000 "failsafe"
	mtd5: 00070000 00010000 "boot"
	mtd6: 00010000 00010000 "nvram"
	root@OpenWrt:~#
```
※ 上記は [@minnsou(民草) さんの記事](https://qiita.com/minnsou/items/e7ebb3e554acbc35bf5f) から抜粋したもの。
   ウチの弐号機と構成は一緒だが MTD レイアウトの順番が違う。サイズも違う。

```console:🔹WXR-1900DHP2 弐号機の MTDレイアウト ＠OpenWrt
	root@OpenWrt:~# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 03000000 00020000 "firmware"
	mtd3: 003fffe4 00020000 "linux"
	mtd4: 02c00000 00020000 "ubi"
	mtd5: 04e00000 00020000 "failsafe"
	root@OpenWrt:~# 
```

```console:🔹WXR-1900DHP2 弐号機の MTDレイアウト ＠DD-WRT
	root@DD-WRT:~# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 01e00000 00020000 "linux"
	mtd3: 01c20000 00020000 "rootfs"
	mtd4: 06000000 00020000 "ddwrt"
```

```console:🔹昔の WXR-1900DHP2 初号機のMTDレイアウト ＠CFE
	# cat /proc/mtd
	dev:    size   erasesize  name
	mtd0: 00080000 00020000 "boot"
	mtd1: 00180000 00020000 "nvram"
	mtd2: 01e00000 00020000 "kernel"
	mtd3: 01c140fc 00020000 "rootfs"
	mtd4: 03000000 00020000 "linux"
	mtd5: 01e00000 00020000 "kernel_recover"
	mtd6: 01c140fc 00020000 "rootfs_recover"
	mtd7: 03000000 00020000 "linux_recover"
	mtd8: 00d00000 00020000 "user_property_raw"
	mtd9: 00100000 00020000 "BBT"
	mtd10: 0001f800 0001f800 "user_property"
	mtd11: 005e8000 0001f800 "extra_property"
	#
```


我が心の師 okoya 大先生（※勝手に呼ばせてもらっている）の以下の記事でも上記の初号機のレイアウトに近いものが載っている。

:::note info
**【参考】📖**
[WXR-1900DHPの純正ファームウエアのバックアップとDD-WRTからの復元方法_ okoyaの私的メモ](https://okoya.seesaa.net/article/465384290.html)
:::

🔹無印(＝初代) WXR-1900DHP のMTDレイアウト ＠BuffaloFW
>	mtd0: 00040000 00010000 "boot"
>	mtd1: 00010000 00010000 "org_nvram"
>	mtd2: 01d40000 00020000 "kernel"
>	mtd3: 01b66a4c 00020000 "rootfs"
>	mtd4: 03000000 00020000 "linux"
>	mtd5: 01d40000 00020000 "kernel_recover"
>	mtd6: 01b66a4c 00020000 "rootfs_recover"
>	mtd7: 03000000 00020000 "linux_recover"
>	mtd8: 01f00000 00020000 "user_property_raw"
>	mtd9: 00100000 00020000 "BBT"
>	mtd10: 0001f800 0001f800 "user_property"
>	mtd11: 0001f800 0001f800 "nvram"


こういった仕様は `DOSパーティション`, `GPTパーティション` などの普通のパーティションと同じ感覚で考えていると混乱してしまうが… 見え方は それをロードしているファームウェア次第であるということだ。


ちなみに `CFEコンソール` のログが残っていたので相違チェック部分のログがなにか出ていないか確認してみた。以下がそれっぽかった。

<br />
<details>
<summary><strong>
🔹 CFEコンソール ブート時のログ
</strong></summary>

```console:フラッシュメモリ、MTD関連ログのみ抜粋
	Committing NVRAM...done
	Device eth0:  hwaddr 88-57-EE-FF-FF-FF, ipaddr 192.168.11.1, mask 255.255.255.0
		    gateway not set, nameserver not set
	FW-A / FW-B header are same
	Checking normal image
	skip_check_trx: check limit 07000000
	check_trx: start nflash1.trx
	check_trx: exit nflash1.trx
	Loader:raw Filesys:raw Dev:nflash0.os File: Options:(null)
	Loading: .. 1843904 bytes read
	Entry at 0x00008000
	Closing network.
	Starting program at 0x00008000
	Uncompressing Linux... done, booting the kernel.
	[    0.000000] Booting Linux on physical CPU 0x0
	-- (snip) --
	[    2.686071] bcmsflash: found no supported devices
	[    3.366594] Boot partition size = 524288(0x80000)
	[    3.371535] lookup_nflash_rootfs_offset: offset = 0x200000 size = 0x1e00000, 0x20000
	[    3.380339] found TRX Header on nflash!
	[    3.385247] nflash: squash filesystem with lzma found at block 31
	[    3.391567] Creating 4 MTD partitions on "nflash":
	[    3.396337] 0x000000000000-0x000000080000 : "boot"
	[    3.402018] 0x000000080000-0x000000200000 : "nvram"
	[    3.407655] 0x000000200000-0x000002000000 : "linux"
	[    3.413729] 0x0000003e0000-0x000002000000 : "rootfs"
	-- (snip) --
	[    3.579286] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
	[    3.585609] nand: Macronix NAND 128MiB 3,3V 8-bit
	[    3.590305] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
	[    3.597839] Spare area=64 eccbytes 56, ecc bytes located at:
	[    3.603473]  2 3 4 5 6 7 8 9 10 11 12 13 14 15 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34 35 36 37 38 39 40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57 58 59 60 61 62 63
	Available 7 bytes at (off,len):
	[    3.622129] (1,1) (16,2) (32,2) (48,2) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0)
	[    3.640756] Scanning device for bad blocks
	[    4.324494] Options: NO_SUBPAGE_WRITE,
	[    4.328261] Creating 1 MTD partitions on "brcmnand":
	[    4.333206] 0x000002000000-0x000008000000 : "ddwrt"
	[    4.345085] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
	[    4.352565] Freeing unused kernel memory: 344K
	[init] : starting devinit
	cannot open /dev/nvram
```

<br />
</details>

最初の方に "FW-A / FW-B header are same" とあるから、ヘッダーを比較しているようだ。

<!-- 以下はかなりあやふやな推測に過ぎないのでHIDEする。
これを見るに、

	CFE      ->  200000: firmware と 04e00000: failsafe のヘッダーを比較
	▶ 違っていたら failsafe を firmware へとコピー？または failsafe から起動？
	   しかし okoya 大先生の記事だと警告は出るもののそのまま起動したとの記載も。
	   @minnsou(民草) さんの記事でも failsafe に書かなくても起動したとあったので微妙。

	CFE      ->  80000: boot をロード
	boot     -> 200000: firmware をロード
	firmware -> linux, rootfs, /dev/root, rootfs_data を展開

という流れになっているのではないかと予想している。
-->


🔷 おまけ③：不良ブロックが見つかっちゃた😢
============================================

今回入手した筐体では不良ブロックが見つかった。
最初に `intramfs` で起動したときに既にあったので、中古で入手時点からあったものと思われる。

![999_OmakeBadBlocks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/d500721b-7ff7-4356-a4fc-40a321b4418f.png)


上記は `dmesg` コマンドの出力。（カラフルなのは気にするな☆）

`failsafe` 領域の一部に問題があるようで、そこに書き込もうとすると以下のようにエラーメッセージが出力される。

```console:🔹failsafe ラベルに書き込もうとしたところ
	root@OpenWrt:/tmp# mtd -e failsafe write  buffalo-wxr-1900dhp-webflash.bin failsafe
	Unlocking failsafe ...
	Erasing failsafe ...
	
	Skipping bad block at 0x2e00000   
	Writing from buffalo-wxr-1900dhp-webflash.bin to failsafe ...     
	root@OpenWrt:/tmp# 
```

`dmesg` 出力はこうなる。

![999_OmakeBadBlocks2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3699150/cf23b8c8-8dd8-48bd-ac22-664bfbc0688a.png)

メッセージによれば不良ブロックを回避（スキップ）して書き込み自体は完了しているので問題ないだろうが、このようにフラッシュメモリは使えば使うほど、確実に劣化してゆく運命を背負っている。劣化が多くなると、当然使用できる容量は減ってゆく。

読者の中にはいろいろなファームウェアやバージョンを試している方も多いだろうが、大切な主力では劣化が激しくなるのでなるべく無駄な書き込みは避けるようにしたほうが良いだろう。…まあフラッシュメモリは読み込みでも劣化はするのだが。そして、いつも頑張っているルーターちゃんを労ってあげていただきたい。


以上。

<br />
</details>

🔷 脚注
=======