BBR-4MGを改造してlinuxルータにする計画

u-bootとlinuxカーネル,root filesystem(buildroot)のソースとバイナリを公開 しました。
現在の作業
ルータとしての設定

★こんなルータがほしい

うちにはCATVとB-Fletzの2つのインターネット接続経路があるので、 WAN側2ポート、LAN側1ポート+ハブみたいな構成のルータがほしいのです。 以前は、PCを使用していましたが、2005年夏に死んでしまいました。 新しく組み直そうと思ったのですが、小さく作ろうと思うと結構大変です。 miniITXでEther 3portのマザーボードは高価です。 使えそうな市販のルータは、C社の6万円のものや、Y社の10万のもの等、やや高額な上、 期待通りの機能があるとは限りません。 そこで、市販の安いルータを改造することにしました。

★方針

BuffaloのBBR-4MGをベースに、ハードウェア、ソフトウェアの両方を改造して実現します。

ハードウェア

コンソールがないとなにも作業できないので、シリアルポートを使える状態にします。 USBメモリを使用できるようにし、オンボードフラッシュとは比較にならないほど楽にシステムを構築できるようにします。

ソフトウェア

オリジナルのモニタでは、プログラムはFlashメモリのCode領域からしかロードできません。この領域は512KBしかないのでカーネルを入れるのは困難です。ダウンロードもシリアルからしかできないので、linuxカーネルのデバッグ作業の効率が悪いです。そこでu-bootを移植することにしました。

u-bootはオリジナルのモニタを残す形で、実装します。オリジナルのモニタから、Code領域のプログラムとしてロードされるようにします。

OSとして、linuxを使用します。仕事でドライバいじったりして、慣れているのでlinuxにしました。

ユーザランドはbuildrootを使用して作成しました。CのライブラリにuClibcを使用しているため、glibcを使用する場合に比べて遙かにコンパクトになります。

フラッシュメモリの使い方は以下のようにしました。
FlashROM 使用状況
Address size 元の使われ方 改造後
0xbfc00000 - 0xbfc20000128KBoot
0xbfc20000 - 0xbfc40000128KConfigurationU-boot env.
0xbfc40000 - 0xbfc80000256KWeb Image未使用
0xbfc80000 - 0xbfd00000512KCode Imageu-boot
0xbfd00000 - 0xbfd1000064KBoot Params
0xbfd10000 - 0xbfe00000960K未使用Linux Kernel

BBR-4MG

ベースは buffaloのBBR-4MGです。

ADM5120P (MIPS 4Kc) 175Mhz
SDRAM 8MB
FlashROM 2MB(intelのものとAMDのものがあるみたいです)
Ether 5 port

Etherが5ポートあるのがすばらしいです。ADM5120は内部にプログラマブルなハブが入っていて、各portを自由に振り分けることができます。 たとえば、通常のBBR-4MGは、WAN1ポートとLAN4ポートをそれぞれ別の論理ハブに接続し、CPU側からは2つの論理ポートとして見えるような設定で動作しています。これを WANには1本づつの計2本の物理ポートを、LANにはハブでつながった3本の物理ポートを割り当てて、 WAN2本LAN1本の合計3本の論理ポートに見えるようにします。 (WAN2本+LAN1本+DMZ2本という強力な構成にもできるはずです。)

linuxを動かすことを考えるとRAMもROMも少ないです。 とくにROM 2MBにカーネルとユーザランド(とブートローダ)を入れるのは無理です。 (2MBにいれちゃったすごい人もいるようですが) USBポートを追加してUSBメモリを接続し、そこにユーザランドを入れることにします。

ちょっと気をつけなければいけないこととして、ADM5120のEther物理ポートの番号と、BBR-4MGに振ってあるポートの番号が一致しないということがあります。 BBR-4MGのWANがADM5120のport4, LANの1〜4がADM5120のport3〜1になっています。
油性ペンで番号を書いておきました。
BBR-4MG Ether port number

ADM5120

ADMTek製の MIPS 4KcコアのSoCです。

CPUコア
MIPS 4Kc
BBR-4MGでは175Mhzで動作しています。
速度的には微妙で、よく見かける組込用のCPU(H8とかSH2とか)と比較すると高速ですが、同クロックのPentiumやPowerPCやSH4と比較して半分くらいの速度です。同クロックのARM9と同等か少し遅い感じです。
Ether
100/10M PHY内蔵ポート ... 5本
Giga etherのGMIIポート... 1本
シリアル
2ポート内蔵しています。BBR-4MGでは1ポート目だけがピンヘッダにでています
価格
BBR-4MGは定価3800円です。この価格でこれだけ遊べるCPUボードは他にありません。
ADM5120そのものは5ドルくらいでしょうか?
USB
2ポート内臓しています。
BBR4-MGではUSBの信号線はでてないので、直接CPUから取り出します。
LED
LEDポートは各etherポート毎に3本でています。それぞれlink,送信、受信等の機能に設定できるほかGPIOにすることもできます。

★ハードウェアの改造(シリアルポートとUSBポートの追加)

シリアルポート

シリアルポートの信号はピンヘッダ(J1)にでています。

                  +-+
   CPU(123) DCD---1 6---DSR CPU(124)
   CPU(127) DIO---2 7--
   CPU(129) DOO---3 8---CTS CPU(125)
                  4 9
            VSS---5 10--VDD
                  +-+
DIO, DOOがそれぞれ、受信(RxD)、送信(TxD)です。

RS232Cレベルに変換してパソコンとつなげられるようにします。 秋月電子で買ったADM3202ANを使用しました。
万能基板にピンヘッダの受け側をつけて、直接本体に挿すようにしています。

DSUB 9pinコネクタを筐体を縦置きしたときに下になるところにつけました。 ど真ん中です。ど真ん中にすると付属の縦置きスタンドもつけられます。

RS232C for BBR-4MG

USBのクロック

ADM5120Pのピンをあげて、48Mhzのクロックを接続します。接続先は

168 CLK48M
167 VSS
です。
後で気づいたのですが、168ピンは基板裏側のR79でプルダウンされています。 R79を外せば、ピンを上げる必要はありません。
48Mhzのオシレータで3.3v仕様のものを使用しました。キンセキFXO31FLです。 サンエレクトロ (ラジオデパートの2階)で400円でした。 あとで日米商事で100円で売ってるのを見かけました。

小さな万能基板上に組んでCPUの上に両面テープで貼り付けました。 電源にフェライトビーズとパスコンを入れてあります。 電源は、C44の両端からとりました。

USB信号線

USBの信号線を引っ張りだします。 ADM5120PはUSBホストポートを2本持っていますが、1本だけ出しました。
使用したUSBの信号線は、

174 DPLS0 (D+)
175 DMNS0 (D-)
です。
ピンを上げて接続しました。
後で気がついたのですが、基板裏側のR82, R83がそれぞれ、174,175番ピンに 接続されているようです。ここからとれば楽勝ですね。その場合R82,R83を15Kオームに変更するとよいでしょう。 top layer of BBR-4MG USB

基板に穴をあけて、USBコネクタをつけてました。USBコネクタの位置にあわせて 筐体にも穴をあけてあります
USBの信号線は、直列に33オームの抵抗を入れ、15kオームでGNDに落とします
VBUSとGNDはACアダプタから入ってすぐのところから分岐して、フェライトビーズを入れて接続しています。 私は秋月で買った5V出力の小さなACアダプタを使用しているのですが、付属のACアダプタでは5.5vなのであまりよくないかもしれません。
bottom layer of BBR-4MG USB

USBが見えた!

USBメモリをつないでhdparmで速度を調べてみました。
620kB/secです。うーん。遅いけどまあこんなもんか。

カーネルメッセージの途中に

Start Init AHCI_INIT Sep  5 2006
USB AHCI at membase 0xb1200000, IRQ 11
usb.c: new USB bus registered, assigned bus number 1
hub.c: USB hub found
hub.c: 2 ports detected
と出ました。
ここでUSBメモリを挿す
# hub.c: new USB device adm5120-hcd-1, assigned address 2
scsi0 : SCSI emulation for USB Mass Storage devices
  Vendor:           Model: USB DISK 2.0      Rev: PMAP
  Type:   Direct-Access                      ANSI SCSI revision: 02
Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0
SCSI device sda: 2009088 512-byte hdwr sectors (1029 MB)
sda: Write Protect is off
Partition check:
 sda: sda1

# hdparm -t /dev/sda

/dev/sda:
 Timing buffered disk reads:    2 MB in  3.30 seconds = 620.61 kB/sec
# 

★u-bootの移植

オリジナルのモニタでは不便なのでu-bootを移植します。

方針

オリジナルのモニタを残す形でu-bootをインストールすることを考えます。 リセットベクタを書き換えると失敗して再起不能になってしまいますので、 JTAG-ICEを持っていない場合には、この方法がベストです。

u-bootにはADM5120用のコードはないようなので、ドライバ類を自分で作る必要があります。
とりあえず、シリアルとイーサネットだけは使えるようにしたいです。イーサが使えなければなんのためにu-boot移植するのかわからないので。
せっかくだからUSBからカーネルよめるようにしたいですが、これはちょっと大変なので後回しです。

MACアドレス、VLAN(仮想ハブ)の設定はu-bootの環境変数で設定し、それをlinuxに渡せるようにします。u-bootの環境変数はFlashに保存できるので、これらの設定も電源を切っても残すことができます。

u-boot移植備忘録

手順
boards/bbr/*を作成 
include/configs/bbr4.hを作成
Makefileを編集してbbr4_config:を追加
make bbr4_config
make
(cpu/mips/adm5120_serial.c, cpu/mips/adm5120_eth.c追加)
例外ベクタ
RAMで動かす場合, RAMの例外ベクタ領域にベクタ用のコードを置き、mips のCP0 statusレジスタBEVビットを落とす必要があります。
u-bootのmips用の例外ハンドラはただ無限ループするだけのコードになっているので要注意です。 たとえば0番地をつつくとTLB missが発生してハングアップします。
簡易的な例外ハンドラを実装しました。例外要因とレジスタをダンプします。(2006/09/30)
リロケーション
走り始めて直ぐ、自分自身をRAMの最終領域付近に移動します。このときdata領域もコピーします。こうしてdata領域への初期値の設定も済ませています。
このときbssは単純にクリアしています。結果としてそれまでに書いたデータが消えます。これは要注意です。いくつかの初期化エントリはRAMに移動する前に呼ばれるので、それらの中では変数の初期化をしても忘れてしまいます。
いちおう逃げ道はあるようです。gdというポインタでアクセスするグローバルデータ領域というのがあって、これはrom上で動作しているときからram動作に移行しても同じところを使い続けます。gdの構造体のエントリを追加すれば利用できます。
RAMにコードを移すとき、mips用のコードではキャッシュのフラッシュが省かれています。いっぱいコピーしてるからフラッシュする必要がないのかもしれませんが、一応追加しました。
FLASHのprotection
なんかFlashが書けないと思ったらflashのprotectionのコントロールルーチンが呼ばれていませんでした。
CFG_FLASH_PROTECTIONをdefineすることで呼ばれるようになりました。
Ether net ドライバ
u-bootのcache制御がへぼくて気になる。
u-bootのドライバをいろいろみたけど、まともにキャッシュ制御してないような...
明示的にフラッシュする必要のあるキャッシュを持つCPUで、DMAするデバイスを使うときは、まずいことになると思う。
au1xxxや4kc(adm5120)はライトアロケートしないし、ライトスルーだったりするから問題になりにくいのかもしれないが、みんなちゃんと動いてるのかなあ?
とりあえずadm5120内蔵etherドライバはフラッシュするようにした
VLAN(仮想ハブ)を環境変数(ethports)で設定できるようにしてあります。
ethports=0x41,0x42,0x44,0x48,0x50 とすると全物理ポート独立したVLANポートに見えるようになります。
プログラムロード時のキャッシュフラッシュ
キャッシュをフラッシュする関数の中身がすっからかんなので追加しました。
本来、ロードしたら実行を移す前に、data cacheをwrite backして、instraction cacheをinvalidateする必要があります。
実際には、linuxカーネルはキャッシュサイズよりずっと大きいのでキャッシュがあふれてフラッシュされてしまうので必要ないです。
bootelfの引数にコマンドラインの引数が渡らない
bootelfコマンドを定義している構造体で、引数の最大値を定義しているところが2になっていたので、CFG_MAXARGSに変更しました
linuxに環境変数を渡す
go, bootm, bootelfで、第三引数に環境変数を渡すように改良しました
この仕組み利用してlinuxにイーサのMACアドレスを渡しています。
ポインタや、ポインタのテーブルの制約
リロケートすると、ポインタを修正する必要があるので、静的な初期化を するのは避けた方が無難です。はまりました。
dma_cache...系の関数のポインタをやめて直接関数を呼ぶようにしました。
文字列のテーブル等を参照するとき、テーブルそのものはGOTの修正で直っていますが、テーブル内の文字列へのポインタは元のままです。
文字列のテーブルをやめて、switch - case文に書き換えました。
UNCACHED_SDRAMマクロ
Au1x00, TB0226以外はphysical addressに変換されるようになっていましたが、 常にKSEG1に変換するようにしました。この方が普通です。
ロードアドレス
BBR-4MGのブートローダーは0x80001000番地にロードするようです。
ただし、バージョンによってはちがうかもしれません。 そこで、予定と違うアドレスにロードされた場合、自分自身を移動するようにしました。
アドレスによっては、自分自身を上書きするので失敗しそうですが、 キャッシュ上で動いているので意外にうまくいきます。
そのために、キャッシュフラッシュを省いているので、移動後におかしくなるかもしれません。
違うアドレスにロードされるようならコンパイルしなおした方がよいでしょう。 コンパイルし直すときの参考にするために、実際にloadされたアドレス、loadしてほしかったアドレスを表示するようにしました
UNEXPECTED LOAD ADDRESS!!!
LOADED   0x80002000
EXPECTED 0x80001000
上のLOADEDのアドレス値をboard/bbr4/config.mkのTEXT_BASE=に書いて コンパイルし直します。
bzip2対応
include/configs/bbr4.hにCONFIG_BZIPを追加しました。
malloc用のエリアを2.5MB以上とらなければ動かないらしいので、CFG_MALLOC_LENを3072*1024にしました。
AutoMDIXが働かない
phy_cntl2のbit25〜bit29だけでなくbit31を立てる必要があるみたい。これはundocumented.

★linuxカーネルの移植

linuxカーネルを移植します。 ADM5120で動くlinuxカーネルはけっこうあちこちにありますが、 ADM5120のUSB hostのドライバは、最近のカーネルに対応したものはなかなか見つかりません。

linuxカーネルは2.4系を使用しました。 2.6系のカーネル用のUSBドライバがまともに動かなかったからです。 ほかに、2.6系はカーネルサイズが大きいのとコンパイルに時間がかかるという 問題があるので、2.4系の方がいいと思います。 2.6系でうまく動かなかったのはでかすぎたせいのような気がします。

linuxカーネル備忘録

USBにPCIが必要
configurationでPCI bus supportを有効にする必要があります。
ADM5120のUSB host controlerはPCIを経由しているわけではありませんが、 ドライバの構造体にPCI関連のものを参照している部分があります。
コンパイラに注意
gcc-4.xとgcc-3.4.xでコンパイルするとうまくいきませんでした。
gcc-4.xではコンパイル通らないし、gcc-3.4.xでは動かないコード (arch/mips/signal.cでごっそり関数が消滅して、呼ばれたときにその先が よばれてしまう)を吐いていました。
gcc-4.xでもgcc-3.4.xでも正しくコンパイルされるようにソースを書き換えました。
removable deviceをroot filesystemとするときの問題
USBなどのremovable deviceにroot filesystemを置くと、マウントするときまでにデバイスが認識されておらず、失敗することがあります。
1秒間待ちながらリトライするようにしました。

★ユーザランドの構築

buildrootを使用します。 uClibcを使用しており、glibcと比べてコンパクトになります。 USBを増設したことで、ルートファイルシステムのサイズが問題になることは ありませんが、RAM容量が非常に少ないので、依然、プログラムのサイズを気にする必要があります。

手順

make menuconfig
make

buildroot備忘録

インストールするパッケージを考える
dhcp client/server(udhcp), pppoe(ppp), iptables, sshd(dropbear), ntp, iproute2くらいか
バイナリサイズは8MBくらいになった。
RAMもなんとか足りそう。
ppp
rp_pppoe.soのリンクにしっぱいしていた
AR=$(TARGET_CROSS)arを渡すと通る
最近ftp://ftp.samba.org/がつながらない(2007/03/18)、とりあえずhttp://samba.org/ftp/ppp/からhttpでとってdl/にコピー。
udhcp
udhcpdがインストールされない。
packages/udhcp/udhcp.mkにudhcpd用の手順を追加
と、思ったらbusyboxにもudhcpd/udhcpcがあるんですね。こっちを使おう。
inittab
tty[0123]を無効にしてをttyS0を有効に。
mountに失敗する
busyboxのmountはmount -aできない?
うーん、わからん
mount -t proc none /procとするとなぜかread onlyでマウントされる
結論。busyboxのmountコマンドは変。
/etc/TZ
uClibcのtimezoneの設定方法がわからない
/etc/TZをJST-8JSTにしたらJSTになった (#echo JST-8JST > /etc/TZ)
-9じゃなくて-8であることに注意。バグっぽいので要確認。
ntpd
_ntpd:_ntpdなuserを用意する必要がある
なぜかgettyが動かない
未解決
IPv6で遊びたいなあ
rtadvdはないのか?linuxではradvdなのか。後回し
iproute2
WANが2つあるので、外からの接続について接続もと経路で応答できるように設定する必要がある。これにはiproute2が必要。
busyboxに入ってる
wake on lan
busyboxにether_wakeが入ってた。でもちょっとパッチが必要。
dropbear
sshの小さな実装
ssh 2.0専用?
busybox 1.4.1がインストールできない
Makefile.custumのinstall:でCONFIG_PREFIXだけを見るようになっていてPREFIXが無視される。5 Oct 2006(たぶん1.2.1)以降。ちょっとパッチ当ててみた。
# mount
/dev/root on / type ext3 (rw)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw)
# ps ax
  PID  Uid     VmSize Stat Command
    1 root        372 S   init
    2 root            SW  [keventd]
    3 root            SWN [ksoftirqd_CPU0]
    4 root            SW  [kswapd]
    5 root            SW  [bdflush]
    6 root            SW  [kupdated]
   14 root            SW  [khubd]
   17 root            SW  [usb-storage-0]
   18 root            SW  [scsi_eh_0]
   20 root            SW  [kjournald]
   57 root        360 S   /sbin/syslogd -n -m 0
   58 root        340 S   /sbin/klogd -n
   59 root        484 S   /bin/sh
   60 root        444 S   /usr/sbin/dropbear
   73 root        296 S   udhcpc -i eth0
   89 root        444 S   ntpd
   90 _ntp        444 S   ntpd
   99 root        728 S   /usr/sbin/dropbear
  100 root        572 S   -sh
  140 root        320 S   udhcpd
  143 root        352 R   ps ax
# free
              total         used         free       shared      buffers
  Mem:         6084         4964         1120            0          560
 Swap:            0            0            0
Total:         6084         4964         1120
#
ntpd, dhcp client/server(udhcpc,udhcpd), sshd(dropbear),syslogdを 動かした状態で、sshdでログインしてみました。 この状態で1120KB空いているのでRAM容量も足りそうです。

★配布

ソース

u-boot
u-boot-1.1.4-bbr4-20070316.tar.bz2
linux kernel
linux-2.4.33-bbr4-20061016.tar.bz2
buildroot
buildroot-20060918+bbr4-20061012.tar.bz2

バイナリ

u-boot
u-boot-bbr4-20070316.zip
BBR-4MGの標準のブートローダを使用して(Uコマンド)展開せずにそのまま書き込みます
linux kernel
linux-bbr4-bin-20061016.tar.bz2
展開して、中にあるvmlinux.imgをu-bootを使用してFlashROMの0xbfd10000〜に書き込みます。
root filesystem
bbr4-rootfs-20061012-2.tar.bz2
USBメモリに展開してください。(NFS root用としても使用できます)
root directory直下からのツリーになっているので展開するときには注意してください

★インストール手順

u-bootのインストール

BBR-4MGに標準で書き込まれているbootloaderのUコマンドを使用して書き込みます。 プロトコルはX-MODEM CRCです。

linuxでkermitとsxを使用するとうまくいきませんでした。改行を入力すると中止するそうなので、そのせいかもしれません。 仕方がないのでwindowsでteratermを使用しました。

起動時に
Press any key to enter command mode ...
と表示されたら、すぐに何かキーを押します。
プロンプト
[BBR-4HG Boot]:
が表示されたらUを押します
[BBR-4HG Boot]:U


UPLOAD Flash
--------------------------------------
Area         Address     Length 
--------------------------------------
[0] Boot            0xBFC00000     128K
[1] Configuration   0xBFC20000     128K
[2] Web Image       0xBFC40000     256K
[3] Code Image      0xBFC80000     512K
[4] Boot Params     0xBFD00000      64K
--------------------------------------
Enter area to UPLOAD: 
3を入力します。
Upload area 3.  Are you sure? (Y/n) 
大文字でYを入力します。
Starting XModem download...(press Enter to abort)
と表示されたら、 XMODEMで、u-boot-bbr4-XXXXXXXX.zip を送信します。

Ether portの振り分けとMACアドレスの設定

u-bootの環境変数のethportsに設定し、linuxカーネルからもこれを使用します。 ethportsには、VLANのリストを16進数で設定します。各ビットが物理ポートに対応します。

ADM5120 ether port ビット定義
ビット76543210
ポート-CPUGMIIport4port3port2port1port0

port0,port1,port2をLAN, port3をWAN1, port4をWAN2になるように設定します。 それぞれのグループにCPUポートを加えると、0x47, 0x48, 0x50となります。 u-bootのコマンドで以下のように設定します。

BBR-4MG/HG # setenv ethports 0x47,0x48,0x50

MACアドレスは、group毎に振る必要があります。 一つ目のグループのMACアドレスは標準で割り振られているアドレスを環境変数ethaddr に自動的にセットするようにしてあります。 それ以外のグループのMACアドレスは設定を行う必要があります。 2つめ以降はeth1addr, eth2addrのように設定します。

BBR-4MG/HG # setenv eth1addr 00:0d:0b:08:06:51
BBR-4MG/HG # setenv eth2addr 00:0d:0b:08:06:51
保存して再起動して確認します。
BBR-4MG/HG # saveenv
BBR-4MG/HG # reset
...略
ポートグループが3つになったのが起動時のメッセージのNet:で確認できます。
printenvコマンドで環境変数を表示してMACアドレスを確認します。
...略
Net:   adm0, adm1, adm2
Flash:  2 MB
In:    serial
Out:   serial
Err:   serial
Net:   adm0, adm1, adm2
Hit any key to stop autoboot:  0 
BBR-4MG/HG # printenv
bootdelay=2
baudrate=115200
ethaddr=00:0d:0b:08:06:50
ethact=adm0
bootcmd=bootm 0xbfd10000
bootargs=ttyS0,115200 root=/dev/sda1
ethports=0x47,0x48,0x50
eth1addr=00:0d:0b:08:06:51
eth2addr=00:0d:0b:08:06:51
stdin=serial
stdout=serial
stderr=serial

Environment size: 247/65532 bytes

linuxカーネルのインストール

TFTPでカーネルイメージを転送しました。 TFTPで転送するためには、自分のIPアドレスとサーバのIPアドレスを環境変数にセットしておく必要があります。それぞれ、ipaddr, serveripです。

もちろんサーバの準備も必要です。サーバの準備についてはここでは割愛します。

ファイルをRAMに転送した後、FlashROMに書き込みます。 FlashROMに書き込む前にprotectの解除とeraseを行う必要があります。

BBR-4MG/HG # setenv ipaddr 192.168.0.51
BBR-4MG/HG # setenv serverip 192.168.0.18
BBR-4MG/HG # tftp 0x80300000 vmlinux.img
Using adm0 device
TFTP from server 192.168.0.18; our IP address is 192.168.0.51
Filename 'vmlinux.img'.
Load address: 0x80300000
Loading: #################################################################
         #################################################################
	 ################################################
done
Bytes transferred = 907800 (dda18 hex)			←この値を書き込み時のサイズに指定する
BBR-4MG/HG # protect off 0xbfd10000 0xbfe00000
...............
Un-Protected 15 sectors
BBR-4MG/HG # erase 0xbfd10000 0xbfe00000
............... done
Erased 15 sectors
BBR-4MG/HG # cp.b 0x80300000 0xbfd10000 0xdda18		←tftp転送時のメッセージのBytes transferred の値を指定
Copy to Flash... flash_write_cfiword, cnt=907800, src=80200000
done

上の例ではRAMの0x80300000〜を作業に使用しています。 u-bootが使用している、0x80500000〜80800000(ブートログのu-bootのメッセージ参照)とベクタエリアの0x80000000〜0x80001000をさければ、どこでも使用できます。 0x80300000〜にすると、展開後のカーネルがロードされる0x80001000〜が空くので、 Flashに書き込まずにそのままbootmコマンドで実行することができるので、テストするのに便利です。

ユーザランドのインストール

USBメモリを他のlinuxマシンに接続してインストールを行います。
NFSサーバが用意できるならば、NFS rootでbootして 、BBR-4MG上で作業を行うこともできるかもしれません。

  1. fdiskでパーティションを切る
  2. mke2fsでファイルシステムを作る
  3. tune2fsでfsckの周期を調節する。ついでにjournalも有効にする
    例: tune2fs -j -i 0 -c 0 デバイス
  4. 作成したファイルシステムをマウントする
  5. bbr4-rootfs-XXXXXXXX.tar.bz2を展開する。 例: tar -C マウントポイント -xpSjf bbr4-rootfs-XXXXXXXX.tar.bz2

★再コンパイル方法

コンパイルする順番は、buildroot, u-boot, linux kernelです。

buildrootにクロスコンパイラが含まれているので、これを最初にコンパイルします。 また、u-bootにmkimageというツールが入っていて、これを使用してlinuxカーネルをu-boot イメージ形式に変換するので、u-bootをlinux kernelより先にコンパイルします。

buildrootのコンパイル

$ make

u-bootのコンパイル

$ export PATH=${PATH}:buildrootのディレクトリ/build_mipsel/staging_dir/bin
$ make bbr4_config
$ make
$ zip u-boot.zip u-boot.bin

linux kernelのコンパイル

$ export PATH=${PATH}:buildrootのディレクトリ/build_mipsel/staging_dir/bin
$ yes "" | make config
$ make dep && make
$ mipsel-linux-objdump -f vmlinux		# start addressを確認(下のmkimageのエントリポイントとして入力)
$ mipsel-linux-objcopy -O binary vmlinux vmlinux.bin
$ bzip2 vmlinux.bin
$ u-bootのディレクトリ/tools/mkimage -A mips -O linux -C bzip2 -a 0x80001000 -e エントリポイント -d vmlinux.bin.bz2 vmlinux.img

★ブートログ

BBR-4MGのブートローダがu-bootを実行し、u-bootがlinuxを実行すると、 コンソールにはこんなメッセージが流れます。

★参考にした資料

1.Adm5120 - LinuxMIPS
ここからたどればほとんどの情報にたどりつけます。データシートもあります。
2.びんずめ堂さんのBBR-4MGをハックするページ
すごいです。
2MBのフラッシュにlinuxシステムを入れることに成功されてるようです
3.u-boot
いろんなCPUに対応しているlinux用bootloader。mips向けはあまり力が入ってないような...
4.buildroot
make一発でcross compiler toolchainからroot filesystemイメージまで作成できるすごいやつ
5.NoRocketScience Forum Edimax / Sweex routers → Firmware Upgrade → Linux 2.4.32 ported to ADM5120
NoRocketScience ForumにはADM5120 + linuxに関する話題がいろいろあります。
今回使用したUSBドライバのありかは、この記事で知りました。
6. ADM5120用usbドライバ
今回使用したUSBドライバ。
ファイル名がusb-shciになってるけど中にはusb-ahciと書いてあります。
私はファイル名をusb-ahciに変更して使用しました。

変更履歴

2007/03/16 AutoMDIXが動くようになった。
2007/03/16 割り込みstatusをクリアするようにした。(flow制御でpause状態になると止まりっぱなしだった)
2007/02/02 robertさんから指摘のあったu-bootのethernetドライバのバグを修正した
2006/11/14 コンパイル手順例のsetenvしてるところが間違っていたので修正した
2006/10/20 カーネルにpppoe関係が入っていないので追加した(2006/10/16版)
2006/10/20 ブートログを最新のものに置き換えた(2006/10/18版)
2006/10/19 ルートファイルシステムの配布ファイルがtar.bz2なのに単なるtarファイルになっていたのでbzip2で圧縮し直した。
2006/10/12 ルートファイルシステムのソースとバイナリを公開
2006/10/05 u-bootとlinux kernelのソースとバイナリを公開
2006/09/05 linuxのUSBドライバが動いた

FENIX/ MEMBERS/ thomas's HOME/ MEMO/bbr4

佐藤益弘 thomas@fenix.ne.jp