- FreeBSD Linuxulator explained
docs - FreeBSDにはLinuxバイナリ互換機能が用意されています。通称Linuxulatorとも呼ばれます。LinuxulatorはLinuxエミュレータではなく、
バイナリインターフェースと若干のトリックを追加する機能で、 基本的にFreeBSDはネイティブにLinuxバイナリを実行します。Adobe ReaderやSkypeを使っているFreeBSDユーザは少なくないと思いますが、 これらアプリケーションはLinuxバイナリのアプリケーションです。 どういった仕組みでこれを実現しているのかの説明がThe FreeBSD-linuxulator explained (for users) | Alexander Leidingerに掲載されていて参考になります。
The FreeBSD-linuxulator explained (for users)ではまず、
カーネルの基本的な動作を紹介しています。FreeBSDカーネルはELFファイル (実行ファイル) を読み込むと、 それがFreeBSD ELFであるかLinux ELFであるか判別します。FreeBSD ELFの場合にはFreeBSDテーブルを使って、 Linux ELFである場合にはLinuxテーブルを使ってプログラムの実行にとりかかります。テーブルはパラメータやポインタが含まれたデータで、 カーネルはこのテーブルを使ってシステムコール関数など対応するものを探して実行に利用します。FreeBSDバイナリもLinuxバイナリも基本的には同じ仕組みで動いているため、 LinuxバイナリはFreeBSDバイナリとほとんど同じ速度で動作します。 ただし、
FreeBSDカーネルとLinuxカーネルのシステムコールは若干違うところがあるので、 いくつかのシステムコールに対してはトランスレーションが実施されます。FreeBSDカーネルが解釈できるシステムコールに変換してからシステムコールを呼んで処理を実施するというわけです。 もう1つの基本的なトリックとしてパスのトリックも紹介されています。Linuxバイナリが/pathto/
Aにアクセスしようとした場合、 FreeBSDカーネルはまず/compat/ linux/ pathto/ Aがあるか調べ、 なければ/pathto/ Aへアクセスします。こうすることで/compat/ linux/にインストールされるLinuxバイナリやLinuxライブラリを優先的に使いながらも、 /compat/ linux/に存在せずFreeBSDのみ存在するファイルやデータにもシームレスにアクセスできるようになっています。 /compat/
linux/以下にはPorts Collectionからlinux_ baseの内容物がインストールされています。Linuxアプリケーションを実行するために必要になる基本的なバイナリやライブラリのパッケージがインストールされています。ただし、 そのままインストールしているのではなく、 次のような変更が加えられています。 - Linuxバイナリであることをインストール時にマークする
- FreeBSDカーネルがサポートしていない機能を使うバイナリやライブラリは削除してインストールしない
- すでにFreeBSDに同一のパスで同一のファイルがあり、
インストールする必要がないものは削除してインストールしない - /etc/
passwdや/etc/ groupなどのようにFreeBSDのファイルを見に行ってほしいものについては削除してインストールしない - FreeBSDとシームレスに統合されるように設定ファイルなどを変更する
Linuxバイナリを実行しようとして
「ELF file OS ABI invalid」 といったメッセージが出力されるのは、 Linuxに適切なライブラリがないか、 または先にFreeBSDライブラリがローダによって読み込まれることが原因です。Linuxライブラリが先に検出されるように設定を変更するか、 そのライブラリがない場合には/compat/ linux/以下にインストールします。 The FreeBSD-linuxulator explained (for users)では、
/compat/ linuxにchroot(8)する場合にも言及しています。なんの作業をするかにもよりますが、 linux_ baseで/compat/ linux/にインストールされる内容物は基本的なものだけなので、 フルディストリビューションを期待してchroot(8)すると問題が発生するだろうということです。そうした場合、 linux_ dist (emulators/ linux_ dist-gentoo-stage3など)のようにフルディストリビューションをインストールして、 そちらにchroot(8)すればいいと説明されています。