以下は、このためのクロスコンパイラの作成手順です。 glibc2 が事前に用意できるか否かで手間の差は大きく、Debian woody に置かれている lib6_2.1 は利用すべきですが、以下では glibc2 を含めて build します。
binutils の 2.9.5 系列 (Latest は 2.9.5.0.24) を build することもできますし、 arm linux の kernel 2.2.14 のあたりでは 2.9.5 が必須になりましたが、 linux7k の kernel 2.2.1 は逆に binutils 2.9.1 系列でなければ make できません。 また 2.9.1 系列と 2.9.5 系列の binutils は組み合わせる gcc に微妙に互換性がありません。... つまり 2.9.1.x 専用 gcc, 2.9.5.x 専用 gcc というものがそれぞれ必要です。
2.9.1.0.25 のソースを展開し、パッチをあてて make します。
% bzip2 -d < binutils-2.9.1.0.25.tar.bz2 | tar -xvp % cd binutils-2.9.1.0.25 % zcat ../binutils-2.9.1.0.19a-arm-diff-981230.gz | patch -p1{bfd, gas}/Changelog.linux に細かい rej が出ますが、これは仕方ないでしょう。 コードには影響ないようです。 デフォルトターゲットの --target は arm-linux (arm 用 linux, ELF format) を指定します。 as 以外は i386 と共有できるので、この段階で必要なのは実は as だけですが、 ぜんぶ作っておきます:
% ./configure --target=arm-linux % make % su root # make installaout 形式 (linux7k のもともとの標準) を build する場合は --target=arm-linuxaout としますが、 特に必要とする場面もないと思います。
また、/usr/local/lib/libbfd.*.so や /usr/local/lib/libopecodes.*.so が次の共有用のとで衝突するので --enable-shared してはいけません。
% ./configure --enable-targets=arm-linuxaout,arm-linux,i586-linux --enable-sharedとすれば、標準の binutils が arm-linux, arm-linuxaout のものも扱うことができるようになります。 このあと make all ; make install はいつもどおり。
ただ、多くの makefile で arm-linux 用に立ち上げるバイナリは /usr/local/bin/arm-linux-* の形をしているので、このままでは共用できません。 共用する分について
# cd /usr/local/bin # rm arm-linux-strip # ln strip arm-linux-stripなどとする必要があります。
% bzip2 -d < linux-2.2.1.tar.bz2 | tar -xvp % cd linux % bzip2 -d < ../patch-2.2.1-rmk2.bz2 | patch -p1 % bzip2 -d < ../linux-2.2.1-philb-990208.bz2 | patch -p1 % zcat ../crash+burn-26.patch.gz | patch -p1作者の標準 config は myconfig の形で置かれています:
% cp myconfig .config % make xconfig % make dependコンパイラがありませんから make は出来ませんが、これで gcc を make するためのヘッダが出来ました。
# ln -sf include/asm-arm /usr/local/arm-linux/include/asm # ln -sf include/linux /usr/local/arm-linux/include/linux
余談:
ARM linux の latest は linux-2.2.14 + rmk1 です。
linux7k も早く 2.2.14 + rmk1 に対するパッチにならないかなぁ... sigh.
% bzip2 -d < gcc-core-2.95.1.tar.bz2 | tar -xpv % mkdir egcs-i386 % cd egcs-i386 % ../gcc-2.95.1/configure --enable-shared % make all % cd ..ディレクトリ gcc-2.95.1/ でなく、 その外に置かれた egcs-i386/ で作業していますが、 egcs はソースツリーの中で構築することを推奨していません。 外で構築するよう勧めているので、ここでもそれに従いました。
arm 用コンパイラの make に入る前に Phil Blundell さんのサイトから
つづいて Chris Rutter さんのページ から をあてておきます。後者は 2.95 以前 (egcs-1.1.2 など) の場合は必要ないようです:% cd gcc-2.95.1 % zcat ../gcc-2.95-diff-990730.gz | patch -p0 % cd gcc % patch -p0 < ../../gcc-fold-const.patch % cd ..
余談:
現在 gcc-2.95-diff-990730.gz のかわりに
gcc-2.95.2-diff-991022.gz や gcc-2.95.3-diff-000102.gz
が公開されています。... が、snapshot 系列専用で 2.95.2 にはうまくあたりません。
このままだと gcc の build に glibc を使おうとするので、 gcc/config/arm/t-linux を 1 行編集しておきます:
- TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC + TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
% cd .. % mkdir egcs-arm % cd egcs-arm % ../gcc-2.95.1/configure --enable-shared --target=arm-linux --disable-threads % make cross % make install-gcc-cross--target=arm-linuxaout の場合も同様なのですが、 なぜか ld がエラーを吐いていまだ arm-linuxaout の gcc を構築できていません。 もっとも Debian で elf 系が充実しはじめた今 arm-linuxaout が要ることもないでしょう。
% zcat glibc-2.1.2.tar.gz | tar -xvp % cd glibc-2.1.2 % bzip2 -d < ../glibc-linuxthreads-2.1.2.tar.bz2 | tar -xvp % zcat ../glibc-crypt-2.1.tar.gz | tar -xvpさて、 configure:
% ./configure --host=arm-linux --build=i586-linux --prefix=/usr/local/arm-linux --enable-add-ons=crypt,linuxthreadsbinutils, gcc は --prefix 無指定なら /usr/local/${TARGET} に install されます。 arm-linux 用クロス関連なら /usr/local/arm-linux/ と /usr/local/lib/gcc-lib/arm-linux/ です。
ヘッダなど関連ファイルの読み込みもこのディレクトリ下からおこなわれます。 つまり arm-linux-gcc がデフォルトで参照するヘッダ、ライブラリパスは /usr/local/arm-linux/ の下になるため、glibc でも --prefix=/usr/local/arm-linux を指定しなければなりません。 binutils, gcc の install 先が異なる場合はそれに応じて glibc の --prefix も換えておきます。
なお、ここで --enable-omitfp (フレームポインターの除去。最適化を強める) をつけてはいけません。
つけてコンパイルしても build は出来るんですが、適当にプログラムをコンパイル、実行しようとすると
permission error でコケます。
ライブラリアセンブラソースのどれかが frame pointer の存在を仮定しているようですね。
どこかの文書に確かに host,build, prefix,enable-add-ons 以外の option をつけて configure してくれるな
と書いてあったのですが、試しに build したところやっぱり動きませんでした。
% makegcc の make もけっこう長い時間がかかったはずですが、glibc の make は さらに長くかかります。ディスクも 300MB ほど消費します。 mP6-266 で、
4139.138s real 2935.3s user 728.64s system
% du -s 282293 .でした。install すると /usr/local/arm-linux/lib 下にライブラリを かれこれあわせて 72 MB ほど install しますので、その分の容量も必要です。
# make install # cd ..これでようやく gcc を build する準備がととのいました。
% rm -rf egcs-armegcs の他のコンパイラ、C++, Fortran etc. が必要ならここで展開:
% cd gcc-2.95.1 % bzip2 -d < gcc-g++-2.95.1.tar.bz2 | tar -xvp % bzip2 -d < gcc-g77-2.95.1.tar.bz2 | tar -xvp先にいじった gcc/config/arm/t-linux の 1 行をもとにもどします:
- TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h + TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
% cd .. % mkdir egcs-arm % cd egcs-arm % ../gcc-2.95.1/configure --enable-shared --target=arm-linux % make % make install % cd ..
% cd egcs-i386 % make install % cd ..ドキュメントについては、i386 と arm 用で同じものが名前を換えてコピーされているため、 ディスクが節約のため arm-linux- は消しておきます:
% pushd % cd /usr/local/man/man1 % rm arm-linux-*i386, arm 共用の binutils が導入されているなら、/usr/local/bin/strip は arm 用にも使えます。arm 用のバイナリ、i386 用のバイナリが混在する /usr/local/arm-linux/bin で力を発揮するでしょう:
% cd /usr/local/arm-linux/bin % /usr/local/bin/strip --strip-all * % popd
% cd linux % make xconfig % make depend % make Image % make modulesmake zImage, make bzImage などはまだサポートされていないそうです。 また、modules をランタイムにロードする際に必要になる insmod は modutils-2.1.121 以降 (できれば modutils-2.36) が必要です。linux7k project の ftp サイトにある module-2.0.0 は使えません。 Jim's arm binaries か Debian woody などから modutils-2.1.121バイナリか、modutils-2.36 を使うようにしてください。
余談:
Linux7k project に置かれている glue_kernel binary 自身は
modules 機構が外されて make されています。modules-2.0.0 がメンテされてない訳です ...
% zcat boot-13.tar.gz | tar -xp % cd boot % make allさらに
% ./glue.pl ../linux/arch/arm/boot/Image > glue_imageとしてつくった glue_image が Arlo でロードすべきカーネルイメージになります。
% gcc -b arm-linux hogehoge.cあるいは
% arm-linux-gcc hogehoge.cこの時、ターゲットバイナリのフォーマットを管理するのはインストールした /usr/local/ 直下にある /usr/local/arm-linux/ や /usr/local/i586-linux-glibc1/ などです。 この管理ファイルを通じて gcc は cc1 や as の起動パスを定めるので、 binutils は gcc と同じ --prefix で configure しなければなりません。
クロス環境を build する際にはインストールディレクトリを gcc, binutils で揃えることに留意して下さい。
ところで手元の環境では gcc -b arm-linux では ld がフォーマットを認識せず、 ld --help として調べたところ elf32-arm というフォーマットになっていました。 しかし -b elf32-arm にするとこんどは gcc 側が認識しません。 窮余の策として、
# cd /usr/local/lib/gcc-lib # ln -sf arm-linux elf32-arm # cd /usr/local/ # ln -sf arm-linux elf32-armしてあります。これで gcc -b elf32-arm hogehoge.c という形でコンパイルできるようになります。 なお、arm-linux-gcc によるコンパイルの方は何の問題もなくコンパイルできました。
通常 configure でクロスコンパイルを指定(--target=arm-linux)すると arm-linux-gcc を使うように Makefile が作成されます。 gcc, arm-linux-gcc のどちらでもコンパイルできるからといって arm-linux-gcc を消すのはやめましょう。
余談:
binutils 2.9.5 で互換性がなくなるのはこの部分です。
elf32-arm が elf32-littlearm に変わっています。
% ./configure --host=arm-linux --build=i586-linuxとすることで linux7k 用のバイナリが build できるようになりました。 .... もっともこのままでは install できないので、--prefix に適切な位置を指示してやる必要があるでしょうし、 --host, --build は受け付けるのに Makefile には CC = gcc とだけ定義されてしまい、 セルフ用のバイナリが make されてしまうケースも多いのですが。
% CC=arm-linux-gcc LD=arm-linux-ld ./configure --host=arm-linux --build=i586-linuxとするのが素直です。ただこれも Makefile.in 中に "gcc" を直書きしているものが タマにあります -_-;;
例として linux7k の上でうごく cat を make します。 cat が無いというのは不便とかいうレベルではないので:
% zcat textutils-1.22.tar.gz | tar -x % ./configure --host=arm-linux --build=i586-linux --prefix=/mnt/flashcard % for name in **/Makefile ; do > sed 's/CC = gcc/CC = arm-linux-gcc/g' < $name > /tmp/Makefile > mv /tmp/Makefile $name > done % make % make installtextutils はそのままだと CC = gcc としますので、これを arm-linux-gcc で上書きしてから make に入ります。 Makefile を作成したのちに sed で上書きしているのは、リンクに gcc を Makefile.in 中に直書きしている部分があるからです。
この方法で大抵うまくいくんですが、 セルフとクロスと両方のコンパイラを同時に必要とするパッケージでたまにハマります。 たとえば多くの場合、document で .info や .tex などが使われますが、 これらのファイルをパッケージ独自のフィルタ経由で作成する場合、 そのフィルタはセルフのコンパイラで動かなければなりません。 あるいは emacs のように、build された自分自身(temacs) がその場で動く必要のあるものもあります。
textutils では何もしてないのでそのままでうまく make できます。
/usr/local/bin/strip が arm-linux format を受け付けるようにしてあるなら、
# cd /mnt/flashcard/bin # for name in * ; do > if file $name | grep 'not stripped' > /dev/null ; then > /usr/local/bin/strip --strip-all $name > fi > doneもしておくと、Psion5 のカードの容量の節約になるのは普段と同じです。