BBR-4MG::Linuxをインストール
BBR-4MG上でLinuxが動くところまで確認できたので,今度はフラッシュメモリ上にインストールしてみます.これで,電源を切ったり再起動してもちゃんとLinuxが起動します.
おことわり
- 何があっても自己責任で.
- 私は,Linuxを殆ど知らないので,妙な事をしている可能性があります.
- 実はLinuxが入ったPCさえ無いのでFreeBSD上でやってます.
ダウンロード
とりあえず,作ったバイナリと変更済みのソースを.ソースは説明と食い違っている部分があると思いますが,分かると思います.
MIPS用のコンパイラ一式は,別途ダウンロードしておいてください.
- bbr-4mg/vmlinux.bin - 単体で起動できるバイナリ
- bbr-4mg/kernel.img - カーネル(/dev/mtd3に書き込んでください)
- bbr-4mg/ramdisk.bz2 - RAMディスクの圧縮イメージ(/dev/mtd5に書き込んでください)
-
bbr-4mg/linux-bbr4mg.tar.gz- ソース一式(50MBあります…) >bbr-4mg06
ここからダウンロードできるものは,試行錯誤の最中に作ったものです.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」がそれです.
Linuxの修正
drivers/mtd/maps/mx29lv320b.c
あと,CONFIG_EMBEDDED_RAMDISKが無ければ,フラッシュメモリから読むように.initrd_startにイメージのアドレス(0xbfd10000)を入れておきます.カーネルが確保しているメモリの外なので,開放されないようにinitrd_endは0.
真っ当な方法を知っている人がいるならば,教えてください.
.config
CONFIG_EMBEDDED_RAMDISKを外してmake config.
make
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
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を起動します.
ファームウェアとして,フラッシュメモリに書き込みます.書きかけ.メモだけ.
- 圧縮されたファイルシステムのイメージを削ればvmlinuzは512Kに収まる
- ファイルシステムを何処に入れるかが問題
- 256KBに収まれば,Web用だったスペースに入る
- 実はBBR-4MGのフラッシュメモリは2MBのうち1MB強しかつかってない(たぶん)
kernel.imgの作成
.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倍くらいは凄いことが出来るはずです.
この文書の履歴
- 2005-09-27 公開
- 2006-03-29 細かい部分を修正