前回(結局やってるzxLinux)の dhrystone テストの結果ですが、よくよく考えたら、 60MHz 前後のシンプルな RISC CPU と考えればものすごく妥当な値ですよね。 だから、逆にプログラムの動作は正しかったのではないかと考えられます。 (あくまで MI-C1 の SH3 CPU が 60MHz であるとの仮定によりますけど) dhrystone はコンパイラオプションの選定次第でさらに数値が変わりますので、 興味ある方は挑戦してみてください。
前回(結局やってるzxLinux) 発覚した float による実数演算を使うと固まってしまう問題を、 もう少し詳しく調べてみました。 まずは詳しい条件出しを行いました。
いくつかのテストプログラムを走らせてわかったのは、 どんな演算であれ float 値を使った計算をした時点で 止まってしまう(おそらくシステムエラーになっている)ことです。 他の型からのキャストでも同様。
float 時にのみ問題が発生するケースとして、 良くあるのが関数コール時にスタックに積む値のサイズを間違えてしまうこと。 Traditional なCコンパイラでは、 float も double に型変換してからスタックに積む規則になっていました。 ANSI-C で仕様変更されたので、 Traditional な挙動を期待していると動かないコードができることがあります。
さらに思考を巡らせていてふと思いついたのが CPU の違いです。 実は以前から疑問に思っていた点があります。 なぜコンパイラのプロセッサ別ライブラリに m3 が無くて m3e しかないのか。 SH3 用のライブラリが他にないので、 これまでは仕方なく m3e を選択していたわけです。
/usr/local/zxlinux/lib/gcc-lib/sh-hitacih-elf/2.95.2 以下のフォルダを見てみると、次のようになっています。 ここにはリンクすべき libgcc.a が CPU 別に置いてあります。 (さらに ml の下がリトルエンディアンバージョンです)
# ls -l /usr/local/zxlinux/lib/gcc-lib/sh-hitachi-elf/2.95.2 total 4717 -rw-r--r-- 1 root root 88205 Jan 27 02:52 SYSCALLS.c.X -rwxr-xr-x 1 root root 4047026 Jan 27 02:52 cc1* -rwxr-xr-x 1 root root 195220 Jan 27 02:52 collect2* -rwxr-xr-x 1 root root 275051 Jan 27 02:52 cpp* drwxr-xr-x 2 root root 1024 Jul 22 00:45 include/ -rw-r--r-- 1 root root 188794 Jan 27 02:52 libgcc.a drwxr-xr-x 2 root root 1024 Jan 27 02:52 m2/ drwxr-xr-x 2 root root 1024 Jan 27 02:52 m3e/ drwxr-xr-x 2 root root 1024 Jan 27 02:52 m4/ drwxr-xr-x 2 root root 1024 Jan 27 02:52 m4-single/ drwxr-xr-x 2 root root 1024 Jan 27 02:52 m4-single-only/ drwxr-xr-x 7 root root 1024 Jan 27 02:52 ml/ -rw-r--r-- 1 root root 1813 Jan 27 02:52 specs |
m2 が SH2、m4 が SH4 を指しているであろうことは明白です。 m4-single(-only) はおそらく、浮動小数演算の単制度版ではないかと思います。
SH4 は FPU を内蔵しており、3D 演算等に特化した専用の積和演算器を持っています。 マトリクスやベクトル演算の専用命令まで備えています。 リアルタイム 3D の演算は、精度よりも速度を優先することが多いので、 これらの命令は単精度であり、 また SH4 も単精度演算を非常に高速に行えるようにできています。 そのため SH4 は、単精度演算は高速なものの、 倍精度演算モードでの計算はさほど速くありません。 精度をとるか速度を取るか、 ライブラリも選択できるようになっているのではないでしょうか。
話がそれましたが、問題は m3e の方です。 SH3 アーキテクチャには SH3、SH3E、SH3-DSP の3種類があります。 それぞれノーマル、FPU付き、DSP付きです。 それを考えると m3e は SH3E のことで、 m3e は FPU 用のライブラリではないかと推測できます。
Zaurus が使っている CPU はノーマルの FPU 無し SH3 です。 なので、リンクするライブラリを試しに、 同じように FPU がない SH2 用の m2 に変更してみます。
ZGCCLIB = $(ZTOP)/lib/gcc-lib/sh-hitachi-elf/2.95.2/ml/m2 |
この設定でコンパイルしてみると、 なんと float の実数演算を使ったプログラムも 正しく実行できるようになりました。
zxLinux のカーネルやバイナリキット付属のコマンド類も ml/m3e を使ってるようなのですが、果たしてどっちが正解なのでしょうか。
開発に使っているノートPC の方の Linux です。 HDD 容量が 800M しかないので、 zxLinux 開発環境を展開して、 ソースを展開して、すでに容量がいっぱいになってしまいました。 UNIX 用のコマンドソースを展開してコンパイルテストをするどころか、 これだとオリジナルソースを展開できないのでパッチも作れません。
容量が足りないから最初から X-WINDOW とかは入れてませんけど、 zxLinux 開発をするのであれば、もっとディスク容量が必要だというお話でした。
他にもいろいろとコマンドをコンパイルしてみようとはするのですが、 どっちかというと「zxLinux でも通りそうなコマンドを探している」感じです。 コンパイルできて一見動いても、 ちょっとまだファイルアクセス周りの挙動が若干おかしいようです。 詳しくは調べていませんけれど。
コンパイルで良く引っかかるのが newlib の dirent.h です。 newlib の dirent は実装されておらず、 内部でエラー停止するような構造になっています。(無限include) opendir, readdir を実装しようとすると、今度は zx_syscall.c でシステムコール側の readdir とシンボルが衝突します。 zx_syscall のインターフェース名は、一度全部変更した方が良いのかもしれません。
ちなみにシステムコールの readdir、zx_syscall.c 内部で行っている処理と Linux のマニュアルと違いがあるので、 呼び出し先のカーネルを追っていったら、 内部でも動作は未定義(return -ENOSYS;)になっていました。 現在の zxLinux のカーネルは 2.3.23 です。
おかしければ原因を見つけて直すというデバッグスタイルよりも、 まとまった時間を作ってライブラリから きっちり作っていった方が良さそうな気がします。
何もなければ作るだけ、 またはバグがあるなら直すだけ。 ソースも開発環境も全部公開されてるので、 これくらいならばまあ、当たり前と思って普通にこなしても構わないんですよ。 気になるのは、 やってることも引っかかる点も あまりに基礎的な(初歩的すぎる)部分だということです。
zxLinux が3月に公開されてからすでに 4ヶ月。 カーネルやライブラリの更新が無いとしても、 誰かちょっと使ってみればすぐわかるようなところばかりでいいんでしょうか。
これくらいしかありません。 zxls000.lzh は、ファイル書き込みのデバッグで、 必要に迫られて作った ls コマンドです。 バイナリキットの ls では、ファイルサイズやタイムスタンプ、パーミッションも 確認することができなかったので、本当にとりあえずです。
・zxls000.lzh
lsコマンド
・rtpatch.lzh
rt-src に加えた修正
・newlibpatch.lzh
newlib に加えた修正
zxLinux 関連の情報ページを こちら に作成しました。
[メニューに戻る] | [ZAURUS総合] | [DirectX] | [Ko-Window] | [Win32] | [WinCE] | [携帯電話] | [その他] |
フルパワー全開 | Hyperでんち |