BBR-4MG の活用法

BroadStation も積もれば山となる。先日 HARD OFF のジャンクコーナにて 105 円でたたき売られていたブロードバンドルータ BBR-4MG を捕獲したので早速フルボッコにしてみようと思います。とりあえずびんずめ堂さんや Thomas さん、bird.dip.jp さんの記事を参考に Linux をインストールして LED を操作するところまで。

と言っても Linux はびんずめ堂さんが既にファームウェア化してくれているので WEB 画面上から更新するだけで終わってしまいます。それでは面白くありませんのでびんずめ堂さんの Linux ソースに bird.dip.jp さんの LED ドライバを組み込んでビルドしてみます。

作業内容

01. 環境構築
02. ビルド
03. LED ドライバの組み込み
04. BBR-4MG に転送
05. LED を光らせる
06. Flash メモリにインストールする
07. バイナリ時計を動かす

01. 環境構築

ビルド環境は Linux なら何でも良いと思います。今回は Arch Linux を使用します。何はともあれびんずめ堂さんの Linux ソースをビルドできる状態にしたいところです。Buildroot を使って試行錯誤していましたが結局ビルドできず、どうしたものか?と悩んでいたところ bird.dip.jp さんの Wiki に方法が載っていました。

以下、bird.dip.jp さんの記事の通り進めていきます。

http://www.edimax.at/download/Linux-SC.zip

こちらからコンパイル済みのツールチェーンを取得します。

wget http://www.edimax.at/download/Linux-SC.zip
unzip Linux-SC.zip

解凍して出てきたファイル 6114-GPL.tgz と 6114-tool-chain.tgz をさらに展開します。

tar zxf 6114-GPL.tgz
tar zxf 6114-tool-chain.tgz

出来上がった EdiLinux ディレクトリはホームディレクトリに、export ディレクトリはルート直下に移動させます。

mv EdiLinux/ ~/
mv export/ /

忘れないうちに開発ツール類にパスを通しておきましょう。

PATH=$PATH:/export/tools/bin:/export/tools/mipsel-linux-uclibc/bin

02. ソースの修正とビルド

びんずめ堂さんからソースを頂いてきます。

wget http://www.binzume.net/library/bbr-4mg/linux-src.tar.gz
tar zxf linux-src.tar.gz

展開できたら EdiLinux ディレクトリの中に既にある linux-2.4.18-adm を削除して代わりにびんずめ堂さんのソースを配置します。現在 EdiLinux の配下は状態はこんな感じです。

ls
6104IPC-BUILD  AP  MAKE-CONF.sh  build.tmp  define  enter  image  linux-2.4.18-adm  make.def  mode.def  target.def

びんずめ堂さんのソースから .depend ファイルを削除します。

find linux-2.4.18-adm/ -name .depend | xargs rm

私の BBR-4MG は Intel 製の Flash メモリでしたがびんずめ堂さんのソースは AMD 用になっていましたのでソースを修正します。drivers/mtd/maps/mx29lv320b.c の下の方にある "for AMD" の行をコメントにして "for CFI" の行のコメントを解除します。

vi drivers/mtd/maps/mx29lv320b.c
// mymtd = do_map_probe("amd_flash", &pnc_map); // for AMD
mymtd = do_map_probe("cfi_probe", &pnc_map); // for CFI

びんずめ堂さんの解説にあるように AP ディレクトリの一部のアプリはコンパイルエラーになるので不要なものは削除しておきます。

rm -r AP/clockspeed-0.62/
rm -r AP/ppp-2.4.1/

とりあえず上記の二つを削除すればビルドが通りました。

./6104IPC-BUILD

ファームウェアに付けるバージョン情報などを聞かれるので適当に Enter を押します。ビルドが終わると linux-2.4.18-adm の下に vmlinux.bin が作成されていますのでこれを BBR-4MG に転送すれば Linux が起動するはずです。

03. LED ドライバの組み込み

さて問題の LED ドライバです。まずは bird.dip.jp さんのところからドライバを頂いてきます。driver.zip を展開すると led.c と led.h が出てきます。これをびんずめ堂さんのソースに組み込んでみます。

cd linux-2.4.18-adm/arch/mips/am5120
ls
5120_int.c  5120_rtc.c  Makefile  cmdline.c  irq.c  led.c  led.o     memory.o   mipsIRQ.o  pci.o   prom.o    serial.o      setup.c  time.c
5120_int.o  5120_rtc.o  am5120.o  cmdline.o  irq.o  led.h  memory.c  mipsIRQ.S  pci.c      prom.c  serial.c  serial_ref.c  setup.o  time.o

念のためバックアップを取り、先ほど展開した driver の配下にある led.c と led.h に差し替えます。

mv led.c led.c.bak
mv led.h led.h.bak
cp ~/driver/led.c ./
cp ~/driver/led.h ./

さすがにこれだけだとエラーが出てコンパイルできないようですね。

led.c:81:38: asm-mips/adm5120/adm5120.h: そのようなファイルやディレクトリはありません

仕方が無いのでソースを修正してみます。led.c の 81 行目付近の include のパスです。

#include <asm-mips/adm5120/adm5120.h>
#include <asm-mips/am5120/adm5120.h>

adm5120 というディレクトリ名の部分のみ am5120 に変更します。これで linux-2.4.18-adm ディレクトリに移動して make を走らせます。

cd ~/EdiLinux/linux-2.4.18-adm/
make

コンパイルが通りました。

04. BBR-4MG に転送

出来上がった vmlinux.bin を XMODEM で転送します。BBR-4MG をシリアル接続して起動します。

BBR-4MG が起動したらすぐに適当なキーを押すと画面が止まります。ここで "!" を押すと管理者メニューが表示されますので "m" キーを押して転送先のアドレス "0x80002000" を入力します。

転送待ちの状態になったら vmlinux.bin を転送します。完了したら「y」を押し、ジャンプ先のアドレス「0x800026d8」を入力すると運が良ければ Linux が起動します。

===========================================================
 BUFFALO BBR-4MG Loader v1.80 build Dec 12 2003 10:13:58
                 Broad Net Technology, INC.
===========================================================

manu_id=6000 chip_id=401A
INTEL TE28F160C3-B bottom boot 16-bit mode found

Copying boot params.....DONE

Press any key to enter command mode ...
Press Reset button to enter Tiny_ETCPIP_KERNEL ...


[BBR-4MG Boot]:!

Enter Administrator Mode !

======================
 [U] Upload to Flash
 [E] Erase Flash
 [G] Run Runtime Code
 [M] Upload to Memory
 [R] Read from Memory
 [W] Write to Memory
 [T] Memory Test
 [Y] Go to Memory
 [A] Set MAC Address
 [#] Set Serial Number
 [V] Set Board Version
 [P] Print Boot Params
======================

[BBR-4MG Boot]:m

RAM upload destination: (default:0x80001000) : 0x80002000
Starting XMODEM download...(press Enter to abort)
CC

[BBR-4MG Boot]:y
Go to Memory Address: (default:0x1000050) : 0x800026d8
LINUX started...
ADM5120 Demo board
CPU revision is: 0001800b
Primary instruction cache 8kb, linesize 16 bytes (2 ways)
Primary data cache 8kb, linesize 16 bytes (2 ways)
Linux version 2.4.18-MIPS-01.00 (root@archlinux) #1125 2014a1年 1a?月 10a?日 e?T
am5120_setup() starts.
System no PCI BIOS
Determined physical RAM map:
 memory: 006a3000 @ 0015d000 (usable)
On node 0 totalpages: 2048
zone(0): 2048 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/ram0 console=ttyS0
CPU clock: 175MHz
Calibrating delay loop... 174.48 BogoMIPS
Memory: 6656k/6796k available (1116k kernel code, 140k reserved, 72k data, 52k )
Dentry-cache hash table entries: 1024 (order: 1, 8192 bytes)
Inode-cache hash table entries: 512 (order: 0, 4096 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 2048 (order: 1, 8192 bytes)
Checking for 'wait' instruction...  available.
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
HDLC line discipline: version $Revision: 1.1.1.1 $, maxframe=4096
N_HDLC line discipline registered.
block: 64 slots per queue, batch=16
RAMDISK driver initialized: 16 RAM disks of 3072K size 1024 blocksize
loop: loaded (max 8 devices)
ADM5120 Switch Module Init
 initrd image at bfd10000
ADM5120 flash mapping: 200000 at bfc00000
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
ip_conntrack version 2.1 (64 buckets, 512 max) - 360 bytes per conntrack
ip_tables: (C) 2000-2002 Netfilter core team
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
adm5120gpio: Checking GPIO pins:
GPIO 0: OUTPUT normal
GPIO 1: OUTPUT inverted
GPIO 2: OUTPUT normal
GPIO 3: OUTPUT inverted
 GPIO 4: INPUT: 0 normal
 GPIO 5: INPUT: 0 normal
 GPIO 6: INPUT: 0 normal
 GPIO 7: INPUT: 0 normal
GPIO 8: LINK_ACT
GPIO 9: SPEED
GPIO 10: DUPLEX_COL
GPIO 11: LINK_ACT
GPIO 12: SPEED
GPIO 13: DUPLEX_COL
GPIO 14: LINK_ACT
GPIO 15: SPEED
GPIO 16: DUPLEX_COL
GPIO 17: LINK_ACT
GPIO 18: SPEED
GPIO 19: DUPLEX_COL
GPIO 20: LINK_ACT
GPIO 21: SPEED
GPIO 22: DUPLEX_COL
adm5120gpio: ADM5120 GPIO driver V2.5 ready.
RAMDISK: bzip2 compressed image found at block 0
VFS: Mounted root (ext2 filesystem).
Freeing prom memory: 0kb freed
Freeing unused kernel memory: 52k freed
init started:  BusyBox v1.00 (2005.10.10-01:34+0000) multi-call binary
Starting pid 10, console /dev/ttyS0: '/etc/init.d/rcS'
mount: Mounting /dev/mtd1 on /flash failed: No such device
info, udhcpc (v0.9.9-pre) started
info, udhcpc (v0.9.9-pre) started
warning, Could not load seed from /dev/urandom: No such file or directory
debug, Sending discover...
debug, Sending select for 192.168.0.81...
warning, Could not load seed from /dev/urandom: No such file or directory
info, Lease of 192.168.0.81 obtained, lease time 172800
debug, Sending discover...
deleting routers
route: SIOC[ADD|DEL]RT: No such process
adding dns 192.168.0.1
debug, Sending discover...
debug, Sending discover...
Fri Jan 10 20:53:21 JST 2014
Starting pid 72, console /dev/ttyS0: '/bin/sh'


BusyBox v1.00 (2005.10.10-01:34+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

# Jan 10 20:53:21 crond[73]: crond 2.3.2 dillon, started, log level 8

05. LED を光らせる

GPIO のドライバがうまく組み込まれていれば起動ログに GPIO の情報が表示されているはずです。下記のコマンドでも確認することができます。

cat /proc/driver/led
0: OUTPUT normal
1: OUTPUT inverted
2: OUTPUT normal
3: OUTPUT inverted
4: INPUT: 0 normal
5: INPUT: 0 normal
6: INPUT: 0 normal
7: INPUT: 0 normal
8: LINK_ACT
9: SPEED
10: DUPLEX_COL
11: LINK_ACT
12: SPEED
13: DUPLEX_COL
14: LINK_ACT
15: SPEED
16: DUPLEX_COL
17: LINK_ACT
18: SPEED
19: DUPLEX_COL
20: LINK_ACT
21: SPEED
22: DUPLEX_COL

次に mknod でデバイスファイルを作成します。

i=0
while [ $i != 23 ]
 do
   mknod /dev/gpio$i c 167 $((i++))
done

LED として使用可能なのは 8 から 22 番までです。led.c によると下記のような状態を設定できるようです。

  • 0 = INPUT
  • 1 = OUTPUT
  • 2 = OUTPUT_1
  • 3 = OUTPUT_0
  • 4 = LINK
  • 5 = SPEED
  • 6 = DUPLEX
  • 7 = ACTIVITY
  • 8 = COLLISION
  • 9 = LINK_ACT
  • 10 = DUPLEX_COL
  • 11 = 10M_ACT
  • 12 = 100M_ACT
  • 13 = FLASH

LED を光らせるには "LED SWITCH" で OUTPUT モードに設定し "LED ON"、"LED OFF" で点灯・消灯を切り替えます。ON と OFF を反転させるには "LED INVERT" を使用します。

echo "LED SWITCH 2">/dev/gpio20
echo "LED OFF">/dev/gpio20
echo "LED ON">/dev/gpio20

各 LED は隣のピンの状態によって緑と橙に切り替えることができます。

echo "LED SWITCH 3">/dev/gpio21
echo "LED OFF">/dev/gpio21
echo "LED ON">/dev/gpio21

とこんな感じで LED を操作するところまではできましたがこの状態ですと電源を落としたらすべて消えてしまいますので、なんとか Flash メモリにインストールする方法を考えてみます。

06. Flash メモリにインストールする

びんずめ堂さんの記事を見ると vmlinux.bin の先頭に 0x80002000 に移動して 0x800026d8 にジャンプするプログラムを埋め込み、ZIP で固めて CRC32 を計算し 512 KB になるように末尾を 0xFF で埋めてサイズやら CRC32 やらを末尾に書き込めば良いと書かれています。「やら」というのがやっかいですがびんずめ堂さんのカーネルイメージを調べてみたところ末尾はファイルサイズ + "00" + "12345678" + CRC32 になっているようです。

私は Stirling というバイナリエディタを使わさせて頂きました。初めはびんずめ堂さんの記事に従って色々いじくり回しておりましたが、結局ファイルサイズや CRC32 は無くても動くことがわかりました。

vmlinux.bin の先頭にプログラムを埋め込む作業だけで済みそうです。もちろん私はアセンブリなど書いたことがありませんのでびんずめ堂さんのカーネルイメージの先頭 0x000013FF までをバイナリエディタで切り取って vmlinux.bin の先頭のバイナリと差し替えました。

そして vmlinux.bin を SOHO.BIN にリネームして zip コマンドで圧縮して /dev/mtd3 に転送します。ファイル名を SOHO.BIN にしておかないとうまく動きませんでした。また、TFTP による転送では成功率が低かったため XMODEM で転送しました。

07. バイナリ時計を動かす

せっかく LED を操作することができるようになったので、何か使い道は無いかと考えてみたところ時間が分かりにくくてお洒落なバイナリ時計を作ってみることにします。と言っても使えそうな LED が 5 つしかありませんので 31 までしか数えることができません。緑と橙で区別するとして 60 秒ならなんとか行けそうです。

echo "LED SWITCH 2">/dev/gpio8
echo "LED SWITCH 3">/dev/gpio9
echo "LED SWITCH 2">/dev/gpio11
echo "LED SWITCH 3">/dev/gpio12
echo "LED SWITCH 2">/dev/gpio14
echo "LED SWITCH 3">/dev/gpio15
echo "LED SWITCH 2">/dev/gpio17
echo "LED SWITCH 3">/dev/gpio18
echo "LED SWITCH 2">/dev/gpio20
echo "LED SWITCH 3">/dev/gpio21
while :
do
	a=$(date +"%S")
	b=$(expr $a / 30)
	c=$(expr $a % 30)
	if [ $b -eq 0 ]; then
		echo "LED OFF">/dev/gpio9
		echo "LED OFF">/dev/gpio12
		echo "LED OFF">/dev/gpio15
		echo "LED OFF">/dev/gpio18
		echo "LED OFF">/dev/gpio21
	else
		echo "LED ON">/dev/gpio9
		echo "LED ON">/dev/gpio12
		echo "LED ON">/dev/gpio15
		echo "LED ON">/dev/gpio18
		echo "LED ON">/dev/gpio21
	fi
	if [ $(($c & 1)) -eq 0 ]; then
		echo "LED OFF">/dev/gpio8
	else
		echo "LED ON">/dev/gpio8
	fi
	if [ $(($c & 2)) -eq 0 ]; then
		echo "LED OFF">/dev/gpio11
	else
		echo "LED ON">/dev/gpio11
	fi
	if [ $(($c & 4)) -eq 0 ]; then
		echo "LED OFF">/dev/gpio14
	else
		echo "LED ON">/dev/gpio14
	fi
	if [ $(($c & 8)) -eq 0 ]; then
		echo "LED OFF">/dev/gpio17
	else
		echo "LED ON">/dev/gpio17
	fi
	if [ $(($c & 16)) -eq 0 ]; then
		echo "LED OFF">/dev/gpio20
	else
		echo "LED ON">/dev/gpio20
	fi
	sleep 1
done

こんな感じで適当にシェルを書いて動かしてみたところ、少しだけ楽しい気持ちになれました。httpd が入っているので簡単な WEB サーバとして使ってみたり、100Mbps ですがハブとして使ってみたり、他には wget と二進数で簡単な温度計、LED の色で天気予報、cron と ping でサーバ監視などはできるかもしれません。

で?っていうツッコミは勘弁してください。

Comments (6)

  1. バイナリをいじるなんてそうそうしないですよね。
    昔、画像に任意のJavaScriptを埋め込めるか試した時に、少し使ったような…
    サクっと書かれてますが、読まれたコード量は私からしたら半端無さそうです!

     |  saku
  2. > 昔、画像に任意のJavaScriptを埋め込める

    一体、何をなさろうとしていたのか、気になりますw

    今回参考にさせていただいた元のサイトの人たちはガチで半端ない感じでした。
    私はコードを読むのは好きですが、組み込み系の知識がないので全く理解できず、むっちゃ時間がかかりましたw
    でも 105 円でここまで遊べたらお得ですね。

     |  Kuro
  3. 画像もアップされるポータルサイトみたいなのを作っていた時に、セキュリティ上ちょっと調べまして。
    当時は確か画像内のコメント欄にJSが書けてIEでは実行できたような…
    知識なしで挑んだんですか、スゲー!

     |  saku
  4. 調べてみると,gif でバッファオーバーランを利用してプログラムを実行させる手法が存在したようです.
    当然正規ではなく,ブラウザクラッシャー的な悪意ある動作だったようですが.

    最近だと svg は javascript を正式に埋め込めるみたいですね.

     |  ks
  5. そういえば昔、そんなセキュリティホールが話題になってましたね。
    なるほど、スッキリしましたw

     |  Kuro
  6. 話が続いていたのですね ^^
    当時チェックしたのはこの画像で、IEでJSが実行できました。今(IE11)ではさずがに大丈夫でした。
    http://www.tokumaru.org/d/images/20070717_0.png

    テキストエディタでファイルを見ると、先頭のJSコードを確認できると思います。
    IEのバージョン移行期だったので、特に対処しませんでした…

    gifの話は知りませんでした。勉強になります。

     |  saku

コメントを残す