8月 172015
 

前回のエントリは「FreeBSD/arm の ports コンパイル環境の作成。」というヤツを書きました。

ports の ports-mgmt/poudriere-devel/ というのを利用すると FreeBSD/arm のクロスコンパイル環境ができますよ。っていうやつです。

しかし、環境構築が大変すぎる。もっと簡単にできないのか?などと思うわけですね。環境構築に時間が掛かり過ぎる点は以下の辺り。

・FreeBSD のソース一式を svnweb から取ってきて make buildworld する。
・ports ツリー一式を portsnap で取ってきてインストールする。

時間が掛かり過ぎるよー。ってんで、今回はもっとお気楽に環境を構築する案を思いつきました。

ports-mgmt/poudriere-devel/ は jail に FreeBSD/arm のバイナリの環境を構築して qemu でエミュレートして動作しているようです。そのためにソースコード取ってきたり ports ツリー取ってきたりしているんですが、既にあるものを使おう。ってのが今回の趣旨です。

 
1). 準備するモノ
まずは Raspberry Pi 2 に FreeBSD をインストールします。多分 CURRENT が良いのかもしれないです。
Raspberry Pi 2 用の img を用意して SD カードに dd したら、同じバージョンの FreeBSD/amd64 の iso イメージもダウンロードしてきて、仮想環境に FreeBSD/amd64 をインストールします。あ。実機にインストールしても全然良いんですけどね;-)。

僕の場合、は以下のような環境を作りました。

o. Raspberry Pi 2 の FreeBSD/arm

FreeBSD wanchan.running-dog.net 11.0-CURRENT
FreeBSD 11.0-CURRENT #0 r284544: Thu Jun 18 19:36:01 UTC 2015
root@releng2.nyi.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI2  arm

 
o. 仮想環境上の FreeBSD/amd64

FreeBSD nyanchan.running-dog.net 11.0-CURRENT
FreeBSD 11.0-CURRENT #0 r284544: Thu Jun 18 12:24:12 UTC 2015
root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

 
ちなみに、仮想環境上の FreeBSD/amd64 が母艦になります。ここで FreeBSD/arm の ports の make をする予定です。

この後、母艦側で ports の emulators/qemu-user-static/ をインストールします。

これで、ほぼ九割の環境が整いました;-)。

ports-mgmt/poudriere-devel/ とかインストールする必要はありません。 jail 環境用に make buldworld もする必要はありません。

と、いうことでここでだいたいの構成がわかってきたと思いますが;-)。

 
2). 環境構築
まず、 Raspberry Pi 2 側の FreeBSD/arm で nfsd を起動します。

以下は /etc/exports の設定内容。

/   -network 192.168.1.0 -mask 255.255.255.0 -maproot=root
/   -network 2001:470:fe36:1234::/64 -maproot=root

 
強引ですねぇ。 / を NFS mount するようにします;-)。
あ。/etc/rc.conf の設定は今回は書かないです。

 
続いて母艦側の FreeBSD/amd64 側で nfs client を有効にします。こちらも /etc/rc.conf の設定は書かないですが、大丈夫ですね?

あとは母艦側で mount_nfs を実行します。

# mount_nfs -o rw wanchan:/ /home/armv6

 
うひょー。これで ports-mgmt/poudriere-devel/ でいうところの jail 環境ができてしまいました。ちょっと強引ですが。しかし、 make buildworld したのと一緒の状態ですね;-)。

一個、そして一回だけ、以下のコマンドを打ちます。

# cp -pr /usr/local/bin/qemu-arm-static /home/armv6/usr/local/bin/

 
FreeBSD/arm 側の /usr/local/bin/ に FreeBSD/amd64 上でコンパイルした qemu-arm-static をコピーしてあげます。これで準備は全て整いました。

 
まぁ、FreeBSD/arm の環境一式は色々抜き出すことができます。例えばインストールの iso イメージを mount して抜き出すとか、 ports-mgmt/poudriere-devel/ をインストールしてできた jail 環境を tar で固めて持ってくるとかですね。

しかし、 make buildworld を走らせるのは辛すぎる・・。ってのが今回の根本にあります。
make buildworld するより OS 二つインストールしたほうが速くないかい? みたいな;-P。

 
3). 環境構築スクリプト
まずは下に起動用のサンプルを書きますね。

#!/bin/sh

HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin/:/usr/local/bin
export HOME PATH

export LC_CTYPE=ja_JP.UTF-8
export LANG=ja_JP.UTF-8

ARMV6DIR='/home/armv6'

kldload imgact_binmisc.ko

binmiscctl add armv6 --interpreter "/usr/local/bin/qemu-arm-static" --magic "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00" --mask "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" --size 20 --set-enabled

mount_nullfs -o rw /usr/ports ${ARMV6DIR}/usr/ports
#mount -t devfs devfs ${ARMV6DIR}/dev

chroot ${AMD64DIR}

 
解る人は何をしているか解ると思います。

jail 環境作るの大変なので直接 Raspberry Pi 2 の FreeBSD/arm の環境を利用してしまいます。
そして chroot しています。 jexec でなくとも chroot で十分なのでそうしているんですが。

ちと説明をすると、

kldload は自動的にしてくれると思います。

binmiscctl add armv6 の行は qemu を使うおまじないです。このコマンドを叩かないと chroot したときに /bin/tcsh えぐぜっくふぉーまっとえらー。とか言われます。

FreeBSD/arm 側に母艦の /usr/ports を mountしてあげます。これで portsnap で ports ツリー一式取ってくる必要がなくなります;-)。

mount -t devfs は多分必要ないと思います。 jail 環境の場合は必要なのですが、今回は nfs mount した環境なのですねぇ。

と、いうことで最後に chroot します。

うひひ。これで FreeBSD/amd64 上に FreeBSD/arm の環境が整いました。ports のコンパイルや(多分)カーネルのコンパイルなど、もう何でもできます;-)。

このスクリプトは別途置いといたのでダウンロードしてください。ブログだと binmiscctl add armv6 の行が全部表示できないので・・。

 
ちなみに FreeBSD/arm 側が CURRENT で母艦側が 10.1-RELEASE だったりすると ports のコンパイル時に uname -r のチェックでエラーになってしまいます。 chroot した FreeBSD/arm 側で uname -r すると母艦側のバージョン情報を返してしまいます。あたたた。なので、 FreeBSD/arm 側と母艦側では FreeBSD のバージョンを揃える必要があります。

が、uname には裏ワザがあるようで、

$ uname -r
10.1-RELEASE-p16
$ setenv UNAME_r 11.0-CURRENT
$ uname -r
11.0-CURRENT
$

 
おやおや。環境変数で uname -r が変更できるのね。と、いうこで母艦が 10.1-RELEASE-p16 で FreeBSD/arm 側は 11-CURRENT の状態で ports を make してみましたが ports のコンパイルが始まって configure の実行中に「存在しないシステムコール (core dumped)」などと言われてコンパイルが途中で止まってしまうのでありました。

ふむ。10.1-RELEASE から 11-CURRENT で機能が追加された分があったりして、その辺りが問題となってしまうのでしょうなぁ・・。まぁ、取り合えずはこの環境で利用するのはやめて、母艦側も FreeBSD/arm 側もバージョンは揃えた。と、いうことになります。

 
2015/08/18 加筆
母艦側の FreeBSD/amd64 と FreeBSD/arm 側でバージョンが違っていてもコンパイルできることが解りました。 母艦側の /usr/local/bin/qemu-arm-static と FreeBSD/arm 側のヤツを同じモノにすると無事に動作します。
母艦側の /usr/local/bin/qemu-arm-static は 10.1-RELEASE-p16 で make したモノ、 FreeBSD/arm 側のヤツは 11.0-CURRENT で make したモノ。と、いうふうに異なるバージョンで make したものがインストールされていると「存在しないシステムコール (core dumped)」と出て動作しません。
/usr/local/bin/qemu-arm-static は母艦側で make したものを FreeBSD/arm 側に cp してあげましょう。

 
4). 実際に使ってみると
ports の make は一応問題無しですね。母艦側で make install したやつは FreeBSD/arm で pkg info で見るとちゃんと見えます。 portmaster -D -a も無事に動きます。

しかし、遅い・・。今回の母艦側仮想マシンは CPU 4Core に 1GB のメモリを用意したのですが遅いです。
FreeBSD/arm を NFS しているし SD カード上に入っているのでディスクアクセスが遅いのかもしれません。

それにしても chroot した先で色々動かすと全て qemu がワンクッション入るのでそれが遅いのかもしれません。僕はまだ本格的に qemu を使ったことが無いのでアレですが、パフォーマンスチューニングすればもっと速くなるのかな?

28468 1 I  0:01.76 /usr/local/bin/qemu-arm-static /bin/tcsh -i
28672 1 S+ 0:00.83 qemu-arm-static -L /usr/gnemul/qemu-arm /usr/bin/make install
28689 1 R+ 0:00.48 qemu-arm-static -L /usr/gnemul/qemu-arm /usr/bin/make config

 
母艦側で ps -ax するとこんな感じで chroot 先の全てのプロセスが qemu 経由で動いております。

 
母艦側で ports のコンパイルとかすると、遅いけど律儀に進んでいきます。そのとき FreeBSD/arm 側では CPU ロードアベレージは低いままなので、頑張っているのは母艦側。と、いうことになり、遅いけど Raspberry Pi 2 は無傷な状態ですね。

 
とまぁ、こんな感じの FreeBSD/arm のクロスコンパイル環境なのですが、それにしても qemu が絡むと遅くてしょうがない(と、僕は思っているんだけど、本当に qemu が原因なのか、僕はまだ特定していません・・f(^^;;)。

その昔、 Linux で BB ルータ作っていたんですが、組み込み Linux の ARM のバイナリを i386 の Linux 母艦で作っていたときは qemu 使ってなくて、もっとサクサクとコンパイルができていたんだけど・・。
qemu を使わずに ports をコンパイルする方法をやっぱり見つけないとダメっぽい。ってのが、今回の結論でしょうかねぇ。

それにしても ports-mgmt/poudriere-devel/ で色々仕掛けが解ったので良かったです。そして、それを参考にして ports-mgmt/poudriere-devel/ を使わない、もっと楽したコンパイル環境構築がこうして解ったわけですしね。ネタになったかぁ? ;-)。

次回、qemu を使わない ports のコンパイル環境の構築について掲載できるか?! (多分無理;-)

実は某所で発表した FreeBSD/arm に関する資料があるのですが ports のコンパイル環境構築についても触れています。その時は qemu を使わずに頑張ったのですが、結局ダメでした。その資料を一応おいておきますね。

FreeBSD/arm Raspberry Pi 2 ModelB で動作確認

 
ちなみに文章は Microsoft Office2013 で作りましたが、資料の発表は okular (KDE 4 universal document viewer) で行いました。 calligrastage (KDE graphic art and office suite) では文章を作成するのに苦痛でして・・f(^^;;。
そして、okular は pptx をサクっと開けてしまうすぐれものです;-)。