全体の手順
わたしの環境では、LANが使えない。従ってプログラムの転送が少し面倒になる。全体の手順は以下の通り。
(1)hello のクロスコンパイル
(2)hello コマンドを入れてルートファイルシステムを作る。
(3)RedBoot 経由でルートファイルシステムをボードのFlashに書き込む。
(4)ボード再起動
(5)ログインしてhello 実行
まずクロスコンパイラの導入
ボード付属CDのarm-linux-gcc-3.4.1.tar.bz2 を使う。arm用にコンパイル済みのgccパッケージである。(なお付属CDには gcc-4.0.2 も入っている。3.4.1にしたのはなんとなく。)
$ cd / $ su # tar jxf arm-linux-gcc-3.4.1.tar.bz2
これで /usr/local/arm 以下に gcc その他が展開される。gccコンパイラなどの名前は、arm-linux-gcc。パスを通しておく。
$ export PATH=/usr/local/arm:$PATH
hello の作成
(注)共有ライブラリが使えないのでstaticリンクする。
$ vi hello.c #include <stdio.h> int main(){ printf("hello\n"); return 0; } $ arm-linux-gcc -static -o hello hello.c
ルートファイルシステムの作成
付属CDに入っているルートファイルシステムを流用する。
$ cp /mnt/cdrom/linux-2.6\ images/ramdisk.gz . $ gunzip ramdisk.gz
これをループバックでマウントする。
$ mkdir initrd $ su # mount -o loop ramdisk initrd
次に、hello をルートファイルシステムにコピーする。
その前に、要らないファイルを消す。(サイズが厳しいので)
# rm initrd/Noise.wav # rm initrd/funcky.mp3 # cp hello initrd/bin # chmod 755 initrd/bin/hello
最後にアンマウントして圧縮。
# umount initrd # gzip ramdisk
(参考)「組み込みLINUXシステム構築」8.6章
続いてルートファイルシステムをボードに書き込む。そのためにRedBootのコマンドモードに入る。
コマンドモードの入り方
(1)ボードの電源を入れる。
(2)起動中にCtrl-Cを押す。
...(起動中) == Executing boot script in 5.00 seconds - enter ^C to abort ^C RedBoot>
ルートファイルシステムの書き込み先のアドレスを確認する。
RedBoot> fis list Name FLASH addr Mem addr Length Entry point ... ramdisk.gz 0x60A40000 0x00800000 0x00300000 0x00800000 zImge 0x60D40000 0x00080000 0x00140000 0x00080000
ramdisk.gz 領域のサイズは、0x300000=3145728バイト。
一方、先ほど作った ramdisk.gz のサイズは 2746991バイトだったで、上書きしても大丈夫。<br>
ルートファイルシステムをFLASHに書き込む。
めちゃややこしいが、こうやるらしい。
まず、先ほど作った ramdisk.gz をボードのRAMにアップロードする。
RedBoot> load -r -b 0x00800000 -m xmodem CCC ← ボード側RedBootが受信待ちになっている。
別のX端末で送信コマンドを発行する。
↓ Kermit を実行してるのとは別のX端末 $ sx /home/homerun/ramdisk.gz < /dev/ttyS0 > /dev/ttyS0 Sending ramdisk.gz, 22575 blocks: Give your local XMODEM receive command now. Xmodem sectors/kbyte sent: 0/0kRetry 0: NAK on sector ... Xmodem sectors/kbyte sent: 22161/2770kRetry 0: NAK on sector ← ここまで10分くらい Bytes Sent:2747008 BPS:5571 Transfer complete ← 転送成功
もとのKermitの画面のほうを見ると転送が終了している。
... Row file loaded 0x00800000-0x00a9ea6e, assumed entry at 0x00800000 云々... RedBoot>
転送終了。
(参考)
RedBoot のマニュアル loadの説明
kermitとsxの使い方
次に、RAM上の ramdisk.gz を FLASH に書き込む。
RedBoot> fis write -f 0x60A40000(*注) -b 0x00800000 -l 0x300000 ← -f アドレスに注意 * CAUTION * about to program FLASH at 0x60a40000..0x60d3ffff from 0x00800000 - continue (y/n) ? y ← アドレスが間違ってないことを確認してyを入力 ... Erase from 0x60a40000-0x60d40000: ..... ... Program from 0x00800000-0x00b00000 at 0x60a40000: ..... RedBoot>
(*注) fis write の -f アドレスは、fis list で確認した各ボードの値入力すること。間違えないこと。間違って、他の領域をつぶすとボードが起動しなくなる。(たとえは、RedBootを破壊したり、FLASHの情報領域を破壊したりとか、、、→ こうなるとJTAG接続でFLASHを再構築しないといけない)
(参考)
RedBoot のマニュアル fis writeの説明
以上で書き込み終了。再起動する。
再起動は、ボードのリセットボタン(RSTNと刻印のあるボタン)を押すか、
RedBoot> resetとする。
起動後ログイン。hello が入っていることを確認。
~ # ls -al /bin/hello -rwxr-xr-x 1 root root 510927 Jul 14 2008 /bin/hello ~ #
hello の実行
~ # /bin/hello hello ~ #
上の転送では、Kermitと別のX端末の2つの端末を使ったが、Kermitをエスケープすると、1つの端末でも送信可能である。
RedBoot> load -r -b 0x00800000 -m xmodem Ctrl+\c ← Kermitのエスケープを入力 C-Kermit> ← カーミットのコマンドモードに戻る。 C-Kermit> !sx /home/homerun/ramdisk.gz < /dev/ttyS0 > /dev/ttyS0 ← 送信コマンド発行 Sending ramdisk.gz ... ... Bytes Sent:2747008 BPS:5571 Transfer complete C-Kermit> c ← 再度ボードに接続する Row file loaded 0x00800000-0x00a9ea6e, assumed entry at 0x00800000 云々... RedBoot>