2023/03/12 追記: このデバイスのサポート作業については完全に中止とし、実機は処分しました。今後再開する可能性は限りなく低いです。
既に雑記で書き散らかしている通り、メーカーファームがNetBSDベースであるNEC Aterm WR8750NのOpenWrtにおけるサポート作業を行っています。
最近多少進展があったため、ここで一度進捗をまとめておきます。
きっかけ
今に至るまで少しずつデバイスサポートを進めてきたものの、国内メーカーの中で現状サポートできているのが2機種のみ(WG800HP, WG2600HP)とほとんど手つかずになっているNEC機をどうにかできないか、と思ったため。
また、単純にNetBSD機でもLinuxであるOpenWrtをブートできるのか、という単純な興味もあった。
仕様
ソフトウェア面が家庭向けルータとしては独特であるものの、ハードウェアはRAMの サイズが大きい以外はおおよそ一般的な構成。
SoC | Atheros AR9344 |
RAM | DDR2 128MB |
Flash | SPI-NOR 8MB |
WAN/LAN (switch) |
1000Mbps x1 / 1000Mbps x4 (AR8327) |
WLAN | Atheros AR9382 |
USB | USB 2.0 Type-A x1 |
Bootloader | original ? |
OS | NetBSD based |
サポート作業状況
repo: devadd/wr8750n in musashino-build/openwrt
- 現状動作するもの
-
- initramfsファームでのブート
- イーサネット(有線)
- 無線 (2.4/5G) 認識(動作未確認)
- LED
- ボタン, スライドスイッチ
- 現状動作しないもの
-
- sysupgradeファームでのブート
- USBポート
作業についての詳細
- ブートできるファームのフォーマット
- WR8750Nではオリジナルと思われるBootloaderを搭載しており、それ故ブートできるファームのフォーマットもよく用いられるuImage等ではなく、独特なヘッダを付加したものである必要がある。
アップデート用に提供されるファームはファーム自体のヘッダ、ライセンス表記部、テストプログラム部、OSイメージ部に分かれており、ファームヘッダ部以外の各データにはそれぞれデータ用のヘッダが付加されている。
このデータ用ヘッダは、自分での推測に加え、やもり氏より多分に情報を頂いた。ヘッダのフォーマットは以下の通り。| 0x0 - 0x3 | 0x4 - 0x7 | 0x8 - 0xB | 0xC - 0xF | +-------------+-------------+-------------+-------------+ 0x0 | Data Flag | Data Len. | Header Len. | checksum | +-------------+-------------+-------------+-------------+ 0x10 | Load Addr | Entry Point | | +-------------+-------------+ + 0x20 | Data | + + ...
Note: checksumは上位2 byteのみ、下位2 byteは0埋め 例 (loader + initramfs, LOADER_TYPE := bin):| 0x0 - 0x3 | 0x4 - 0x7 | 0x8 - 0xB | 0xC - 0xF | +-------------+-------------+-------------+-------------+ 0x0 | 0002 FFFD | 0031 3000 | 0000 0018 | 4C81 0000 | +-------------+-------------+-------------+-------------+ 0x10 | 8006 0000 | 8006 0000 | 4080 9000 4080 9800 | +-------------+-------------+ + 0x20 | 4080 6800 4008 6000 3C09 1000 3529 001F | + + ...
- "Data Flag" はデータの種類を示す。詳細はやもり氏の記事を参照。
- "Data Len." はデータ用ヘッダを含めたデータの長さ (hex)。
- "Header Len." はデータ用ヘッダの長さ (hex)。通常
0x18
の模様。 - "checksum" は "Data Len." からデータ末尾までのチェックサム。前半2byteのみで、後半2byteは0埋め。このチェックサムの算出方法が不明で、やもり氏から情報を頂いていたものの正確と思われる算出方法を中々見つけられなかった。
対象データのサイズを "4"(多分 "2" でも良い)で割り切れるようにデータ末尾をpaddingしてchecksum部分 (0xC - 0xF) を "00000000
" としてヘッダを付加、以下のスクリプトにより算出し、前半2桁と後半2桁を入れ替えたものがおおよそアタリと思われる。
ddのログが邪魔な場合は、2> /dev/null
を付ける。dd if=fw.bin ibs=4 skip=1 | od -A n -t u2 | tr -s ' ' '\n' | awk '{s+=$0}END{printf "%04x", 0xffff-(s%0x100000000)%0xffff}'
ibs=4 skip=1
は "Data Flag" をスキップして算出するため。(s%0x100000000)
のカッコは無くても四則演算の優先順位上問題無いけれども、わかりやすいので付けた。 - "Load Addr", "Entry Point" は、自分の知識不足もありAtheros/QCAで一般的に使用される
0x80060000
を使用した。
- Watchdog Timer
- 当初WR8750Nでgzip-compressedなOpenWrtファームをブートさせた際、途中でSOFT-RESETが掛かってブートが中断され、再起動されてしまっていた。(雑記の記事を参照)
複数の方から「watchdogでは」という指摘を頂いて調べたところ、WR8750NのBootloaderがWatchdog Timerのカウンタに設定する値が小さく、OpenWrtのLinux KernelがブートしてWatchdogのドライバがロードされるタイミングに間に合わず、その結果resetが発生していることを特定。
対処としては、Kernelをlzmaによる圧縮に変更したうえでOpenWrtのlzma-loaderを先頭に付加し、loader内でWatchdog Timerのカウンタが格納されるレジスタを操作して最大値を書き込むようにした。
これにより、途中でresetされることなくブートが完了するようになった。(雑記の記事1や記事2を参照) - イーサネット(有線部)
- Atheros/QCA SoCではネットワーク周りで様々なパラメータを設定する必要があるが(正しい値が設定されていない場合、NA(P)T速度が著しく低下したりそもそも通信できない)、BootloaderやOSにかなりクセがあるため手探りで調整するしかないかと考えていたものの、Bootloaderのdebugコマンドを利用して必要な値を取得できた。
詳細については雑記の記事を参照。
ただ、iperfでテストした際に瞬間的に速度が落ちることが何度か発生したため、要調整と思われる。 - 無線周り
- 無線を動作させる際に、調整に必要なcalibration dataはもしかしたらNetBSDなAtermでも持っているのでは、と予想していたら、やはりFlash内に存在していた。また、データの存在するoffsetやsizeも一般的なLinux機と同じ様に格納されていた。
当然ながら、法律の関係上無線は実際には使用しない。 - LED
- SoCのGPIOからLEDを調べた際、一つもLEDが点灯しなかった。結局のところ、WR8750Nの搭載するLEDは5か所 x 各2色 = 10個すべてが5GHz帯用として搭載されているath9kチップ (AR9382)のGPIOコントローラに接続されていた。
- Flashからのブート
- 正直厳しい感じ。メーカーファームではOSイメージをFlash上に存在するファイルの様に扱っており、通常OpenWrtで行うようなmtdによる単純な区切りではなかった。このため、単に直接ファームをFlashに書き込んだだけでは "データが破損している" とBootloaderに判断されてしまい、リカバリが発生して書き込んだデータを削除されてしまった。
- USB周り
- AR9344のUSBが直接出ておらず、途中にNECのハブチップ(刻印: D720114, 型番μPD720114?)を経由して出ている。複数のGPIOを操作するとUSBポートに接続したデバイスをLinux Kernelから認識される状態にできるものの、何故かFull Speedまででしか認識されない(AR9344, μPD720114自体はHigh Speedまで対応)。
どの様に構成すればHigh Speedまで利用できるようになるかは、現状では自分の知識不足により不明。
今後
Flashからのブートについては、NECのBootloaderをそのまま利用するのが非常に厳しいと思われるため、U-Bootへの置き換えを検討。現状initramfsファームで起動できる状況ではあるため、ユーザーがインストールする際はそれを踏み台にすることで、SPI-NOR Flashを取り外したりする必要無しにU-BootとOpenWrtへの書き換えをできるようにする状態を目指す。
ただし、U-Bootについての知識は非常に乏しいため、まだ時間が掛かる。また、この作業はBootloaderレベルでの試行錯誤になるので、Flashを直接読み書きできるようにハードウェアに変更を加える必要もあり、少々難易度も上がるし時間も更に掛かる。
USB周りについては現状理解が追い付いていないため、一旦保留。
この機種をサポートできればNECの他のNetBSD機もおおよそ同じ手法でサポートできると思われるため、じっくり進めていきたい。