2006年10月某日、ひょんなことからBuffalo社LinkStation LS-160GLを入手しました。sshとか動かしてみようかと思いましたがLS-160GLにはsuコマンドが無かったのでクロスでビルドしようと思い、クロスコンパイラを勉強がてら作ってみた時の備忘録です。当方、その筋の達人ではまったくないので誤りだらけかと思われますが試行錯誤の末、嘘っぽ〜いtoolchainsが出来たので、まぁ、何かの参考や笑いのネタくらいになればと・・・w
Buffalo社のWebより申し込みを行いLS-GLシリーズのソースCDを取得。この中にbinutilとgccのソース、glibcのバイナリ、その他アプリのソースが入っていました。しかし、CodeSourceryのtoolchainsを使用している?のかglibcのソースコードは入っていません。バイナリとincludeが入っていたのでincludeのみを使用することにし、binutilsとgccだけをビルドすることにしました。ファームをVer1.11に更新したのに伴いkernelも2.6.12から2.6.16に上がっていたので再度ソースCDを取得しました。.configファイル名からするとkernelはver1.10相当のようですが、ver1.11ではver1.10からkernelは変更されていないということですかね?当方はVer1.10に上げていなかったので(出てたの知らなくてw)、これまでずっと1.02のままでした(汗 内容は大して代わり映えしていませんが、相変わらずu-bootのソースは入っていません。
ホストとしてCentOS 4.3 FinalがインストールされたPC(Prescott 2.8G)を利用しました。特に変わったところのない平凡なPCです。ホストがCentOSである理由は以前、別件でクロス開発を行なった時のマシンを流用しており、当時CentOSのgccが4.x系ではなく、3.x系だったので採用しました。尚、LS-GLのHDDを直接ホストに接続しmountする際にファイルシステムがxfsのパーティションが存在します(しかも本体のroot"/")。CentOSの標準kernelではxfsがサポートされていないようなので、別バージョンのkernelを拾って入れました。ホストにHDDを直結する場合は起動時にこのkernelをGRUBで選択します。
最終的にホスト上の/usr/local/developにtoolchains一式がインストールされるように、~/ls-glにて作業を行ないました。
作業用の~/ls-glは以下の様な構成にしました:
cd ~/ls-gl/src
tar xvjf ../tar/binutils-2005q3-2.tar.bz2
tar xvjf ../tar/gcc-2005q3-2.tar.bz2
patch -p1 -d gcc-2005q3 < gcc-2005q3.diff
これで作業ディレクトリ側の準備完了。
gcc-2005q3-2はgcc 3.4.4ですが、コンパイルを行うと内部エラーが発生する現象が一部で発生しました。具体的にはVineのSRPM版mysqlのビルドで発生したのですが、同じ症状のバグ報告もなされているようでパッチがありましたので当てておきます。2つのパッチが用意されていますが、そのままではうまく当たらないので2番目、1番目、2番目の順で当てます。面倒な場合はgcc 3.4.6のソースを拾ってきて中のgcc/gcc/regrename.cと差し替えてやれば同等かと思います:
(略)… internal compiler error: in verify_local_live_at_start, at flow.c:546
このパッチを行ったgccにて再度mysqlをビルドしたら上記のエラーは発生することなく回避できていました。
正直、どこまで必要かわからなかったので本体の/lib、/usr/lib、/usr/locla/libを全てホスト側に持ってきました(ソースCDに入っていたlibraryではどうもうまくいかなかったのですが、やり方が悪いんだか原因がわからず・・・)。因みにファームウェアはVer.1.02に上げてあります(Ver1.11にしたのを機に再度作り直しました)。そしてソースCDに入っていたglibc-devel-arm_trg-2005q3-2.arm.rpmのincludeのみを利用しました(kernelのヘッダも含まれているようです):
bintuilsからビルドします(シェルスクリプトでやった方が便利でしょう):
export CROSSPATH=/usr/local/develop
export PATH=${CROSSPATH}/bin:$PATH
export LC_ALL=POSIX
export LFS_HOST="i686-pc-linux-gnu"
export LFS_TARGET="arm-none-linux-gnueabi"
cd ~/ls-gl/build
rm -rf binutil
mkdir binutil
cd binutil
../../src/binutils-2.17pre/configure \
--with-sysroot=${CLOSSPATH} \
--prefix=${CROSSPATH} \
--host=${LFS_HOST} \
--target=${LFS_TARGET} \
--disable-nls \
--enable-shared \
--with-lib-path=${CROSSPATH}/usr/local/lib:${CROSSPATH}/usr/lib:${CROSSPATH}/lib \
--disable-multilib
make configure-host
make
sudo make install
sudo cp -v ../../src/binutils-2.17pre/include/libiberty.h ${CLOSSPATH}/include
LFS_HOSTは各自の環境に合わせて設定します。ビルドが成功すれば/usr/local/ls-glにbinutilsがインストールされます。これも必要かどうか不明ですが、インストールされた先でちょっと小細工します。
cd ${CLOSSPATH}/arm-none-linux-gnueabi/lib
sudo mv ldscripts ../../usr/lib
cd ..
sudo rm -rf lib
sudo ln -s ../usr/lib lib
以上。
gccをビルドします:
export CROSSPATH=/usr/local/develop
export PATH=${CROSSPATH}/bin:$PATH
export LC_ALL=POSIX
export LFS_HOST="i686-pc-linux-gnu"
export LFS_TARGET="arm-none-linux-gnueabi"
cd ~/ls-gl/build
rm -rf gcc
mkdir gcc
cd gcc
../../src/gcc-2005q3/configure \
--prefix=${CROSSPATH} \
--host=${LFS_HOST} \
--target=${LFS_TARGET} \
--with-local-prefix=${CROSSPATH} \
--with-cpu=arm926ej-s \
--with-gnu-ld \
--with-gnu-as \
--with-libs=${CROSSPATH}/lib \
--disable-multilib \
--disable-sanity-checks \
--disable-libstdcxx-pch \
--disable-nls \
--enable-shared \
--enable-c99 \
--enable-long-long \
--enable-__cxa_atexit \
--enable-threads=posix \
--enable-languages=c,c++
make
sudo make install
多少時間は掛りますが、以上でtoolchainsは完成?w
試しにクロス環境でkernelをビルドしてみます。ソースCDよりlinux-2.6.12_lsp.1.7.8.tgzをtarディレクトリにコピーしておきます。どうやらコンパイルした状態のままでcleanやmrproperされないまま圧縮されているようです(その方が好都合ですが)。ファームウェアVer1.11相当?のソースCD入手に伴いlinux-2.6.16_lsp.1.7.8.tar.gzにて再びカーネルビルドに挑戦してみました:
export TARGET="arm-none-linux-gnueabi"
export CROSSPATH=/usr/local/develop
export PATH=${CROSSPATH}/bin:$PATH
export INSTALL_MOD_PATH=~/ls-gl/rootfs
cd ~/ls-gl/srctar xvzf ../tar/linux-2.6.12_lsp.1.7.8.tgz
ln -s linux-2.6.12_lsp.1.7.8 linux
tar xvzf linux-2.6.16_lsp.1.7.8.tar.gz
ln -s linux-2.6.16_lsp.1.7.8 linux
cd linux
cp buffalo/buffalo_lsgl_arm_110.config .config
CC=${TARGET}-gcc AR=${TARGET}-ar RANLIB=${TARGET}-ranlib make menuconfig
CC=${TARGET}-gcc AR=${TARGET}-ar RANLIB=${TARGET}-ranlib make bzImage modules modules_install
カーネルとmodulesのビルドには成功しましたが、modules_installのスクリプトで失敗。コンパイルは出来ているようですが、時間が無いので原因究明はまた後日。今回は最後までビルドできました。本来はLS-GLのブートローダ"U-BOOT"に合わせてmake bzImageではなくmake uImageでビルドすべきなのですがmkimageコマンドがないのとクロスコンパイルでやっているので試していません。どこかでu-bootのソースを拾ってこればmkimage(実際あるみたいですし)でビルド可能なんでしょうがまだkernelを入れ替えるだけの根気と動機がありません(実験用のHDDも要るでしょうし)。
LS-GLではbusyboxが採用されているので、多くのコマンドが一つのバイナリにリンクされる形式で導入されている。suコマンドの追加にbusybox全てを入れ替えるのも危険なのでw suコマンドだけ単独でビルドすることにしました:
export DESTDIR=~/ls-gl/rootfs
export PATH=/usr/local/develop/bin:$PATH
export TARGET="arm-none-linux-gnueabi"
cd ~/ls-gl/build
rm -rf coreutl
mkdir coreutl
cd coreutl
CC=${TARGET}-gcc AS=${TARGET}-as AR=${TARGET}-ar LD=${TARGET}-ld RANLIB=${TARGET}-ranlib \
../../src/coreutils-6.3/configure \
--prefix=/usr \
--program-prefix= \
--target=${TARGET} \
--build="i686-pc-linux-gnu" \
--host=${TARGET}
make
sudo make install
ビルドが成功したら、suコマンドだけをLS-GL本体にコピーします。一応、動作したようなので成功かな?w
おまけにsuコマンド置いておきます、但し完全無保証なので、使用によるいかなる損害、損失について当方は一切責任を負いません。
試行錯誤の上の結果なので、不要な作業が入ったままかもしれません。まだまだ改良の余地はあるでしょうが、取り合えず今回はここまでとします。