fon2405e hack: SPI フラッシュを換装してOpenWrtをインストールする

かなり前にfon2405eへカスタムファームウェアを入れ替えたことがあるのですが、今回、2MBしかないSPIフラッシュを8MB(MX25L6405D)に置き換えてOpenWrtを入れてみます。このことに思い立ったのは前回、IPカメラにOpenWrtをインストールして、思っていたよりも使い道があったことが理由です。IPカメラのSoCはRT5350FでRT3050系の2世代目にあたり、fon2405e/fon2305eはRT3050Fで1世代目に当たります。それなので機能的にはクロックや機能に多少違いがあるものの基本的に同じなので、fon2405eもOpenWrtを入れれば使い道が出てくるということです。OpenWrtでは4M/32MルータのサポートはV19で終了なので、改造するなら今が最後のチャンスと見てよいでしょう。

OpenWrtのインストール方法

fon2405eにシリアル用のヘッダーピンを立てます。LANポートを上にしてGnd Tx Rx Vccの順です。そしてPCからシリアルアクセス(57600 / 8N1)できるようにします。LANケーブルをPCとfon2405e(PCポート)につなぎます。

fon2405e用のinitramfsのファームウェアをダウンロードしてfonita,imgにリネームしてtftp(tftpd-hpa)サーバのルートディレクトリに置きます。サーバのアドレスを10.10.10.3/24にセットアップします。

WPSボタンを押しながら電源を入れ数秒後、「2」を押してu-boot環境に入ります。タイミングが難しいのでアクセスするまで何度もトライするかもしれません。そのメニューからtftpサーバ(ftpd-hpa)に置いてあるinitramfsイメージをロードしてmtdコマンドでu-bootをアップグレードします。もしくはオリジナルのu-bootでもできるかもしれませんが私は試していません。u-bootは換装後でもアップグレードできます。

次にSPIフラッシュを2GBからu-bootを焼いた4GBもしくは8GBに換装します。4GBのSPIフラッシュは8ピン、8GBは16ピンになります(注:MX25L6406Eは8ピンタイプです)。8ピンの場合はクリップを挟んで焼けますが、16ピンの場合は基盤にハンダ付けしてROMライターにセットします。ROMライターで基盤から取り外したSPIフラッシュのイメージを保存します。エラーが起きやすいので数回行い、md5sum等で正確にコピーできたかチェックします。

SPIフラッシュの焼き方

型番:25L6405DMI-12G
ROMライターにSPIフラッシュを半田付けしてセットします。
Windowsのプログラムを使って元の吸い出した2MBのSPIフラッシュのデータをロードして新しいSPIフラッシュに焼き付けます。Detectでチップを認識していることを確認します。Erase>Write>Verifyの順に実行します。エラーが発生した場合は配線を見直します。
縒り合わせた銅線にハンダをたっぷりつけて熱するとICチップが簡単に取れます。
焼き付けたSPIフラッシュをボードに半田付けします
シリアルアクセスします

ファームウェアの焼き方は何通りかあり、u-bootコマンドで直接ROMを焼く方法、OpenWrtのinitramfsをロードしてからsysupgradeでROM版を焼く方法があります。

ファームウェアを自分でビルドする

Build OpenWrt

gitでOpenWrtのソースをダウンロードしパッチを当ててコンパイルします。

git clone https://git.openwrt.org/openwrt/openwrt.git
cd openwrt
git checkout v19.07.3
# v19.07.0 and later
wget https://downloads.openwrt.org/releases/19.07.0/targets/ramips/rt305x/config.buildinfo -O .config
# v18.06.8 and before
wget https://downloads.openwrt.org/releases/18.06.1/targets/ramips/rt305x/config.seed -O .config
./scripts/feeds update -a
./scripts/feeds install -a
make defconfig
make menuconfig
make

コンパイルに失敗したときはログを出力させて原因を調べます。

make V=s 2>&1 | tee build.log | grep -i -E "^make.*(error|[12345]...Entering dir)"

Build u-boot

ソースに設定変更したパッチを当ててビルドするか自分で設定してビルドします。基本、u-bootの起動に失敗したらSPIフラッシュをROMライターで書き込む以外方法はありません。試してみたところOLinuXinoのu-boot(v4.0)のソースが使えます。u-bootのビルドはUbuntu 12.04.5 32bitを使いました。ソースが古いためディストビューションのバージョンによってはビルドに失敗することもあるようです。

注意: u-bootのパーティションサイズはOpenWrtと同じ標準サイズでサブセット版のオリジナルに比べて大きくなっており、SDKのイメージ、オリジナルのFONのイメージを書き込むと使用不能になります。

insmod mtd-rw.ko i_want_a_brick=1
mtd -r write uboot.img u-boot
[    0.460471] spi spi0.0: force spi mode3
[    0.466203] m25p80 spi0.0: mx25l6405d (8192 Kbytes)
[    0.471242] 4 fixed-partitions partitions found on MTD device spi0.0
[    0.477771] Creating 4 MTD partitions on "spi0.0":
[    0.482649] 0x000000000000-0x000000030000 : "u-boot"
[    0.489940] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.497680] 0x000000040000-0x000000050000 : "factory"
[    0.504921] 0x000000050000-0x000000800000 : "firmware"
[    0.521707] 2 uimage-fw partitions found on MTD device firmware
[    0.527856] Creating 2 MTD partitions on "firmware":
[    0.532914] 0x000000000000-0x000000148a49 : "kernel"
[    0.540179] 0x000000148a49-0x0000007b0000 : "rootfs"
[    0.547460] mtd: device 5 (rootfs) set to be root filesystem
[    0.558165] 1 squashfs-split partitions found on MTD device rootfs
[    0.564472] 0x000000366000-0x0000007b0000 : "rootfs_data"

kermit

u-bootをビルド・インストールできたものの、FirmwareのロードでLZMA解凍に失敗した場合、kermitを使ってシリアル経由で圧縮していないFirmwareを転送する方法を使います。Kermitはビルドがすんなりいってくれそうもなく、当時の最新バージョンではソースを少し変更しました。

kermit-9.0.302.diff

diff -u kermit.orig/makefile kermit/makefile
--- kermit.orig/makefile	2011-08-22 00:12:07.000000000 +0900
+++ kermit/makefile	2020-07-27 13:31:17.955075460 +0900
@@ -6053,9 +6053,9 @@
 	@echo 'makefile if you have trouble.'
 	$(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \
 	"CFLAGS = -O -DLINUX -pipe -funsigned-char -DFNFLOAT -DCK_POSIX_SIG \
-	-DCK_NEWTERM -DTCPSOCKET -DLINUXFSSTND -DNOCOTFMC -DPOSIX \
+	-D_IO_file_flags -DCK_NEWTERM -DTCPSOCKET -DLINUXFSSTND -DNOCOTFMC -DPOSIX \
 	-DUSE_STRERROR $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \
-	"LIBS = $(LIBS) -lm"
+	"LIBS = $(LIBS) -lncurses -lm"
 
 # As above but with profiling
 linuxp:
Only in kermit: UNINSTALL
Only in kermit: wermit

簡単な操作方法

  • Ctrl+\ :ターミナルから抜ける
  • s <filename> :ファイルを転送する

通信設定

.kermrc

set line /dev/ttyUSB0
set speed 115200
set carrier-watch off
set flow-control none
set handshake none
set prefixing all
set streaming off
set parity none

WLANのeepromのインストール

SPIフラッシュを換装してu-bootとfirmwareをインストールできても、まだWLANが使えない問題があります。原因はWLANのeepromがないためです。そこでRalink SDKで作ったファームウェアを調べてそれを使ってみることにしました。元のFONでもいいのですがアクセスが難しいのでRalink SDKのイメージから/etcにあるeeprom(RT3050_AP_1T1R_V1_0.bin)を取り出しました。OpenWrtのeepromはmtd2に保存してあるようで、同じパーティション構成のIPカメラのeepromでhexdumpで調べて比較してみたところ、先頭がボード番号になっていたので、同じことをRT3050_AP_1T1R_V1_0.binでやってみたました。同じくボード番号(3050)だったので、mtdに書き込めば使えるだろう予想して試したところできることが確認できました。

$ hexdump RT3050_AP_1T1R_V1_0.bin
0000000 3050 0100 0c00 3043 8850 ffff ffff ffff
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
0000020 ffff ffff ffff ffff 0c00 3043 7750 0c00
0000030 3043 6650 0511 0024 ffff 012f 7755 aaa8
0000040 888c ffff 000c 0000 0000 0000 0000 ffff
0000050 ffff 0d0d 0d0d 0c0c 0c0c 0c0c 0c0c 0c0c
0000060 1010 1111 1211 1212 1313 1413 1414 ffff
0000070 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000d0 ffff ffff ffff ffff ffff ffff ffff 6666
00000e0 aacc 6688 aacc 6688 aacc 6688 aacc 6688
00000f0 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000200
insmod mtd-rw.ko i_want_a_brick=1
mtd -r write RT3050_AP_1T1R_V1_0.bin factory

OpenWrtにアクセスしてみます。

メッシュネットワークで接続してみました。これにVPNの一つtincを乗せるとセキュアな回線になります。またはメッシュネットワークの中継器としても使えます。
ダッシュボードでledの設定します。インストール時はオフになっています。

Install package

OpenWrtはバージョンコントロールが厳格なのでカスタムファームウェアの場合エラーが起きるときがあります。その場合、--force-dependsをつけるとインストールできます。

# opkg install kmod-tun --force-depends
Package kmod-tun (4.14.180-1) installed in root is up to date.
root@OpenWrt:/etc/opkg# modprobe tun
tun is already loaded

追記:

25l12835Fが届いたのでfon2305eで試してみました。LEDランプが灯ってるので動いているようですが、スイッチ周りが違っているようでネットワークにアクセスできません。さらにGPIOボタンが違っているらしくfailsafeにアクセスできないばかりか、UARTでも115200bpsでアクセスすると不明な文字列となってアクセスできません。fon2305eとfon2405eは微妙な違いでデバイスツリーを変更しないといけないようです。16Mフラッシュは魅力的ですが必要が出た時にfon2405eで換装するかもしれません。

fon2405eがまだ1台残っていたので換装しました。

8ピンタイプはクリップ使うと楽です

無事ランプが灯りました
[    0.460516] spi spi0.0: force spi mode3
[    0.466256] m25p80 spi0.0: mx25l12805d (16384 Kbytes)
[    0.471474] 4 fixed-partitions partitions found on MTD device spi0.0
[    0.477999] Creating 4 MTD partitions on "spi0.0":
[    0.482878] 0x000000000000-0x000000030000 : "u-boot"
[    0.490178] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.497927] 0x000000040000-0x000000050000 : "factory"
[    0.505153] 0x000000050000-0x000001000000 : "firmware"
[    0.522029] 2 uimage-fw partitions found on MTD device firmware
[    0.528180] Creating 2 MTD partitions on "firmware":
[    0.533238] 0x000000000000-0x000000148aab : "kernel"
[    0.540471] 0x000000148aab-0x000000fb0000 : "rootfs"
[    0.547742] mtd: device 5 (rootfs) set to be root filesystem
[    0.558380] 1 squashfs-split partitions found on MTD device rootfs
[    0.564685] 0x000000380000-0x000000fb0000 : "rootfs_data"

SPIマスターに接続してmx25l12805dと認識しています。互換性が高いROMチップです。

追記2

Fon2305eにOpenWrtを再インストールしました。この型番にはjtagがあるのですが配列がわからないので、貼り付けたSPIフラッシュを取り出して再度焼きなおしました。57600bpsに再設定したのですが、相変わらずジブリッシュのままです。おそらくswitchの設定だろうと考えていて、あらかじめ手を打っておいたのでどうにか繋がりました。やはりfon2405eとVLANのレイアウトが違ってました。あとGPIOのリセットボタンも違うので、これも調べて再コンパイルが必要です。とりあえず繋がることが確認できたのでめでたしでした。VLANは0LAN1とWANが有効です。

fon2305e GPIO

GPIO 9: wps or power
GPIO 10: ?
GPIO 11: LAN
GPIO 12: Button
GPIO 14: WAN

TODO

  • DTSに設定したGPIOのledがどうもあってないらしく機能してません。
  • VLANポートの調整(2ポートともLANに接続)

リソース

成果物のu-bootおよびOpenWrtのファームウェアはオリジナルと区別するために通信速度は115200 bpsに設定してあります。

その他

  • ハンダゴテは温度調整付きが使いやすいです。
  • ハンダ吸い取り線は必須です。
  • CH340系のUSBシリアル変換だとプルアップがなくても入力できます。
  • 無理にSPIフラッシュを取ろうとすると基盤が剥がれるので注意しましょう。
  • ROMライタープログラムはWindowsのバージョンによって使えないのでレビュー見て使えるバージョンをインストールします。
  • フラックスを使うと綺麗に半田付けできます。なくてもできますがあると便利です。
  • 試してませんが、リサーチ不足で、MX25L6406EM2I-12Gの方がいいかもしれません。MX25L6405Dの後継チップですが8ピンタイプなのでROMライターの書き込みが楽です。
  • リセット(初期化)はWPSボタンを長押しします。LANランプが消えれば自動的に立ち上がりリセットは完了です。

参考

  • https://openwrt.org/docs/guide-developer/quickstart-build-images
  • https://openwrt.org/docs/guide-developer/build-system/use-buildsystem
  • https://www.olimex.com/wiki/RT5350F-OLinuXino