原作: Brian N. Handy <handy@sxt4.physics.montana.edu> and Rich Murphey <rich@FreeBSD.ORG>
訳: はらだ きろう <kiroh@jp.FreeBSD.org>. 24 September 1996.
FreeBSD での Linux エミュレーションは, 大部分の Linux バイナリ(a.out および ELF フォーマット)を実行できる状態になっています. 2.1-STABLE ブラン チでのエミュレーションでは, Linux DOOM や Mathematica が実行できます. 3.1-RELEASE でのエミュレーションは, さらに強化されており, Linux 用 の Quake, Abuse, IDL, netrek など, 多数のソフトウェアが実行できます.
Linux オペレーティングシステムには, 特有の機能がいくつかあり, FreeBSD でサポートされていないものもあります. Linux の /proc ファイルシステム を使ったバイナリは, FreeBSD では実行できません (FreeBSD で使用可能な /proc ファイルシステムとは仕様が異なっているためです). また仮想8086モー ドを有効にするなど, i386 に特有なシステムコールを使っている場合も実行 できません.
Linux エミュレーションの設定方法は, 使用している FreeBSD のバージョン によって多少異なっています.
2.1-STABLE の GENERIC カーネルは, Linux との互換性を保つように構築 されていません. カーネルの再構築が必要です. 再構築をおこなうには, 2つの方 法があります. 1つは, エミュレータをカーネル自体にスタティックリンクす る方法. もう1つは, 動的に Linux ローダブルカーネルモジュール(LKM)をロー ドするようにする方法です.
エミュレータを有効にするには, 以下をコンフィグレーションファイル (/sys/i386/conf/LINT など) に追加します.
options COMPAT_LINUX
Linux DOOM などのアプリケーションを実行したい場合は, 共有メモリも有効 にしておかなければなりません. 以下を追加します.
options SYSVSHM
Linux のシステムコールを使用するには, 4.3BSD のシステムコールとの互換 性が保たれていることが必要です. 以下の行が含まれていることを確認してく ださい.
options "COMPAT_43"
LKM を使用せずエミュレータをカーネルにスタティックにリンクしたい場合は, 以下の行を追加します.
options LINUX
FreeBSD カーネルのコンフィグレーション の節の記述に したがって config と, 新しいカーネルのインストールをおこなってください.
LKM を使用する場合は, ローダブルモジュールをインストールしなければなり ません. カーネルとローダブルモジュールのバージョンが異なると, カーネル がクラッシュする場合がありますので, 安全を期すためには, カーネルをイン ストールするごとに, LKM も再インストールしてください.
# cd /usr/src/lkm/linux # make all install
カーネルと LKM のインストールが終了したら, root で `linux' コマンドを 実行することで LKM をロードできます.
# linux Linux emulator installed Module loaded as ID 0 #
LKM がロードされたかどうかを確認するには, modstat を実行します.
% modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 3 f0baf000 0018 f0bb4000 1 linux_emulator
システムブート時に, LKM をロードするようにするには, 2つの方法がありま す. FreeBSD 2.2.1-RELEASE または 2.1-STABLE では, /etc/sysconfig を,
linux=YESのように, NO を YES に変更してください. FreeBSD 2.1-RELEASE およびそれ以 前のバージョンでは, そのような行はありませんので, /etc/rc.local に以下 の行を追加する必要があります.
linux
options LINUX や options COMPAT_LINUX を指定する必要 はなくなりました. Linux エミュレーションは LKM(``ローダブルカーネルモジュール'') を使用して, リブートせず簡単にインストールできます. スタートアッ プファイルで以下のように指定します.
/etc/rc.conf に以下の行が必要です.
linux_enable=YES
これは結果的に, /etc/rc.i386 の以下の指定を有効にします.
# Start the Linux binary emulation if requested. if [ "X${linux_enable}" = X"YES" ]; then echo -n ' linux'; linux > /dev/null 2>&1 fi
実行されたかどうかを確認するには, modstat を使用します.
% modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 4 f09e6000 001c f09ec010 1 linux_mod
2.2-RELEASE とそれ以降のシステムの中には, modstat の実行がうまくいかない ものがあるという報告もあります. 何らかの理由で, Linux LKM がロードできな い場合は,
options LINUXをカーネルの設定ファイルに指定して, エミュレータをスタティックにリンク してください. FreeBSDカーネルのコンフィグレーション の節の記述にしたがって config と, 新しいカーネルのインストールをおこ なってください.
多くの Linux アプリケーションはシェアードライブラリを使用しますので, シェアードライブラリのインストールが終了しなければ, エミュレータのイン ストールは終わったことになりません. 手動でもインストールできますが, linux_lib port を使用するのが簡単です.
# cd /usr/ports/emulators/linux_lib # make all install
これで, Linux エミュレータが動作するようになったはずです. 伝説(とメー ルのアーカイブ :-) によれば, Linux エミュレーションは, ZMAGIC ライブラ リとリンクされている Linux バイナリに対して, 最もうまく動作するようで す. Slackware V2.0 などに使われている QMAGIC ライブラリだと, エミュレー タが胸やけするかもしれません. マイナーバージョンの不一致などを 報告するプログラムもありますが, 普通は 問題にならないようです.
``ports'' ディストリビューションが手元にない場合は, 手動でライブラ リをインストールする必要があります. プログラムが必要とする Linux のシェ アードライブラリとラインタイムリンカが必要です. また Linux ライブラリ の用の``shadow root'' ディレクトリ, /compat/linux, を作成する必要があ ります. FreeBSD で動作する Linux のプログラムが使用するシェアードライ ブラリは,まずこのファイルツリーから検索されます. 例えば, Linux のプロ グラムが /lib/libc.so をロードしようとした場合には, FreeBSD は, まず /compat/linux/lib/libc.so を開こうとします. 存在にしなかった場合には, 次に /lib/libc.so を試します. シェアードライブラリは, Linux の ld.so が参照するライブラリではなく, /compat/linux/lib 以下にインストールする 必要があります.
FreeBSD 2.2-RELEASE 以降では, /compat/linux にかかわる動作が多少異なっており, ライブラリだけでなくすべてのファイルが, ``shadow root'' /compat/linux から検索されるようになっています.
Linux のプログラムが必要とする シェアードライブラリを探す必要があるのは, FreeBSD のシステムに Linux のプログラムをインストールする最初の数回だ けでしょう. それが過ぎれば, 十分な Linux のシェアードライブラリがシス テムにインストールされ, 新しくインストールした Linux のバイナリも, 余 計な作業をせずに動作させることができるようになります.
linux_port をインストールした後に, アプリケーションが必要なライブラリ が存在しないというエラーを出したらどうしたらよいでしょうか? Linux のバ イナリがどのシェアードライブラリを必要とし, そしてどこで入手できるか, どのように探したらよいでしょうか? 基本的には, 以下の2種類の方法があり ます(以下の手順にしたがう場合には, 必要なインストール作業をおこなう FreeBSD シ ステム上で root として作業をおこなう必要があります).
Linux システムを使用でき, 必要なシェアードライブラリが調べられる場 合には, 単に FreeBSD のシステムにそのライブラリをコピーするだけで す. 例えば, DOOM の Linux バイナリを ftp で持ってきたとします. 使用で きる Linux システムの上に転送して, ldd linuxxdoom とやれば, 必要とす るシェアードライブラリがチェックできます.
% ldd linuxxdoom libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0 libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0 libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
最後のカラムに表示されている すべてのファイルを持って来て, /compat/linux の下 に置き, 最初のカラムに示されるファイル名から シンボリックリンクを張る必 要があります. すなわち, FreeBSD のシステムで, 以下のようなファイルが必 要となります.
/compat/linux/usr/X11/lib/libXt.so.3.1.0 /compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0 /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29
Note: 最初のカラムに表示されているファイルと, メジャーバージョンの同じ Linux シェアードライブラリを既にインストールしている場合は, 新たにコピーする 必要はありません. 既にあるライブラリで動作するはずです. ただ, 新しいバー ジョンのシェアードライブラリがある場合は, 新しいものをコピーすることを お奨めします. 新しいライブラリにシンボリックリンクを変更したら, 古いラ イブラリは削除してかまいません.
/compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27以上のようなライブラリがインストールされており, 新しいバイナリに対する ldd の出力が 以下のようになる場合を考えます.libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29このように最後の番号が1つか2つ古いだけならば, 普通は /lib/libc.so.4.6.29 をコピーする必要はありません. わずかに古いライブラ リでも, プログラムは動作するはずだからです. もちろん, 新しいライブラリ と置き換えて, 以下のようにしても構いません.
/compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29
Note: シンボリックリンクのメカニズムは, Linux バイナリにのみ必要 なことに注意してください. FreeBSD のランタイムリンカは, メジャーリビジョ ン番号の一致したライブラリを検索しますから, ユーザが気にする必要はあり ません.
このセクションは, FreeBSD 2.2-CURRENT 以降にのみ当てはまります. 2.1-STABLE を使用している方は, 飛ばしてください.
最後に, FreeBSD 2.2-RELEASE を使われている場合は, Linux のランタイムリンカと その設定ファイルがシステムに導入されていることを 確認してください. これらのファイルは, FreeBSD システムの適切な位置(/compat/linux ツリー以 下)にコピーされている必要があります.
/compat/linux/lib/ld.so /compat/linux/etc/ld.so.config
使用できる Linux システムがない場合は, 必要なファイルは近くの FTP サイ トから入手してください. 各種ファイルの入手先についての情報を, 後に付 けておきます. ここでは, 必要なファイルの入手先がわかっているものとしま す.
以下のファイルを取得します (バージョンの不一致を避けるために, すべて同一 の FTP サイトから入手してください). 取得したファイルを /compat/linux 以下にインストールしてください(例えば, /foo/bar は, /compat/linux/foo/bar にインストールされます).
/sbin/ldconfig /usr/bin/ldd /lib/libc.so.x.y.z /lib/ld.so
ldconfig と ldd は, /compat/linux の下にある必要はありません. システム のどこにあっても構いません. ただ, FreeBSD の同名のコマンドと間違えないように 注意してください. /usr/local/bin の中に, ldconfig-linux, ldd-linux とし てインストールするのもよいアイディアでしょう.
/compat/linux/etc/ld.so.conf ファイルを作成し, Linux ラインタイムリンカ がシェアードライブラリを検索する ディレクトリを記述してください. このファ イルはプレインテキストファイルで, それぞれの行にディレクトリ名を含みま す. /lib と /usr/lib は標準ですから, 以下のようなディレクトリが追加できま す.
/usr/X11/lib /usr/local/lib
Linux バイナリが, /lib/libc.so というライブラリを開いた場合, エミュレー タは内部で, ファイル名を /compat/linux/lib/libc.so にマップします. エ ミュレータがライブラリを検索するために, すべての Linux のライブラリ (/compat/linux/lib/libc.so, /compat/linux/usr/X11/lib/libX11.so など) は, /compat/linux 以下にインストールされていなければなりません.
FreeBSD 2.2-RELEASE を使用している場合は, Linux の ldconfig プログラム を実行する必要があります.
# cd /compat/linux/lib # /compat/linux/sbin/ldconfig
ldconfig はスタティックリンクされていますから, 実行するのにシェアードラ イブラリを必要としません. ldconfig は, /compat/linux/etc/ld.so.cache ファイルを作成し, すべてのシェアードライブラリの名前を格納します. ライ ブラリの追加をおこなった場合には, ldconfig を再実行して, このファイルを作り 直さなければなりません.
2.1-STABLE では, /compat/linux/etc/ld.so.cache をインストールしたり, ldconfig を実行したりしないでください. 2.1-STABLE では, システムコー ルの実装方法が異なるため, ldconfig は使用されません.
これで, libc シェアードライブラリを必要とする Linux バイナリを実行する設 定が終了しました. ldd を ldd 自身に実行してテストしてください. ldd-linux としてインストールしている場合は, 以下のような結果になるはず です.
# ldd-linux `which ldd-linux` libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
ここまで終了すれば, 新しい Linux のバイナリを インストールできます. 新しい Linux バイナリをインストールするときは, それがシェアードライブ ラリを必要とするかどうか確認してください. 必要とする場合は, /compat/linux 以下に インストールされているかどうか確認してください. こ れは, Linux の ldd を新しいプログラムに 対して実行し, 出力を確認するこ とによりおこなえます. ldd (ldd(1) マニュアルページも参照してください)は, プ ログラムが必要とするシェアードライブラリのリストを, majorname (jumpversion) => fullname という形式で出力します.
fullname のかわりに not found と出力される場合は, ライブラリの追加をす る必要があります. 必要なライブラリの名前は, majorname に libXXXX .so.N.mm という形式で示されています. Linux の FTP サイトで libXXXX.so.N.mm を探し, インストールしてください. XXXX(名前)とN (メジャー リビジョン番号)は一致している必要があります. マイナー番号 mm は, それほ ど重要ではありませんが, なるべく最新のものをインストールするようにして ください.
ELF のバイナリを使うためには, ``焼き印を押す(branding)'' 作業が必要になります. 焼き印を押していない ELF バイナリを実行しようとすると, 以下のようなエラーメッセージを うけとってしまうことでしょう.
% ./my-linux-elf-binary ELF binary type not known Abort
カーネルが FreeBSD の ELF バイナリと Linux のバイナリとを 見分けられるようにするためには, brandelf(1) を以下のようにして使ってください:
% brandelf -t Linux my-linux-elf-binary
今ではGNU のツールたちが, ELFバイナリに自動的に適切な焼き印を押すようになったので, 今後はこの作業もだんだんと必要なくなってゆくでしょう.
DNS がうまく動作しなかったり, 以下のようなエラーメッセージが表示され る場合は, /compat/linux/etc/host.conf ファイルを設定する必要があります.
resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keywordファイルの内容を以下のように設定してください.
order hosts, bind multi onここで, order は /etc/hosts を最初に検索し, 次にDNSを検索するように指定 します. /compat/linux/etc/host.conf がインストールされていない場合は, Linux のアプリケーションは, FreeBSD の /etc/host.conf を使用しようとして, 文法の違いによる警告を表示します. /etc/resolv.conf を使用してネームサー バを設定していない場合には, bind を削除してください.
最後になりますが, 2.1-STABLE を使用している場合は, RESOLV_HOST_CONF 環境変数を指定して, アプリケーションにホストテーブル の検索方法を指定する必要があります. FreeBSD 2.2-RELEASE かそれ以降を使用している場合 は, スキップしてください. /bin/csh を使っている場合は, 以下のようにし ます.
% setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf
/bin/shの場合は, 以下のようにします.
% RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF
Note: 以下の情報は, この文書が書かれた時点では有効ですが, FTP サイトの 名前, ディレクトリ, 配布ファイル名などは, 変更されている可能性がありま す.
Note: 訳注: ここに取り上げられている FTP サイトは, 日本国内にもミラーサイト が多数存在します. なるべく近くの FTP サイトからファイルを入手してくだ さい.
Linux は, いくつかのグループが, それぞれ独自のバイナリ配布セットを作成 して配布しています. 配布セットは, ``Slackware'' や ``Yggdrasil'' など の名前がつけられています. これらの配布セットは, 多くの FTP サイトから 入手できます. ファイルが展開されており, 必要なファイルのみを取得できる 場合もありますが, 通常は圧縮された配布セットの形で入手できます. 配布 セットは, いくつかのサブディレクトリに, gzip で圧縮された tar ファイル として格納されています. それぞれの配布セットの一次配布先は, 以下の通り です.
sunsite.unc.edu:/pub/Linux/distributions
tsx-11.mit.edu:/pub/linux/distributions
ヨーロッパのミラーサイトの例:
ftp.luth.se:/pub/linux/distributions
ftp.demon.co.uk:/pub/unix/linux
src.doc.ic.ac.uk:/packages/linux/distributions
混乱を避けるために, ここでは Slackware だけを取り上げます. この配布セッ トは, 多くのサブディレクトリ内にある 別々のパッケージから構成されていま す. 通常, パッケージはインストールプログラムにより自動的に制御されま すが, ``手動で''おこなうことも可能です. まず配布セットの中の, contents サブディレクトリの内容を書くにしてください. ここには多く の小さなテキストファイルが含まれおり, それぞれのパッケージの内容が記述 されています. 必要なファイルを探している場合は, まず contents 内のテキ ストファイルを取得し, そのファイルの中から grep を使用して検索するのが, 最も速い方法でしょう. 以下に必要となるであろうファイルを, grep を使用 して検索した例を示します.
Library | Package |
---|---|
ld.so | ldso |
ldconfig | ldso |
ldd | ldso |
libc.so.4 | shlibs |
libX11.so.6.0 | xf_lib |
libXt.so.6.0 | xf_lib |
libX11.so.3 | oldlibs |
libXt.so.3 | oldlibs |
この場合は, ldso, shlibs, xf_lib, oldlibs というパッケージが必要なこと がわかります. それぞれのcontentsファイルの中で, PACKAGE LOCATION と書いてある行を探してください. その行に, パッケージが含まれている``ディ スク'', 今回の場合はサブディレクトリ名が書かれています. たとえば, 以下の ようになります.
Package | Location |
---|---|
ldso | diska2 |
shlibs | diska2 |
oldlibs | diskx6 |
xf_lib | diskx9 |
``diskXX'' というのは, 配布セットの slackware/XX サブディレクトリ を示します. それ以外の場合は, contrib サブディレクトリに格納されて います. 今回の場合は, 以下のファイルを取得すればいいことがわかります (ファイル名は, 配布セットのルートディレクトリからの相対パスで示してあ ります).
slakware/a2/ldso.tgz
slakware/a2/shlibs.tgz
slakware/x6/oldlibs/tgz
slakware/x9/xf_lib.tgz
gzip で圧縮された tar ファイルから必要なファイルを /compat/linux ディ レクトリに格納してください(必要なファイルのみを展開するか, あるいは必 要でないファイルを後で削除してください). これで作業は終了です.
参照: ftp.freebsd.org:pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README と /usr/src/sys/i386/ibcs2/README.iBCS2