hello プログラムを転送するのに、ルートファイルシステムを作って、RedBoot 経由で転送という手順だと10分くらいかかる。 RedBoot経由せずに、ボードのLinuxと開発PCとの間で直接ファイル転送できると作業が効率的である。
そこで、ボードに xmodem 転送コマンドを導入することにする。ソースは、lrzsz パッケージを使う。(というか、これしかない)
まずこちらから↓ lrzsz のソースをダウンロードする。
lrzsz-0.12.20.tar.gz
これを uClibc の環境でコンパイルする。
解凍してコンフィグ
$ tar zxf lrzsz-0.12.20.tar.gz $ cd lrzsz-0.12.20 $ CC=arm-linux-gcc ./configure --prfix=/bin creating cache ./config.cache checking for a BSD comptatible install... /usr/bin/install -c ...
CC=arm-linux-gccとしているが、わたしの環境では、これが glibc ではなく uClibc をリンクするようにしている。(普通の環境だと、arm-linux-uclibc-gcc のこと)
コンパイル
$ make make all-recursive make[1]: ... ... make[2]: ディレクトリ `/home/homerun/arm-dev/lrzsz-0.12.20/src' に入ります arm-linux-gcc -g -O2 -o lrz lrz.o timing.o zperr.o zreadline.o crctab.o rbsb.o zm.o protname.o tcp.o lsyslog.o canit.o ../lib/libzmodem.a ../intl/libintl.a -lnsl lrz.o(.text+0x264): In function `wcgetsec': /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include/bits/stdio.h:68: undefined reference to `_IO_putc' lrz.o(.text+0x49c):/usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include/bits/stdio.h:68: undefined reference to `_IO_putc' ... collect2: ld returned 1 exit status make[2]: *** [lrz] エラー 1 make[2]: ディレクトリ `/home/homerun/arm-dev/lrzsz-0.12.20/src' から出ます make[1]: *** [all-recursive] エラー 1 make[1]: ディレクトリ `/home/homerun/arm-dev/lrzsz-0.12.20' から出ます make: *** [all-recursive-am] エラー 2
なんかエラーになった。 _IO_putc がないというエラーが延々と出ている。
uClibc のincludeディレクトリ /usr/local/arm/3.4.1/arm-linux/include を確認したが、_IO_putc は定義されていない。grep で探すと /usr/local/arm/3.4.1/arm-linux/sys-include/stdio.h で使用されている。
どうやら arm-linux-gcc のデフォルトインクルードパスがおかしいらしい。
デフォルトインクルードパスを確認する。
$ arm-linux-cpp -v ← gcc でなく cpp ... #include "..." search starts here: #include <...> search starts here: /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/include /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include ← ここの順番が不味い /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/include ← ここの順番が不味い End of search list. ^C
.../arm-linux/sys-include が先になっている。ほんとうは、uClibc をインストールした .../arm-linux/include を先に見て欲しいのである。もう少し確認してみよう。
$ arm-linux-gcc -H hello.c . /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include/stdio.h ← NG ...
完全にsys-include/stdio.h を見に行っている。
回避方法は、-isystem オプションを使って以下のようにすればよい。
$ arm-linux-gcc -H -isystem /usr/local/arm/3.4.1/arm-linux/include hello.c . /usr/local/arm/3.4.1/arm-linux/include/stdio.h ← OK ...
なお -I オプションではうまくいかない。.../arm-linux/include が元々デフォルトのインクルードパスに含まれているので -I オプションでは順番が変わらないからだ。
(因みに-nostdinc を使うとデフォルトインクルードをなしにもできる)
参考 Cプリプロセッサのman
lrzsz のコンフィグではこうする
$ CC=arm-linux-gcc CFLAGS="-isystem /usr/local/arm/3.4.1/arm-linux/include" ./configure --prfix=/bin ...
この後 make すると正常に終了することを確認した。
しかし、コンパイルの度に -isystem を指定するのは面倒なので、今後のことも考えて、arm-linux-gcc の specs を変更しておく。
$ su # vi /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/specs ... *cpp: %(cpp_cpu_arch) %(subtarget_cpp_spec) ← これらの行は1行です %{mapcs-32:%{mapcs-26: ← これらの行は1行です %e-mapcs-26 and -mapcs-32 may not be used together}} ← これらの行は1行です %{msoft-float:%{mhard-float: ← これらの行は1行です %e-msoft-float and -mhard_float may not be used together}} ← これらの行は1行です %{mbig-endian:%{mlittle-endian: ← これらの行は1行です %e-mbig-endian and -mlittle-endian may not be used together}} ← これらの行は1行です -isystem /usr/local/arm/3.4.1/arm-linux/include ← これらの行は1行です ...
表示のために改行しているが、実際は1行です。-isystem xxx オプションを cpp に追加した。
インクルードパスが変わっていることの確認。
$ arm-linux-cpp -v ... #include "..." search starts here: #include <...> search starts here: /usr/local/arm/3.4.1/arm-linux/include ← 先頭に追加されている。OK /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/include /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/include End of search list.
うまくいっている。
あらためて、lrzsz のコンフィグ&コンパイル
$ CC=arm-linux-gcc ./configure --prfix=/bin ... $ make ... make[1]: ディレクトリ `/home/homerun/arm-dev/lrzsz-0.12.20`から出ます
うまくコンパイルできた。
ボードへのインストール
コンパイルしてできた lsz, lrz コマンドをボードのルートファイルシステムにコピーする。ルートファイルシステムの作り方は前回と同じ。再掲する。
$ cp /mnt/cdrom/linux-2.6\ images/ramdisk.gz . ← 付属CDのルートファイルシステムを流用 $ gunzip ramdisk.gz $ mkdir initrd $ su # mount -o loop ramdisk initrd ← ループバックでマウント # rm initrd/Noise.wav ← 不要ファイル消す # rm initrd/funcky.mp3 # cp lrzsz-0.12.20/src/lsz initrd/bin/. ← lsz のコピー # cp lrzsz-0.12.20/src/lrz initrd/bin/. ← lrz のコピー # cd initrd/bin/. # ln lsz lsx ← ハードリンク作成 # ln lrz lrx # ln lsz lsy # ln lrz lry # ln -s lsz sz ← ソフトリンク作成 # ln -s lrz rz # ln -s lsx sx # ln -s lrx rx # ln -s lsy sy # ln -s lry ry # cd ../.. # umount initrd # gzip ramdisk
ramdisk.gz をRedBoot経由でボードに転送して、FLASHに書き込む。やり方は前回と同じ。
ここでは、lrzsz を使ったが、gkermit という転送コマンドも便利である。(ただしKermitとしか通信できない)