NECのAtermはオリジナルなブートが入っているのでFreeBSD 10.3でU-Bootをビルドして焼き直してみた。
ハードオフで108円で購入した、Atheros AR7240(AP91)が対象です。
当初はRedbootを試そうと思っていたが、ちゃんとビルドできるソースがなくて、U-Bootを試す事にしました。
Atherosのサポートコードはu-bootの本家には入っていないのですが、GPLで公開されたベンダーのアーカイブに入っています。
AR7240はネットワークIF×2とEtherSwitchがチップに内蔵になっていて、個別のコードが必要無いのでビルドは比較的簡単なほうではないかと思われます。EtherSwichが外付けされてたりすると、それの制御用のコードが必要になりちと厄介です。
このSOCはSPIなフラッシュなのでいったんフラッシュを外して、SOP変換基板に貼付けジャンパーをはりました。VCC,GNDはflashromで焼く時はFTに接続して、起動する時は本体側に接続するようにしました。
CPUを止める事ができれば基板に実装したまま焼く事ができるのかもしれません。CFIなフラッシュをJTAGで焼く時は300Kで2時間くらいかかったのですが、SPIなフラッシュは2Mを5分くらいで焼けるので、試しやすいです。
MacでflashromはFT232HでシリアルコンソールはFT231Xで接続していたが、FT232Hだけでも良い。対象のモジュールのシリアルコネクタは1mピッチ5本という変則的で秋月のICクリップ(グラバークリップ)でどうにか接続できた。
ar7240なファイルは本家には含まれていないのですが、U-BootはGPLなので、いろいろところにソースがころがっています。
AP91などのソースはAtherosが作成したものと思われるがAtherosは本家には提供しない主義なのかもしれません。
手元にある同じSOCを使った某社のアーカイブを利用させてもらった。
toolchainはRedBootの時と同じようにlinux x86なバイナリをFreeBSDのlinuxエミュレーションで利用してビルドすることにする。
% sudo kldload linux
ビルドは以下のスクリプトで通りました。
#!/bin/sh
export PATH="/storage/home/hiroki/tools/linux-toolchain/mips-linux-gcc344/bin:${PATH}"
CROSS=mips-linux-
gmake distclean
gmake HOSTCC=cc CROSS_COMPILE=${CROSS} ap91_config
gmake HOSTCC=cc CROSS_COMPILE=${CROSS} u-boot.bin
include/configs/ap91.hとboard/ar7240/ap91/の下がこのターゲット用のファイルになります。
最初はRedBootのビルドに使ったgcc 3.2.1を使ったところ-march=mips32r2なんてオプション知らんと言われてしまいました。
MIPS公式のtoolchain(mips-mti-linux-gnu/2015.
06-05)を使ったらリンカーがエラーを吐いていました。
cpu/mips/start.o: In function `reset':
(.text+0x4b4): undefined reference to `_GLOBAL_OFFSET_TABLE_'
Makefile:178: recipe for target 'u-boot' failed
gmake: *** [u-boot] Error 1
あまり深追いはせずに、gcc3系のel(リトルエンディアン)なtoolchainを-EBオプションで通しました。
起動はできて、setenv,saveenvしてFlashのアクセスはOKだったのですがネットワークがTime Outで使えませんでした。ネット検索したらelなtoolchainの問題のようでした。
手元にあったgcc4系のeb(ビッグエンディアン)なtoolchainを使ったところ、エラーで起動できなくなりました。
### ERROR ### Please RESET the board ###
たまたま手元にあった、gcc3.4.4のebなtoolchainを使ったら、ネットワークも使えるようになりました。
U-Boot 1.1.4 (Jun 27 2016 - 00:51:30)
AP91 (ar7240) U-boot
DRAM:
sri
#### TAP VALUE 1 = 8, 2 = 9
32 MB
Top of RAM usable for U-Boot at: 82000000
Reserving 256k for U-Boot at: 81fbc000
Reserving 192k for malloc() at: 81f8c000
Reserving 44 Bytes for Board Info at: 81f8bfd4
Reserving 36 Bytes for Global Data at: 81f8bfb0
Reserving 128k for boot params() at: 81f6bfb0
Stack Pointer at: 81f6bf98
Now running in RAM - U-Boot at: 81fbc000
id read 0x100000ff
flash size 2097152, sector count = 32
Flash: 2 MB
BOARD IS NOT CALIBRATED!!!
In: serial
Out: serial
Err: serial
Net: ag7240_enet_initialize...
No valid address in Flash. Using fixed address
: cfg1 0xf cfg2 0x7014
eth0: 00:03:7f:09:0b:ad
eth0 up
No valid address in Flash. Using fixed address
: cfg1 0xf cfg2 0x7214
eth1: 00:03:7f:09:0b:ad
ATHRS26: resetting s26
ATHRS26: s26 reset done
eth1 up
eth0, eth1
Hit any key to stop autoboot: 0
## Booting image at 9f300000 ...
Bad Magic Number
ar7240> ping 10.10.10.100
Trying eth0
dup 1 speed 100
Using eth0 device
host 10.10.10.100 is alive
ar7240>
WAN側のeth0もLAN側のeth1も使えるようになりました。eth1の方にはスイッチ経由になります。
gcc 3.4のtoolchainはftp.mips.comにrpmが置いてあったようなのですが、このサーバが無くなってrpmの入手ができずあきらめかけたのですが、たまたまダウンロードしてあったアーカイブに入っていました。
u-bootのサイズによりエントリーポイントと環境変数で設定された値が違ってしまう事があるので、その場合は以下のようにエントリーポイントを設定してください。
ar7240> setenv bootcmd "bootm 0x9F050000"
ar7240> saveenv
u-bootのsetenvは"でくくると、環境変数が含まれる場合展開されてしまいますが、'でくくると環境変数のまま保存されます。
もともと4Mのフラッシュが実装されていたのですが8Mのフラッシュに換えてFreeBSD焼いてみました。
もともと入っていたNECオリジナルのbootは、起動時にキーをいろいろ入力したら一回プロンプトがでたのですが、再現できませんでした。
IPL:HARD-RESET
memory test ... ok
flinstall OK
boot version: 1.0.1
PKG "FERRY"
CPU "Atheros/AR7240"
Revision c.2 CLOCK 340.0 MHz
Boot:InitFilesystem
phy0.4: "Atheros/AR7240(phy)"
phy0.0: "Atheros/AR7240(SW)"
active ch:1
post start
DRAM Test ..... PASS
Timer test .... PASS
FLASH CHKSUM .. PASS
LAN Test .....
LoopBack count 0 ..
phy0.4: "Atheros/AR7240(phy)"
phy0.0: "Atheros/AR7240(SW)"
active ch:0
active ch:1
phy0.4: "Atheros/AR7240(phy)"
phy0.0: "Atheros/AR7240(SW)"
active ch:1
PASS
WAN Test .....
LoopBack count 0 ..
phy0.4: "Atheros/AR7240(phy)"
phy0.0: "Atheros/AR7240(SW)"
active ch:0
active ch:1
phy0.4: "Atheros/AR7240(phy)"
phy0.0: "Atheros/AR7240(SW)"
active ch:1
PASS
Package TYPE = 0x06
post success
now booting Firmware ...
loaded Firmware
welcome to boot console
boot>
U-bootは変数にコマンド列を保存して実行する事ができます。
setenv hoge='tftpboot $(memtmp_addr) kernel;bootm'
saveenv
run hoge
saveenvやrunが無いビルドの場合は使えません。
余談だがこのターゲーットはUSBのパターンがあり、FreeBSDのドライバもあるので、時間ができたら試してみたい。(上が74Pin USB_DP,下が73Pin USB_DN)
同じターゲットが手に入ったので、8MのFlashに同じU-Bootを焼いてつけてみたところ、起動してすぐにハングアップしてしまう事があった。ハングアップするときは
U-Boot 1.1.4 (Jun 27 2016 - 09:39:48)
AP91 (ar7240) U-boot
DRAM:
sri
#### TAP VALUE 1 = 8, 2 = 8
32 MB
Top of RAM usable for U-Boot at: 82000000
Reserving 256k for U-Boot at: 81fbc000
Reserving 192k for malloc() at: 81f8c000
Reserving 44 Bytes for Board Info at: 81f8bfd4
Reserving 36 Bytes for Global Data at: 81f8bfb0
Reserving 128k for boot params() at: 81f6bfb0
Stack Pointer at: 81f6bf98
と表示されて固まる。たまにうまく動くときは
#### TAP VALUE 1 = c, 2 = c
と表示されていた。DDRメモリの初期化がうまくできていないっぽいが、ハードが壊れているのか、U-Bootに問題があるのかは不明。
調べてみた所、U-BootでDDRのTAPを自動判定するコードがstart.Sにあるar7240_ddr_tap_init()となっていて、それがメモリの種類によって不安定になるケースがあるようです。自動判定せずに適当な値で決め打ちにした所、問題なくなりました。
AR7241に同じバイナリ焼いたところ、起動はするがネットワークが使えない。。。
ソースによってはCONFIG_AUTOBOOT_STOP_STRが設定されていて、^Cなどでは止められないコードもあるようです。TP-Link系はtplというおまじないで止まりました。
AP99(AR7241)でビルドしたところeth0addrを設定しないとネットワーク(WANポート)が使えませんでした。
hornet> setenv eth0addr 00:11:22:33:44:55
eth_set_enetaddr(num=0, addr=00:11:22:33:44:55)
Setting new HW address on eth0
New Address is 00:11:22:33:44:55
hornet> ping 10.10.10.3
Trying eth0
dup 0 speed 100
Using eth0 device
host 10.10.10.3 is alive
TP-Link系のu-bootはオリジナルとはイメージのフォーマットが違います。
AP96(AR7161/AR8316)もビルドして入れ替えてみました。Makefileのap96はFLASH_SIZEを見てなくて、デフォルトの8Mで作られてしまっていました。
AP96なRouterStation ProはRedBootのようで、コードを探してみたのですが、見つからなかったのでu-bootにしました。
AR9132とBCM5395なatermはBCM5395に対応したu-bootのソースはなさそうなので、ちょっと無理な気がします。このターゲットはCFIなので貼り替えは無理で、bootがオペレーション可能だったので、オリジナルbootを残してFreeBSD化できないか調査してみようと思います。
linuxエミュレーションはFreeBSD 9上で使い始めて10,11と使い続けているが、全く問題なく使えている。
u-boot_modもビルドしてみた
AtherosのAR9331などをサポートしたu-boot_modもビルドしてみました。
u-boot_modはu-bootをモディファイしたもので、ブラウザでの操作の機能が追加されたりしているようです。
toolchainは64Bitのgcc 5が推奨されていたが、FreeBSDのLinuxエミュレーションではGLIBCが無いとエラーで起動できなかったので、何かに入っていたgcc-4.3.3を使いました。
必要なpkgはbashとgmakeだけでした。
bashのパスやスクリプトをちょっといじったらビルドできました。
イメージはTL-Linkタイプになります。
Onion Omegaのブートもこのコードをベースにしていたようです。