GdiumでOpenBSDの動作確認を行うため、カーネルをクロスビルドしました。最初は無難にOpenBSD上で行い、同じ動作を他のOSで再現するという手順を採りました。
- OpenBSD(i386)上でOpenBSD(mips64el)カーネルとユーザーランドをクロスビルド
- Interix上でOpenBSD(mips64el)カーネルをクロスビルド
- Hurd上でOpenBSD(mips64el)カーネルをクロスビルド
ビルドしたカーネルはGdiumで起動中にパニックします。それを修正するため、日常的に使っている環境でクロス開発できるようにしました。Interix上でOpenBSDの開発というのは一見無茶な組み合わせですが、実はそうでもありません。なぜかというとInterixのlibcの一部はOpenBSD由来で、他のUNIXに比べて親和性があるためです。
OpenBSD(i386)
OpenBSD上で他のアーキテクチャのカーネルをクロスビルドする手順は驟雨さんがまとめています。
- id:syuu1228:20090805 : OpenBSD/sgi クロス開発環境の構築
Gdiumはloongsonアーキテクチャですが、loongsonサポートはつい最近CVSにコミットされたばかりで、CVSからcurrentを取得する必要があります。sgiもloongsonもmips64ですがエンディアンが異なるため、ビルド時にエンディアンを区別する必要がありますが、そのための修正はCVSにはコミットされていません。後述のビルドツールに同梱しているので参照してください。
Interix
OpenBSD上でのビルドの動きを見ていると、ビルドに必要なコマンドを用意すれば他のOSでもビルドできそうです。
真っ先に必要になるのはmakeです。OpenBSD特有のマクロを使用するため、GNU makeでは代用できません。OpenBSDのソースから抜き出してビルドできるように改変しました。GNU makeなどと区別するためobmakeという名前で/usr/local/binに入れてビルドプロセスを試しました。
TARGET=loongson obmake cross-gcc
プロセスが進むうちにコマンドがなかったり非互換だったりでエラーが出ます。その度にコマンドを持って来ることを繰り返して、最終的には以下のコマンドを用意すればカーネルのビルドまで完了しました。
- make, mkdep, config, mtree, readlink, rpcgen, compile_et
binutilsやgccは本来のビルドプロセスに含まれているため、別途用意しなくても問題ありません。
ビルド中に構築される仮想ルートで所有権の設定を試みますが、Interixにはrootやwheelなどが存在しないためエラーになります。そのため所有権を無視したコマンドも用意しました。
- chown, install
こうして用意したコマンドだけを、OpenBSDのソースツリーから抜き出してビルドできるようにまとめました。
Debian/Interix環境で以下のパッケージがインストールされていることが前提です。Debian/Interixについてはid:n7shi:20091214とid:n7shi:20091215を参照してください。
環境が整えばクロスツールのインストールは簡単です。
make install
OpenBSDのソースを/usr/srcに展開します。前述のエンディアンやInterix特有の問題などを修正したパッチがpatch/cross.diffにあるため適用します。CVSの時期によってははじかれる可能性があるため、はじかれた場合は手動で対処が必要です。
パッチを適用後、ソースツリーに移動してビルドします。カーネルのビルドには大量の環境変数を設定する必要があるため、cross-wrapperとして環境変数をシェルスクリプトにダンプできるように改変しています。
cd /usr/src TARGET=loongson obmake cross-gcc TARGET=loongson obmake cross-wrapper ← 独自拡張 mv cross-wrapper /usr/local/bin/loongson cd sys/arch/loongson/conf obconfig GENERIC cd ../compile/GENERIC loongson obmake depend loongson obmake
この手順は複雑なため一発でできるようにも改変しましたが、今回はカーネルを修正しながら何度もビルドするのが目的のため、あまり意味はありません。
cd /usr/src TARGET=loongson obmake cross-kernel ← 独自拡張
RAMDISKカーネルにはディスクイメージを入れる必要がありますが、前述の所有権やディスクイメージのマウントなど問題が山積しているため、OpenBSDでビルドしたイメージを持って来るのが現実的です。
それ以前の問題として、現段階ではルートのマウントの前にカーネルパニックしてしまうため、RAMDISKカーネルを用意しても意味がありません。パニックせずにルートのマウントまで進むようにカーネルをハックするのが先です。RAMDISKについてはその後で考えることにします。
Hurd
Interixで成功したので、Hurdでも試みました。基本的なやり方はInterixと同じですが、前述のようにInterixはOpenBSDに近いため比較的簡単で、Hurdではそれよりもかなり手間が掛かりました。一部の関数はOpenBSDから持って来るのが困難だったため、NetBSDのpkgsrcの互換レイヤ(libnbcompat)から持って来ました。
Hurdで動くようにしたものを置いておきます。readlineは注意が必要で、libreadline6-devではなくlibreadline5-devをインストールしてください。基本的にInterix版にHurd対応コードを付け足したものなので、config.mkを書き換えればInterixでも使えます。
Hurd対応というより実質的にglibc対応です。そのためglibcを使用する他のOS(Debian GNU/kFreeBSDなど)でも少しの修正で使用できると思われます。
ちなみにこれをkではないオリジナルのFreeBSDに持って行くと大量のエラーが出ます。OpenBSDとFreeBSDとで同じ定義が重複するためです。それらはもともと存在して互換レイヤとして必要ないものですから、削ればうまくいくと思われます。