【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

クロス開発環境構築

GdiumでOpenBSDの動作確認を行うため、カーネルをクロスビルドしました。最初は無難にOpenBSD上で行い、同じ動作を他のOSで再現するという手順を採りました。

  1. OpenBSD(i386)上でOpenBSD(mips64el)カーネルとユーザーランドをクロスビルド
  2. Interix上でOpenBSD(mips64el)カーネルをクロスビルド
  3. Hurd上でOpenBSD(mips64el)カーネルをクロスビルド

ビルドしたカーネルはGdiumで起動中にパニックします。それを修正するため、日常的に使っている環境でクロス開発できるようにしました。Interix上でOpenBSDの開発というのは一見無茶な組み合わせですが、実はそうでもありません。なぜかというとInterixのlibcの一部はOpenBSD由来で、他のUNIXに比べて親和性があるためです。

OpenBSD(i386)

OpenBSD上で他のアーキテクチャカーネルをクロスビルドする手順は驟雨さんがまとめています。

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

binutilsgccは本来のビルドプロセスに含まれているため、別途用意しなくても問題ありません。

ビルド中に構築される仮想ルートで所有権の設定を試みますが、Interixにはrootやwheelなどが存在しないためエラーになります。そのため所有権を無視したコマンドも用意しました。

  • chown, install

こうして用意したコマンドだけを、OpenBSDのソースツリーから抜き出してビルドできるようにまとめました。

Debian/Interix環境で以下のパッケージがインストールされていることが前提です。Debian/Interixについてはid:n7shi:20091214とid:n7shi:20091215を参照してください。

  • binutils, bison, flex, gcc, groff, install-info, libreadline5-dev, texinfo

環境が整えばクロスツールのインストールは簡単です。

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に持って行くと大量のエラーが出ます。OpenBSDFreeBSDとで同じ定義が重複するためです。それらはもともと存在して互換レイヤとして必要ないものですから、削ればうまくいくと思われます。