
2019年頃に一度まとめ上げたものの、当時サードパーティのU-Boot(U-Boot本家ではない)を使用していた為に投入を見送り作業終了としていたものを復活させて投げ込み、マージされたものです。
まとめていきます。
仕様
いずれも既に10数年前に発売されたAR9344搭載機であり、それ故に全体的な構成は古めです。
法律の関係上、無線機能の使用は非推奨です。
共通
- SoC: Atheros AR9344
- RAM: DDR2 128MiB
- WAN/LAN: 1000Mbps x1/1000Mbps x4
- USB 2.0 Type-A x1
WR8750N, WG600HP
- Flash: SPI-NOR 8MiB
- UART: CN110, 9600bps(三角マークから3.3V, GND, NC, TX, RX)
WR9500N
- Flash: SPI-NOR 16MiB
- UART: 無線チップ付近のパッド4つ, 9600bps(AR8327側から3.3V, GND, TX, RX)
その他詳細については、雑記を参照。
OpenWrt化
諸々の課題を解決出来た為、2段階ではあるもののfactoryイメージを仕立てることができています。
- WR8750N/WR9500N/WG600HPを起動
なお、ルータモードに設定されていることを前提とする http://192.168.0.1/にアクセスし、ファームウェア更新ページに移動- OpenWrtのfactory.binイメージを選択し、更新実行ボタンを押下
- アップデートが完了し再起動後にOpenWrt上にuboot.binとsysupgradeイメージをアップロード(あるいはダウンロード)
uboot.binで "bootloader" パーティションを書き換えてブートローダをU-Bootへ置き換え
mtd write <uboot.bin> bootloadersysupgradeイメージでsysupgradeを実行
sysupgrade <sysupgrade.bin>Flashに書き込み後再起動され、OpenWrtが起動して完了
備考
全てのLEDはSoCではなく無線チップ (AR938x) に接続されており、それ故に無線の認識が完了するまでは制御することができない。この為、OpenWrtのブート中に点滅させることができず、無線チップが認識されるまでは消灯、認識された後は点灯状態となる。
内部USBハブのRESETラインがLED同様に無線チップのGPIOに接続されており、これも無線チップの認識が完了するまで制御できない為USBハブチップがリセット状態に入ったままとなり、USBポートに接続されたデバイスも無線チップが認識されるまで検出されない。
メーカー出荷時に搭載されているブートローダは、ファームウェア領域において特殊なファイルシステムを必要とする。このファイルシステムはOpenWrtで扱うことができず、sysupgradeイメージをFlashからブートすることができない為、initramfsベースのfactoryイメージでブートした際にブートローダをU-Bootへ入れ替える必要がある。
このU-Bootは利用できるパーティションサイズが
0x20000 (=128KiB)に限られる関係上、サイズ低減の為にネットワークサポートやその他様々な機能/コマンドを無効化しており、kernelが破損していて文鎮化した際などの復旧にはloadbやloadxほかシリアルコンソール経由の投入のみが利用可能。また、環境変数領域の保存に使用できるパーティションが存在しない為、saveenvコマンドは利用不可。元のブートローダで設定されている
baudrate=9600bpsでは遅すぎることもあり、U-Bootではbaudrate=115200bpsに設定し、Linux Kernelにもそれを渡すように設定済。なお、元のブートローダからinitramfs-factoryイメージをブートした場合は、9600bpsで表示される。
作業時の色々
とにもかくにも、sysupgradeイメージをどうやってFlashからブートするかの戦いだった。元のブートローダがファームウェア領域でどうしても謎のファイルシステムを必要とし、通常のLinuxベース機と同じようにプレーンなファームウェアを書き込むとエラーになり消し飛ばしてしまう。
どうにかブートする為にそのFSをmtdとして扱うドライバを書いてみたりしたものの、どうにも知識不足で信頼性に欠ける為、2019年頃は pepe2k/u-boot_mod をフォークしてデバイス用の変更を行い、ビルドしたものに置き換えることで対処した。
ただしOpenWrtにおいて、OSSのサードパーティ(OSS本家ではなく改変された外部のコードを使用したもの)は許容しないという暗黙のルールが存在するらしいことから、これに該当してしまうu-boot_modを使用するこの3機種は投入不可と判断し、一度作業終了とした。
しかし結局のところ諦めの悪さが出て、さらにはU-Boot本家でAtheros AR934xもサポートされていることを知り、ならばと2019年当時は諦めたmainline U-Bootでのこの3機種のサポートにトライし、なんとか達成して投げ込み、マージされた。U-Bootへの置き換えに絡んで、通常のLinux Kernelを使用している市販の無線LANルータではブートローダが初期化している箇所を自前で初期化する必要が出て、いくつかの点で悩まされた。
U-Bootへ置き換えたところ、ネットワーク, PCIe, SoC内蔵無線LANが機能しない状態に陥り、特に後者2つはブートの途中にkernelが固まる症状を引き起こした。このうちネットワークについては、クロック設定が必要だったのと、全般的なリセットレジスタでいくつかのビットが立ったままであったので、それを寝かせることで正しく機能させられるようになった。
PCIeとSoC内蔵無線LANについては、一旦どちらも無効化したうえで片方ずつ検証したところ、PCIeではAR9344におけるPCIeレジスタの初期化が足りておらず、初期化が中途半端となってその後のドライバの処理が止まっており、SoC内蔵無線LANにおいてはネットワーク同様リセットレジスタで一見関係なさそうなビットが立ったままであることでath9kドライバの処理が止まっていた。いずれもドライバ側やlzma-loaderで対処することで、正常に動作する状態に持っていくことができた。念の為、sysupgrade実行時にブートローダがU-Bootへ置き換えられているかチェックを行い、もし置き換えられていない場合はsysupgradeを失敗させるように構成した。
当初initramfs-factoryイメージの形式を生成するのはMakefile内のスクリプトで行っていたものの、ヘッダの生成/付加やチェックサム算出等でスクリプトがあまりにも複雑化していたので、firmware-utilsのツールの1つとして書き直した。
この3機種がマージされた際、本来はそのツールもマージされる必要があったものの見落とされてしまったようで、しばらくビルドが通らない状態に陥った。その後OpenWrtチームメンバーにメッセージを飛ばしてツール側のレビューを依頼し、指摘を受けて改善を行った末にマージされ、正常にビルドできる状態となった。
現在は公式ビルドも利用可能。ath79/tinyfactoryイメージを仕立てる際、メーカーファームウェア内に存在する "tp" ブロックをどうするかもだいぶ問題となった。この "tp" ブロックはAtermシリーズのメーカーファームウェアにおいて通常 "firmware" ブロックの1つ前に存在し、元のブートローダが起動する際に読み込まれ、中にあるPOST (Power On Self Test) を実行するようになっている。 "tp" ブロックは必須であり、もし存在しない場合はブートが止まる為、これをどうにかする必要に迫られた。
多少紆余曲折はあったものの、最終的には、OpenWrtにおいてLinux Kernelを特殊な状況下において読み込んで実行するために用意されているlzma-loaderを置くことで対処に成功し、factoryイメージを実現することができた。
色々
正直なところ、スペックで言ってしまえば今更感は強いものの、もう何年も諦め悪くどうにかできないかと何かと考え続けていたこの3機種を投入しマージされたことで、だいぶ達成感が強い。
積極的に確保する意義は薄いものの、家に残っているなどの理由で試しに投入してみるには良さそう。
QCA9558を搭載するWG1400HP等については、U-Boot側のSoCサポートをU-Boot本家に投げる必要がありそうで、今後どうするかは思案中。