BBR-4MG上でLinuxが動くところまで確認できたので,今度はフラッシュメモリ上に インストールしてみます. これで,電源を切ったり再起動してもちゃんとLinuxが起動します.
とりあえず,作ったバイナリと変更済みのソースを. ソースは説明と食い違っている部分があると思いますが,分かると思います.
MIPS用のコンパイラ一式は,別途ダウンロードしておいてください.
ここからダウンロードできるものは,試行錯誤の最中に作ったものです. Linux化ファームウェアの方に新しいものがあります. 面倒なことをせずともファームウェアのアップデート機能でLinux化できるようになりました.
BBR-4MGのフラッシュメモリに入っているものは,以下のような感じです.
--------------------------------------
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
--------------------------------------
ブートローダが入っているBootの領域が128KBもあります. これは,リセットを押しながら電源を入れたり,ファームウェアが 見つからなかったときに起動する,「Tiny_ETCPIP_KERNEL」 というものが組み込まれているためです. 実際に起動に使っているのは先頭の32KBくらいみたいですが….
Web ImageとCode ImageはZIP形式になってないと起動時にエラーを出して 上記の「Tiny_ETCPIP_KERNEL」を起動します.
BBR-4MGのブートローダーは,Web ImageとCode Imageを メモリ上に展開し,Code Imageのプログラムの先頭から実行します. なので,圧縮したカーネルが512KB以内に収まらないとそのままでは起動できません.
RAMディスクのイメージを削って無理すれば,なんとか512Kに収まりました.
で,RAMディスクのイメージを何処に置くかですが,Webインターフェイス用の 領域は256KBしか無いので,300KB以上あるイメージは書き込めません.
いくつかに分けて入れておいて,カーネルを実行する前に繋ぎ合わせる プログラムを書こうかとも思ったのですが……ちょっと待ってください. BBR-4MGに入っているフラッシュメモリは2MBです. さっきの一覧の領域を全部足しても,せいぜい1MB+αにしかなりません.
実は,BBR-4MGのフラッシュメモリの半分近くが未使用の状態 のまま眠っています(たぶん). これはもったいない.
というわけで,その空いている領域にRAMディスクのイメージを 書き込んでしまいましょう. もちろん,BBR-4MGのデフォルトのファームウェアの管理の外にあるので, ファームウェアとしては書き込めません. となれば,Linuxで起動してmtdディバイス経由で書き込むしかありません.
後ろの使ってない領域は,"User"という名前でMTDパーティションを 分けておきました. ディバイス的には「/dev/mtd5」がそれです.
あと,CONFIG_EMBEDDED_RAMDISKが無ければ,フラッシュメモリから読むように. initrd_startにイメージのアドレス(0xbfd10000)を入れておきます. カーネルが確保しているメモリの外なので,開放されないようにinitrd_endは0.
真っ当な方法を知っている人がいるならば,教えてください.
CONFIG_EMBEDDED_RAMDISKを外してmake config.
makeの要領は前回と同じ.
RAMディスクとカーネルは分離されてるので, linux-2.4.18-admディレクトリでmakeすればカーネルは出来上がります. RAMディスクのイメージは前回のままでよければ,arch/mips/ramdisk内にあります.
中に入れるファイルを変えたい場合は,AP/mkimg内のスクリプトを書き換えて, スクリプトを実行してください. もちろん,busyboxとかをいじる場合はそっちもmake.
BBR-4MGのブートローダはZIP圧縮されたデータを展開して実行するので, ZIPで圧縮されていなければなりません. また,展開される場所も決められないので,別のところに展開されても カーネルを0x80002000に配置して,エントリポイントから実行する必要があります.
そのために,boot-bbr4mg.binというプログラムを作ってカーネルの頭に 付け足すことにしました.
あとはZIP圧縮して,CRCを求めて,512KB丁度になるように後ろを0xFFで埋めて, サイズやCRCやらを書き込む必用があります.(実は無くても起動したりしたかも)
出来たら,imageディレクトリのmkimg.shを実行すると BBR-4MGのブートローダから起動できるkernel.imgが出来上がります. perlとzipコマンドが必用です.
LinuxのcksumはBSDのものと違ったと思うので,checksum.plを 修正しないといけないかもしれません. CRCが変な値だったら確認してください. 多分,"-o 3"のオプションを削ればいけると思いますが….
boot-bbr4mg.binは,展開されたカーネルイメージを0x80002000に移動して, 0x800026d8にジャンプするだけの単純なプログラムです. boot-bbr4mg.bin自体4KBある(もっと小さくするべきだった)ので,0x80001000に移動してます. 展開されるアドレスによっては実行中に上書きされるようなコードですが, とりあえず大丈夫なようです.
書こうと思ったとき,Windowsで別の事をしててアセンブラが無かったので, 仕様書見ながらハンドアセンブルして,バイナリエディタでちまちまと書きました. なのでソースはありません(汗). 逆アセンブラは手元にあったので,確認しながら書きました. CPUがMIPSでよかった….
逆アセンブルしたらこんな感じでした.
80001000 04110001 bal $80001008 80001004 00000000 -s- nop 80001008 03E02025 move a0,ra 8000100C 3C058000 lui a1,$8000 80001010 24A51008 addiu a1,a1,$1008 ; a1 = 0x80001008 80001014 3C060014 lui a2,$14 80001018 24C60000 addiu a2,a2,$0 ; a2 = 0x00140000 8000101C 24C6FFFC addiu a2,a2,-$4 80001020 8C880000 lw t0,$0(a0) 80001024 1CC0FFFD bgtz a2,$8000101c 80001028 ACA80000 -s- sw t0,$0(a1) 8000102C 3C088000 lui t0,$8000 80001030 250826D8 addiu t0,t0,$26d8 ; t0 = 0x800026d8 80001034 01000008 jr t0 80001038 00000000 -s- nop
まず,前回と同様にvmlinux.binを転送してLinuxを起動します.
ファームウェアとして,フラッシュメモリに書き込みます. 書きかけ.メモだけ.
.configから,CONFIG_EMBEDDED_RAMDISKをはずした状態でカーネルを作る. カーネルを0x80002000に配置して0x800026d8にジャンプさせるコードを先頭に書き込む. それをZIPで固めて,終端は0xffで埋めて512KのサイズにしてCRCとかを書き込む. mkimg.shを実行してください. CRC32が計算できるcksumとperlとzipコマンドが必用です.
手順1でLinuxを起動./dev/mtd?をtftpを使ってバックアップ. お使いのOS用のtftpサーバを探してきて,PC上で起動しておきます. 例えば,tftpサーバが192.168.0.100で動いているなら.
tftp -p -l /dev/mtd0 -r boot.img 192.168.0.100 tftp -p -l /dev/mtd1 -r config.img 192.168.0.100 tftp -p -l /dev/mtd2 -r web.img 192.168.0.100 tftp -p -l /dev/mtd3 -r code.img 192.168.0.100 tftp -p -l /dev/mtd4 -r bootprm.img 192.168.0.100 tftp -p -l /dev/mtd5 -r user.img 192.168.0.100
(転送後,領域の終端以降を読もうとしてエラーが出ます. 気になる人はddで切り出してから転送してください)
最後の領域には,何も入っていません.もし,何か意味ありげなデータが入っていたら, ここから先は止めておいたほうが良いかも.
tftpを使って,今度はLinuxをファームウェアにインストールしてみます. 変な領域に書き込まないように慎重に.特にmtd0を壊すと再起不能になる可能性が あるので要注意(JTAG端子が使えるかも?あとはフラッシュメモリに直接書き込める環境があれば…). ramdisk.bz2はarch/mips/ramdisk/内に作られているはずです.
tftp -g -l /dev/mtd3 -r kernel.img 192.168.0.100 tftp -g -l /dev/mtd5 -r ramdisk.bz2 192.168.0.100
後は,祈りながら再起動.
起動しなくても,ブートローダーが起動するなら慌てずにやり直す. ブートローダーも起動しないなら…再び動かすのはかなり大変です.
ブートローダは,/dev/mtd2に入っているデータも展開するので, 起動を少しでも早くしたい場合は,/dev/mtd2にダミーのzipファイルを 書き込んでおくと良いかも. Linux上から書き込むときはチェックサムをつけたりするのを忘れないでください. あと,あまりにも小さすぎるファイルだと壊れているとみなされてしまうようです.
とうとう,3000円程度でLinuxサーバが作れる時代になったんですね. メモリが8MBもあってCPUが175MHzですか…なかなかハイスペックです.
4MHzのZ80と64KBのメモリ(いつの時代だ)でかなり遊べたのだから, その50倍くらいは凄いことが出来るはずです.