nfsd とか top とか、細々としたのを make しているうちにキレた。 emacs クラスの大物なら自前で build する気にもなるが、ちまちまといちいち make してまわるのはかなわん。 まとめて全部一括で Debian woody に面倒みてもらうことにする。 しかし、いまの Debeian woody バイナリの多くは libc に glibc 2.2.3 or higher を要求するため、 SL-A300 のデフォルトの 2.2.2 では足りない。
Woody の 2.2.5 をそのまんまつっこんでもいいのだろうが、 それこそ最適化ついでもあって自前で build という話。 実は build そのものは時間食うわりに手間は大したことない。 どっちかってーと、問題はそのあとだ。
# pushd /opt/Embedix/tools/arm-linux/include # mv asm asm.old # mv linux linux.old # pushd # bzip2 -d < linux-sla300-20020905.tar.bz2 | tar -xv # cd linux # cp arch/arm/def-configs/discovery-MV .config # make menuconfig # make depend # cd include # tar -cvp asm-arm asm-generic linux | tar -xpC /opt/Embedix/tools/arm-linux/include # cd /opt/Embedix/tools/arm-linux/include # ln -sf asm-arm asmasm-generic もコピーしたが、asm-arm の一部が参照してたので。 glibc じゃないけど、実際なんだかのアプリを make したときにひっかかったから、たぶん必要なんだろう。
% apt-get source libc6
% cd glibc-2.2.5
% export PATH=/opt/Embedix/tools/bin/:${PATH}
% export LINUX_SOURCE=/opt/Embedix/tools/arm-linux
% fakeroot dpkg-buildpackage -aarm
% cd ..
% fakeroot alien --to-tgz libc6_2.2.5-6_arm.deb
これで build から binary package 作成までまとめて面倒みてくれた。楽になったなぁ。
時間のほうはあいかわらずかかるけど(セレロン 300MHz で約 100 分) ...
いかにも linux のソースを指定するようにみえる "LINUX_SOURCE"
には本物の kernel source tree を指定してもいいが、
include ファイルの一部を libc6-dev 作るときに一緒にまとめてパッケージングするのに要るだけなんで、
指定しないでおいて libc6-dev 作るトコでわざとエラー起こさせて build を止めさせてもいい。
この時点で libc6 のほうは全部出来上がってるので困ることはない。
ということで、 何の気兼ねもなく出来上がった libc 2.2.5 とかをまとめて SL-A300 に持ち込んだらちゃんと動いた。 もしかすると locale も見てる konsole あたりの挙動がアヤしいかもしれないが、 どーせその場合は konsole のほうを書き換えるから、これでいい。 つーか、もともと /usr/lib/locale が空なんだから、 2.2.5 でヘンだったら 2.2.2 でもヘンな動作のはずだろう。
なお、ここで不精して RAM に置くとハングするので注意。
正しい ld-linux.so.2 が /lib (ROM 上にあるはずだ) になければならず、
そして glibc 2.2.2 に付属する ld-linux.so.2 (ld-2.2.2.so) は glibc 2.2.5 に対応していない。
逆に ld-2.2.5.so のほうは glibc 2.2.2 と組んで使えるけど。
← つまりハングさせたわけね。
しかし、これがどこをどーいじっても最後までいかずに途中でとまる。 たいがいパッケージをつくるちょい手前の、ファイルを用意する段階でコケる。 諦めてファイルかきあつめて SL-A300 につっこんだら、 /sbin/init が segmentation fault を起こした。 なんとなくそんな気はしたんだ ... -fomit-frame-pointer 付けてるし。 GNU の巨大アプリ/ライブラリで -fomit-frame-pointer 付けてまともに動いたためしねーもん。
というわけで、libc6-opt 経由での最適化はボツ。
を置き、debian/sysdeps/sysdeps.mkにMIN_KERNEL_SUPPORTED := 2.4.5
とした:HOST_CFLAGS = -pipe -O6 -funroll-loops -fstrict-aliasing
MIN_KERNEL_SUPPORTED (--enable-kernel) による挙動の違いは sysdeps/unix/sysv/linux/kernel-features.h にある。arm では 2.4.0, 2.4.4 あたりで挙動が変わる。せっかくだから 2.4.5 と指定。これは要するに
といった構造の後半分がなくなるだけなので system call が成功するケースではビタ一文速くなんないが、 ... 失敗するケースではちったー効果あるんかなぁ(ベンチかけてないので弱気)。 ただ system call というのはかなりの高率で失敗するんよね。だから指定してみたんだけど。 HOST_CFLAGS のほうは xscale のパイプラインストール対策っつうことで -funroll-loops 指定。 これによる libc のファイルサイズ増加は 10% 強。速度寄与分はそれ以上だろうからこれは文句なし。2.4.0 以上に存在する system call 実行 もしエラーなら、 2.2.0 に存在する system call 実行
いずれにせよ最適化についてはベンチかけんと何も言えん。 けどベンチかけるんも ROM 書き戻しとかめんどくさい ...
名前が違う (libc-2.2.2.so と libc-2.2.5.so etc.) から、cp で上書きできないばかりでなく symlink 先も違う。SL-A300 中では ROM の中だから SL-A300 に移ってから ldconfig で symlink 一気張り替えというわけにもいかず、 ひとつひとつ手で張り換える ... のは多分 unix 的には間違いで、 script 書いて半自動で一気に書き換えるべきなんだろうが、なにしろファイルの取捨選択で人の判断が入る。 libnss_nisplus まで cp する必要はねーだろ、とか。
いったん rm して tar でまるごとコピーして必要なさそうなものを消していくのがはやそうだが ... libe2p, libext2fs など glibc 由来でないライブラリも /lib に入ってるので、 忘れずに戻さないといけない。
というわけで、結局ディレクトリ見比べてのファイルの名前比較っつう作業が省けないのであった。
libc のコンパイルオプション サイズ(バイト) Normal 1190788 libc6-opt 1238360 動かず :-< unroll-loop したやつ 1349236 現用 SL-A300 付属のやつ 1152468 ROM ver1.1 の glibc 2.2.2
この 200KB のサイズ増加そのほかの理由で cramfs は 14811136 バイトにおさまりきらなくなった。 15073280 バイト以下ではあった (15056896 バイト...) のでそのまま ROM に書き込んで、 いまも普通に使えている。
SL-5000 系のカーネルソース見たらこっちの ROM disk のサイズは 14811136 バイトで、 "14811136 バイト" の上限は合理的だった。 シャープさんてば、SL-A300 に持ちこむ時に何も考えずにドキュメントや script 作ったに違いない。
... ま、でも libncurses は libc と違って /usr/lib において /lib のを上書きしてもいいからね。 あとまわしってことで。