<!--
     The FreeBSD Documentation Project
     The FreeBSD Japanese Documentation Project

     Original revision: 1.35
     $FreeBSD$
-->

<chapter id="linuxemu">
  <title>Linux バイナリ互換機能</title>

  <para><emphasis>オリジナルは Brian N. Handy <email>handy@sxt4.physics.montana.edu</email> と &a.rich; によるものですが、
  &a.jim; が 2000 年 3 月 22 日に再構成と一部の更新を行ないました。</emphasis></para>

  <para><emphasis>訳: &a.jp.kiroh;、1996 年 9 月 24 日</emphasis></para>

  <sect1>
    <title>この章では</title>

    <para>この章では FreeBSD における Linux バイナリとの互換機能について、
    インストール方法やその仕組みを解説します。</para>

    <para>現時点では、一体なぜ FreeBSD が Linux
      バイナリを実行できるようにならなければならないのか自問しているのではないでしょうか?
      答えはきわめて簡単です。
      Linux は現在コンピュータの世界では最も<quote>ホットなモノ</quote>なのでたくさんの会社や開発者たちが
      Linux のためだけに開発を行なっています。そのため、残された私たち
      FreeBSD ユーザは彼らに対して FreeBSD ネイティブなアプリケーションも出すように言うしかないのです。
      問題は、FreeBSD バージョンも出した場合にどれくらいの数のユーザーが使うのかわからない、
      ということであり、そのため Linux 版のみを開発しているということなのです。
      そこで FreeBSD では Linux バイナリ互換機能が役に立つのです。</para>

    <para>簡単に言ってしまえば、この機能により全ての Linux アプリケーションの
      90% が修正なしに FreeBSD 上で起動できます。
      この中には Star Office や Linux 版の Netscape、Adobe Acrobat、RealPlayer 5 と 7、
      VMWare、Oracle、WordPerfect、Doom、Quake などがあります。
      また、ある状況においては Linux バイナリを Linux で動かすよりも
      FreeBSD で動かすほうが良いパフォーマンスが出るという報告もあります。</para>

    <para>しかしながら、いくつかの Linux に特有な OS の機能は FreeBSD ではサポートされていません。
      例えば、Linux の <filename>/proc</filename> ファイルシステムを過度に使うような
      Linux バイナリは FreeBSD では動きません (FreeBSD の <filename>/proc</filename>
      ファイルシステムとは異なるのです) し、
      仮想 8086 モードを有効にするような i386 特有の呼び出しも動きません。</para>

    <para>Linux バイナリ互換モードのインストールに関しては<link linkend="linuxemu-lbc-install">次のセクション</link>をご覧ください。</para>
  </sect1>

  <sect1 id="linuxemu-lbc-install">
    <title>インストール</title>

    <para>3.0-RELEASE以降であればカーネルのコンフィギュレーションファイルに
      <literal>options LINUX</literal> や <literal>options COMPAT_LINUX</literal>
      といった行を加える必要はありません。</para>

    <para>Linux バイナリ互換機能は今は KLD オブジェクト (<quote>Kernel LoaDable object</quote>)
      として実現されており、リブートしなくても
      <quote>on-the-fly</quote> で組み込むことができるのですが、
      <filename>/etc/rc.conf</filename> に次の行を加える必要があります。</para>

    <programlisting>linux_enable=<quote>YES</quote></programlisting>

    <para>この設定により、<filename>/etc/rc.i386</filename>
      では次のような操作が行なわれます。</para>

    <programlisting># Start the Linux binary compatibility if requested.
#
case ${linux_enable} in
[Yy][Ee][Ss])
	echo -n ' linux';	linux &gt; /dev/null 2&gt;&amp;1
	;;
esac
    </programlisting>

    <para>望みの KLD モジュールがロードされているか確認したい時には
      <command>kldstat</command> を利用します。</para>

    <screen>&prompt.user; <userinput>kldstat</userinput>
Id Refs Address    Size     Name
 1    2 0xc0100000 16bdb8   kernel
 7    1 0xc24db000 d000     linux.ko</screen>

      <para>
      何らかの理由で Linux KLD をロードしたくない、
      あるいはロードできないような場合には、
      <literal>options  LINUX</literal>
      をカーネルの設定ファイルに指定して、
      Linux バイナリ互換機能をカーネルにスタティックリンクしてください。
      そして、<link linkend="kernelconfig">FreeBSD カーネルのコンフィギュレーション</link>
      の記述にしたがって新しいカーネルをインストールしてください。</para>

    <sect2>
      <title>Linux ランタイムライブラリのインストール</title>

      <para>これは、<link linkend="linuxemu-libs-port">linux_base</link>
        の port を用いるか、もしくは<link linkend="linuxemu-libs-manually">手動で</link>インストールします。</para>

      <sect3 id="linuxemu-libs-port">
	<title>linux_base の port を用いたインストール</title>

	<para>ランタイムライブラリをインストールするには最も簡単な方法です。
	  <ulink url="../ports/">ports コレクション</ulink>から他の port
	  をインストールするのと全く同じようにできます。</para>

	<screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base</userinput>
&prompt.root; <userinput>make install distclean</userinput></screen>

	<para>これで Linux バイナリ互換機能が使えるはずです。
	  いくつかのプログラムはシステムライブラリのマイナーバージョンが違うと文句を言うかもしれませんが一般的には大した問題ではありません。</para>
      </sect3>

      <sect3 id="linuxemu-libs-manually">
	<title>手動でのライブラリのインストール</title>

	<para><quote>ports</quote> コレクションをインストールしていない場合、
	  代わりに手動でライブラリをインストールすることができます。
	  プログラムが必要とする Linux のシェアードライブラリとランタイムリンカが必要です。
	  また Linux ライブラリ用の <quote>shadow root</quote> ディレクトリ、
	  <filename>/compat/linux</filename> を作成する必要があります。
	  FreeBSD で動作する Linux プログラムが使用するシェアードライブラリは、
	  まずこのファイルツリーから検索されます。例えば、
	  Linux のプログラムが <filename>/lib/libc.so</filename>
	  をロードしようとした場合には、FreeBSD はまず
	  <filename>/compat/linux/lib/libc.so</filename>
	  を開こうとします。これが存在しなかった場合には、次に
	  <filename>/lib/libc.so</filename> を試します。
	  シェアードライブラリは、Linux の <command>ld.so</command>
	  が報告するパスではなく、
	  <filename>/compat/linux/lib</filename>
	  以下にインストールする必要があります。</para>

	<para>Linux のプログラムが必要とする
	  シェアードライブラリを探す必要があるのは、FreeBSD
	  のシステムに Linux
	  のプログラムをインストールする最初の数回だけでしょう。
	  それが過ぎれば、十分な Linux のシェアードライブラリがシステムにインストールされ、
	  新しくインストールした Linux のバイナリも余計な作業をせずに動作させることができるようになります。</para>
      </sect3>

      <sect3>
	<title>シェアードライブラリの追加</title>

	<para><filename>linux_base</filename> port をインストールした後に、
	  アプリケーションが必要なライブラリが存在しないというエラーを出したらどうしたらよいでしょうか?
	  Linux のバイナリがどのシェアードライブラリを必要とし、
	  そしてどこで入手できるか、どのように探したらよいでしょうか?
	  基本的には、以下の 2 種類の方法があります (以下の手順に従う場合には、
	  必要なインストール作業をおこなう FreeBSD システム上で root
	  として作業をおこなう必要があります)。</para>

	<para>Linux システムにアクセス可能ならば、
	  そのアプリケーションがどういうシェアードライブラリを必要としているのか調べ、
	  単に FreeBSD にそのライブラリをコピーするだけです。
	  次の例を見てみましょう。</para>

	<informalexample>
	  <para>FTP を使って Doom の Linux バイナリを取ってきて、
	    アクセスできる Linux システムに置いたとしましょう。
	    次のように <command>ldd linuxdoom</command> とするだけでどのシェアードライブラリが必要かチェックできます。</para>

	<screen>&prompt.user; <userinput>ldd linuxxdoom</userinput>
libXt.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libXt.so.3.1.0
libX11.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libX11.so.3.1.0
libc.so.4 (DLL Jump 4.5pl26) =&gt; /lib/libc.so.4.6.29</screen>

	<para>最後のカラムに表示されているすべてのファイルを持って来て、
	  <filename>/compat/linux</filename> の下に置き、
	  最初のカラムに示されるファイル名にシンボリックリンクを張ります。
	  すなわち、FreeBSD システムでは以下のようなファイルが必要となります。</para>

	  <screen>/compat/linux/usr/X11/lib/libXt.so.3.1.0
/compat/linux/usr/X11/lib/libXt.so.3 -&gt; libXt.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3 -&gt; libX11.so.3.1.0
/compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>

	  <blockquote>
	    <note>
	      <para>最初のカラムに表示されているファイルとメジャーバージョンが同じ
	        Linux シェアードライブラリを既にインストールしている場合は、
		新たにコピーする 必要はありません。
		既にあるライブラリで動作するはずです。
		ただ、新しいバージョンのものをコピーすることをお奨めします。
		新しいライブラリにシンボリックリンクを変更したら、
		古いライブラリは削除してかまいません。</para>

	      <screen>/compat/linux/lib/libc.so.4.6.27
/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.27</screen>

	      <para>従って、以上のようなライブラリがインストールされており、
	        新しいバイナリに対する <command>ldd</command>
	        の出力が以下のようになる場合を考えます。</para>

	      <screen>libc.so.4 (DLL Jump 4.5pl26) -&gt; libc.so.4.6.29</screen>

	      <para>このように最後の番号が 1 つか 2 つ古いだけならば、普通は
	        <filename>/lib/libc.so.4.6.29</filename>
	        をコピーする必要はありません。わずかに古いライブラリでもプログラムは動作するはずだからです。
	        もちろん、以下のように新しいライブラリと置き換えても構いません。</para>

	      <screen>/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>
	    </note>
	  </blockquote>

	  <blockquote>
	    <note>
	      <para>シンボリックリンクのメカニズムは Linux
	      バイナリに<emphasis>のみ</emphasis>必要なことに注意してください。
	      FreeBSD のランタイムリンカはメジャーリビジョン番号の一致したライブラリを検索するので、
	      ユーザが気にする必要はありません。</para>
	    </note>
	  </blockquote>
	</informalexample>
      </sect3>
    </sect2>

    <sect2>
      <title>Linux の ELF バイナリのインストール</title>

      <para>ELF のバイナリを使うためには、
	<quote>マークをつける (branding)</quote> 作業が必要になります。
	マークのない ELF バイナリを実行しようとすると以下のようなエラーメッセージを受けとってしまうことでしょう。</para>

      <screen>&prompt.user; <userinput>./my-linux-elf-binary</userinput>
ELF binary type not known
Abort</screen>

      <para>カーネルが FreeBSD の ELF バイナリと Linux のバイナリとを
	見分けられるようにするためには、&man.brandelf.1;
	ユーティリティを以下のようにして使ってください。</para>

      <screen>&prompt.user; <userinput>brandelf -t Linux my-linux-elf-binary</userinput></screen>

      <para>今では GNU のツールたちが
	ELF バイナリに自動的に適切なマークを付加するようになったので、
	今後はこの作業もだんだんと必要なくなってゆくでしょう。</para>
    </sect2>

    <sect2>
      <title>ホストネームリゾルバの設定</title>

      <para>DNS がうまく動作しなかったり、
	以下のようなエラーメッセージが表示され
	る場合は、<filename>/compat/linux/etc/host.conf</filename>
	ファイルを設定する必要があります。</para>

      <screen>resolv+: "bind" is an invalid keyword resolv+:
"hosts" is an invalid keyword</screen>

      <para>ファイルの内容を以下のように設定してください。</para>

	<programlisting>order hosts, bind
multi on</programlisting>

      <para>ここで、order は <filename>/etc/hosts</filename> を最初に検索し、
	次に DNS を検索するように指定します。
	<filename>/compat/linux/etc/host.conf</filename>
	がインストールされていない場合、
	Linux アプリケーションは FreeBSD の
	<filename>/etc/host.conf</filename> を使用しようとして、
	文法の違いによる警告を出力します。
	<filename>/etc/resolv.conf</filename> を利用してネームサーバの設定をしていない場合には、
	<literal>bind</literal> を削除してください。</para>
    </sect2>
  </sect1>

  <sect1 id="linuxemu-mathematica">
    <title>Mathematica のインストール</title>

    <para><emphasis>Mathematica 4.x 用に &a.murray;
      がアップデートし、Bojan Bistrovic <email>bojanb@physics.odu.edu</email>
      がマージしました。</emphasis></para>

    <para>この章では、Mathematica 4.X Linux 版の FreeBSD
      へのインストールについて説明します。</para>

    <para>Linux 版の Mathematica は FreeBSD においても完璧に動きます。
      ただ、実行する際に Linux ABI を用いる必要があることを
      FreeBSD に教えるために、Wolfram によって出荷されているバイナリにマーク付け
      (branded) をする必要があります。</para>

    <para>Mathematica や Mathematica for Students の Linux 版は Wolfram
      (<ulink url="http://www.wolfram.com/">http://www.wolfram.com/</ulink>)
      から直接注文することができます。</para>

    <sect2>
      <title>Linux バイナリへのマーク付け (branding)</title>

      <para>Linux 用バイナリは Wolfram の Mathematica CD-ROM の
        <filename>Unix</filename> ディレクトリにあります。
	インストーラーを起動する前にこのディレクトリをローカルディスクにコピーし、
	&man.brandelf.1; により Linux バイナリにマークを付けます。</para>

      <screen>&prompt.root; <userinput>mount /cdrom</userinput>
&prompt.root; <userinput>cp -rp /cdrom/Unix/ /localdir/</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/Kernel/Binaries/Linux/*</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/FrontEnd/Binaries/Linux/*</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/Installation/Binaries/Linux/*</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/Graphics/Binaries/Linux/*</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/Converters/Binaries/Linux/*</userinput>
&prompt.root; <userinput>brandelf -t Linux /localdir/Files/SystemFiles/LicenseManager/Binaries/Linux/mathlm</userinput>
&prompt.root; <userinput>cd /localdir/Installers/Linux/</userinput>
&prompt.root; <userinput>./MathInstaller</userinput></screen>

       <para>また以下のようにすると、マーク付けされていない
         ELF バイナリすべての扱いを、デフォルトで Linux
         バイナリとすることが可能です。</para>

       <screen>&prompt.root; <userinput>sysctl -w kern.fallback_elf_brand=3</userinput>
       </screen>

       <para>これは FreeBSD システムに対して、
         マーク付けされていない ELF バイナリが
         Linux ABI を利用するように設定します。こうすることで、
         CDROM から直接インストーラを実行することが可能になります。</para>
    </sect2>

    <sect2>
      <title>Mathematica パスワードの取得</title>

      <para>Mathematica を起動する前に Wolfram から自分の
        <quote>マシン ID</quote> に対応したパスワードを取得しなければいけません。</para>

      <para>一旦 Linux 互換ランタイムライブラリをインストールし、
        Mathematica を展開すれば Install ディレクトリにある
	<command>mathinfo</command> プログラムを起動して
	<quote>マシン ID</quote> を得ることができます。
	このマシン ID は、最初に見つかったイーサネットカードの MAC アドレスをベースに生成されます。</para>

      <screen>&prompt.root; <userinput>cd /localdir/Files/SystemFiles/Installation/Binaries/Linux</userinput>
&prompt.root; <userinput>mathinfo</userinput>
disco.example.com 7115-70839-20412</screen>

      <para>電子メールや電話、FAX などで Wolfram に登録する時にはこの
        <quote>マシン ID</quote> を渡します。
	するといくつかの数字から構成されるパスワードが返されるので、
	他の Mathematica プラットホームでするのと全く同じように最初に
	Mathematica を立ち上げる時にその情報を入力します。</para>
    </sect2>

    <sect2>
      <title>ネットワーク経由での Mathematica フロントエンドの起動</title>

      <para>
        Mathematica は標準フォントセットにない特別な記号 (積分記号、総和記号、
        ギリシャ文字など) を表示するために特殊なフォントを使用します。
        X プロトコルは、
        これらのフォントが<emphasis>ローカルマシンに</emphasis>インストールされていることを要求します。
        これはつまり、ローカルマシンに (CD-ROM や Mathematica
        がインストールされているホストマシンから) そのフォントをコピーしなければならないということです。
        これらのフォントは通常、CD-ROM の
	<filename>/cdrom/Unix/Files/SystemFiles/Fonts</filename> か、もしくはハードディスクの
	<filename>/usr/local/mathematica/SystemFiles/Fonts</filename>
	に置かれており、実際に使用されるフォントは <filename>Type1</filename> と
        <filename>X</filename> のサブディレクトリに格納されています。
        これらを利用するには次のような二つ方法があります。</para>

      <para>一つは、フォントファイルをすべて
        <filename>/usr/X11R6/lib/X11/fonts/</filename>
        以下にある既存のフォントディレクトリにコピーする方法です。
        この場合、<filename>fonts.dir</filename> にフォント名を追加し、
        先頭行のフォント総数を変更することも必要になります。
        あるいは、フォントをコピーしたディレクトリで
	<command>mkfontdir</command> を実行するだけでもかまいません。</para>

      <para>もう一つの方法は、
        <filename>/usr/X11R6/lib/X11/fonts/</filename>
        にフォントディレクトリごとコピーする方法です。</para>

      <screen>&prompt.root; <userinput>cd /usr/X11R6/lib/X11/fonts</userinput>
&prompt.root; <userinput>mkdir X</userinput>
&prompt.root; <userinput>mkdir MathType1</userinput>
&prompt.root; <userinput>cd /cdrom/Unix/Files/SystemFiles/Fonts</userinput>
&prompt.root; <userinput>cp X/* /usr/X11R6/lib/X11/fonts/X</userinput>
&prompt.root; <userinput>cp Type1/* /usr/X11R6/lib/X11/fonts/MathType1</userinput>
&prompt.root; <userinput>cd /usr/X11R6/lib/X11/fonts/X</userinput>
&prompt.root; <userinput>mkfontdir</userinput>
&prompt.root; <userinput>cd ../MathType1</userinput>
&prompt.root; <userinput>mkfontdir</userinput></screen>

      <para>そして、フォントパスに新しいフォントディレクトリを追加します。</para>

      <screen>&prompt.root; <userinput>xset fp+ /usr/X11R6/lib/X11/fonts/X</userinput>
&prompt.root; <userinput>xset fp+ /usr/X11R6/lib/X11/fonts/MathType1</userinput>
&prompt.root; <userinput>xset fp rehash</userinput></screen>

      <para>XFree86 サーバを使用しているなら、
        <filename>/etc/XF86Config</filename> に加えることでこれらのフォントを自動的に読み込むことができます。</para>

      <para>
        <filename>/usr/X11R6/lib/X11/fonts/Type1</filename> という
        ディレクトリが<emphasis>存在していない</emphasis>場合には、
        上記例の <filename>MathType1</filename> を
        <filename>Type1</filename>
        とすることができます。</para>
    </sect2>
  </sect1>

  <sect1 id="linuxemu-oracle">
    <title>Oracle のインストール</title>
    
    <para><emphasis>Marcel Moolenaar 寄贈
	<email>marcel@cup.hp.com</email></emphasis></para>
    
    <sect2>
      <title>はじめに</title>
      <para>このドキュメントでは Oracle 8.0.5 と Oracle 8.0.5.1 Enterprise Edition
        の Linux 版を FreeBSD にインストールするための手順を解説します。</para>
    </sect2>
    
    <sect2>
      <title>Linux 環境のインストール</title>
      
      <para>まずは Ports Collection から <filename>linux_base</filename> と
        <filename>linux_devtools</filename> をインストールしてください。
	これらの ports は FreeBSD 3.2 のリリース後にコレクションに加えられました。
	もし FreeBSD 3.2 もしくはそれよりも古いものを使っている場合は
	ports コレクションをアップデートしましょう。ついでに FreeBSD
	をアップデートするのもいいでしょう。もし <filename>linux_base-6.1</filename>
	や <filename>linux_devtools-6.1</filename> でうまくいかなければ
	5.2 を試してみてください。</para>

      <para>もし賢いエージェント (intelligent agent) を起動したいなら
        Red Hat TCL パッケージ <filename>tcl-8.0.3-20.i386.rpm</filename>
	もインストールする必要があるでしょう。
	公式の RPM パッケージをインストールするには一般的に次のようにします。</para>
      
      <screen>&prompt.root; <userinput>rpm -i --ignoreos --root /compat/linux --dbpath /var/lib/rpm <replaceable>package</replaceable></userinput></screen>

      <para>パッケージのインストール時にエラーが出てはいけません。</para>
    </sect2>

    <sect2>
      <title>Oracle 環境の構築</title>
      
      <para>Oracleをインストールする前に、適切な環境を設定する必要があります。
        このドキュメントでは、
	Oracle のインストールガイドに書いてあるようなことではなく
	FreeBSD で Linux 用 Oracle
	を動かすために<emphasis>特別に</emphasis>必要なことのみを解説します。</para>

      <sect3 id="linuxemu-kernel-tuning">
        <title>カーネルのチューニング</title>
	
	<para>Oracle インストールガイドにあるように、
	  シェアードメモリーの最大サイズを設定しなければいけません。
	  FreeBSD では <literal>SHMMAX</literal> を使わないようにしてください。
	  <literal>SHMMAX</literal> は単に <literal>SHMMAXPGS</literal>
	  と <literal>PGSIZE</literal> から計算されるだけなのです。
	  従って、<literal>SHMMAXPGS</literal> を使うようにしましょう。
	  インストールガイドに記述されている他のオプションは使えます。
	  例えば以下のようにします。</para>

	<programlisting>options SHMMAXPGS=10000
options SHMMNI=100
options SHMSEG=10
options SEMMNS=200
options SEMMNI=70
options SEMMSL=61</programlisting>
	
        <para>これらのオプションを意図した Oracle の使い方に合わせて設定してください。</para>

	<para>また、
	  次のオプションがカーネルのコンフィギュレーションファイルにあることも確認します。</para>

<programlisting>options SYSVSHM #SysV shared memory
options SYSVSEM #SysV semaphores
options SYSVMSG #SysV interprocess communication</programlisting>
      </sect3>

      <sect3 id="linuxemu-oracle-account">
	
        <title>Oracle 用アカウント</title>

	<para>他のアカウントを作るのと同じように Oracle 用のアカウントを作ります。
	  Oracle 用のアカウントに特別なのは Linux のシェルを割り当てるところだけです。
	  <filename>/etc/shells</filename> に <literal>/compat/linux/bin/bash</literal>
	  を加え、Oracle 用のアカウントに設定します。</para>
      </sect3>

      <sect3 id="linuxemu-environment">
        <title>環境設定</title>

	<para><envar>ORACLE_HOME</envar> や <envar>ORACLE_SID</envar>
	  といった通常の Oracle 用の変数の他に次の変数も設定しなければなりません。</para>

	<informaltable frame="none">
	  <tgroup cols="2">
	    <thead>
	      <row>
		<entry>変数</entry>

		<entry>値</entry>
	      </row>
	    </thead>
	    <tbody>
	      <row>
		<entry><envar>LD_LIBRARY_PATH</envar></entry>

		<entry><literal>$ORACLE_HOME/lib</literal></entry>
	      </row>

	      <row>
		<entry><envar>CLASSPATH</envar></entry>

		<entry><literal>$ORACLE_HOME/jdbc/lib/classes111.zip</literal></entry>
	      </row>

	      <row>
		<entry><envar>PATH</envar></entry>

		<entry><literal>/compat/linux/bin
/compat/linux/sbin
/compat/linux/usr/bin
/compat/linux/usr/sbin
/bin
/sbin
/usr/bin
/usr/sbin
/usr/local/bin
$ORACLE_HOME/bin</literal></entry>
	      </row>
	    </tbody>
	  </tgroup>
	</informaltable>

        <para>全ての環境変数は <filename>.profile</filename> で設定することをお勧めします。
	  完璧なサンプルは以下の通りです。</para>

<programlisting>ORACLE_BASE=/oracle; export ORACLE_BASE
ORACLE_HOME=/oracle; export ORACLE_HOME
LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH
ORACLE_SID=ORCL; export ORACLE_SID
ORACLE_TERM=386x; export ORACLE_TERM
CLASSPATH=$ORACLE_HOME/jdbc/lib/classes111.zip
export CLASSPATH
PATH=/compat/linux/bin:/compat/linux/sbin:/compat/linux/usr/bin:/compat/linux/usr/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:$ORACLE_HOME/bin
export PATH</programlisting>
      </sect3>
    </sect2>

    <sect2>
      <title>Oracle のインストール</title> 
      
      <para>インストーラーを起動する前に、<filename>/var/tmp</filename>
        に <filename>.oracle</filename> という名前のディレクトリを作る必要がありますが、
	これは Linux エミュレーターにおけるちょっとした不整合のためです。
	このディレクトリは誰でもが書けるか、もしくは oracle ユーザーのものにしておきます。
	これで特に問題なく Oracle がインストールできるでしょう。
	もし問題が起こったら、まずは Oracle の配布物や設定をチェックしてください。
	Oracle のインストールが終わったら次の二つのサブセクションで解説するパッチを当てます。</para>

      <para>よくあるトラブルは、TCP プロトコルアダプターが正しくインストールされていないことです。
        そのため、一切 TCP リスナーを起動することができないのです。
	次の操作はこの問題を解決するのに役立ちます。</para>

      <screen>&prompt.root; <userinput>cd $ORACLE_HOME/network/lib</userinput>
&prompt.root; <userinput>make -f ins_network.mk ntcontab.o</userinput>
&prompt.root; <userinput>cd $ORACLE_HOME/lib</userinput>
&prompt.root; <userinput>ar r libnetwork.a ntcontab.o</userinput>
&prompt.root; <userinput>cd $ORACLE_HOME/network/lib</userinput>
&prompt.root; <userinput>make -f ins_network.mk install</userinput></screen>

      <para>もう一度 <filename>root.sh</filename> を起動するのを忘れないように!</para>

    <sect3 id="linuxemu-patch-root">
      <title>root.sh へのパッチ</title>
    
	<para>Oracle をインストールする時、<username>root</username>
	  で行なう必要のあるいくつかの操作は <filename>root.sh</filename>
	  と呼ばれるシェルスクリプトに記録されます。
	  <filename>root.sh</filename> は <filename>orainst</filename>
	  ディレクトリにあります。次のパッチを root.sh に当てて
	  正しい場所にある chown コマンドを使うようにするか、
	  代わりに Linux ネイティブなシェルのもとでスクリプトを走らせましょう。</para>

	<programlisting>*** orainst/root.sh.orig Tue Oct 6 21:57:33 1998
--- orainst/root.sh Mon Dec 28 15:58:53 1998
***************
*** 31,37 ****
# This is the default value for CHOWN
# It will redefined later in this script for those ports
# which have it conditionally defined in ss_install.h
! CHOWN=/bin/chown
#
# Define variables to be used in this script
--- 31,37 ----
# This is the default value for CHOWN
# It will redefined later in this script for those ports
# which have it conditionally defined in ss_install.h
! CHOWN=/usr/sbin/chown
#
# Define variables to be used in this script</programlisting>

	<para>CD-ROM からのインストールでない場合は <filename>root.sh</filename>
	  のソースにパッチを当ててもいいでしょう。
	  <filename>rthd.sh</filename> という名前でソースツリーの
	  <filename>orainst</filename> というディレクトリにあります。</para>
      </sect3>

      <sect3 id="linuxemu-patch-tcl">
	<title>genclntsh へのパッチ</title>
	
	<para>genclntsh スクリプトは一つの共有クライアントライブラリを生成するのに用いられます。
	  これはデモを作る時に使われます。
	  PATH の定義をコメントアウトするために次のパッチを当ててください。</para>

	<programlisting>*** bin/genclntsh.orig Wed Sep 30 07:37:19 1998
--- bin/genclntsh Tue Dec 22 15:36:49 1998
***************
*** 32,38 ****
#
# Explicit path to ensure that we're using the correct commands
#PATH=/usr/bin:/usr/ccs/bin export PATH
! PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH
#
# each product MUST provide a $PRODUCT/admin/shrept.lst
--- 32,38 ----
#
# Explicit path to ensure that we're using the correct commands
#PATH=/usr/bin:/usr/ccs/bin export PATH
! #PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH
#
# each product MUST provide a $PRODUCT/admin/shrept.lst</programlisting>
      </sect3>
    </sect2>

    <sect2>
      <title>Oracle の起動</title>
      
      <para>インストラクションに従えば、Linux でと同じように
        Oracle を起動できるでしょう。</para>
    </sect2>
  </sect1>

  <sect1>
    <title>高度なトピックス</title>

    <para>Linux バイナリ互換機能がどのような仕組みなのか興味がある人はこのセクションを読んでください。
      以下の文章で説明されていることのほとんどは &a.chat; に投稿された
      Terry Lambert (<email>tlambert@primenet.com</email>) 氏のメール
      (Message ID: <literal>&lt;199906020108.SAA07001@usr09.primenet.com&gt;</literal>)
      をもとにしています。</para>

    <sect2>
      <title>どのように動くのでしょう?</title>

    <para>FreeBSD は、&ldquo;実行クラスローダ (execution class loader) &rdquo;
      と呼ばれる抽象的な機構を持っています。これは &man.execve.2
      システムコールへの楔という形で実装されています。
    </para>

    <para>FreeBSD は、シェルインタプリタやシェルスクリプトを実行するための
      <literal>#!</literal> ローダを持った単一のプログラムローダではなく、
      ローダのリストを持っているのです。
    </para>

    <para>歴史的には、UNIX プラットフォーム上の唯一のローダーがマジックナンバー
      (一般的にはファイルの先頭の 4 ないし 8 バイトの部分)
      の検査を行ないシステムで実行できるバイナリかどうかを検査し、
      もしそうならバイナリローダーを呼び出すというようになっていました。</para>

    <para>もし、そのシステム用のバイナリでない場合には、
      &man.execve.2; システムコールの呼び出しは失敗の戻り値を返し、
      シェルがシェルコマンドとして実行しようと試みていたわけです。
    </para>

    <para>この仮定は<quote>現在利用しているシェルがどのようなものであっても</quote>変わりません。</para>
    
    <para>後に &man.sh.1; に変更が加えられ、先頭の 2 バイトを検査した結果
      <literal>:\n</literal> であれば代わりに &man.csh.1; を呼び出す、
      というようになりました (この変更は SCO が最初に行なったと思われます)。</para>

    <para>現在の FreeBSD は、プログラムローダリストを走査します。
      その際、空白文字までの文字列をインタプリタとして認識する、
      通常の <literal>#!</literal> ローダを用いるため、
      該当するものが存在しなければ最終的に /bin/sh がロードされます。</para>

    <para>Linux ABI をサポートするため、FreeBSD は
      ELF バイナリを示すマジックナンバを確認します。
      (ただし、この段階では FreeBSD、Solaris、Linux、そしてその他の
      ELF イメージ形式を使っている OS を区別することはできません)。</para>

    <para>ELF ローダは、特殊な<emphasis>マーク (brand)</emphasis> があるかどうか探します。
      このマークとは、ELF イメージのコメントセクションのことです。
      SVR4/Solaris の ELF バイナリには、このセクションは存在しません。</para>

    <para>Linux バイナリを実行するためには、
      ELF バイナリに &man.brandelf.1; で説明されている
      <literal>Linux</literal> のマークが<emphasis>付けられて</emphasis>いなければなりません。</para>
                       
    <screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen>

    <para>上のようにすることで、指定されたファイルは
        <literal>Linux</literal> のマークが付けられ、
        ELF ローダが認識できるようになります。</para>

    <para>ELF ローダが <literal>Linux</literal> マークを確認すると、
      ローダは <literal>proc</literal> 構造体内の
      ある一つのポインタを置き換えます。システムコールは全て、
      このポインタ (伝統的な UNIX システムではこれは構造体の配列 <literal>sysent[]</literal>
      で、システムコールが含まれています) を通してインデックスされます。
      さらに、そのプロセスには Linux カーネルモジュールに必要な
      シグナルトランポリンコード (訳注:
      シグナルの伝播を実現するコード) 用の特殊なトラップベクタの設定や、
      他の (細かな) 調整のための設定が行なわれます。</para>

    <para>Linux システムコールベクタは、
      さまざまなデータに加えて <literal>sysent[]</literal>
      エントリーのリストを含んでおり、それらのアドレスはカーネルモジュール内にあります。</para>

    <para>Linux バイナリがシステムコールを発行する際、トラップコードは
      <literal>proc</literal> 構造体を用いてシステムコール関数ポインタを 
      解釈します。そして FreeBSD ではなく
      Linux 用のシステムコールエントリポイントを得るわけです。</para>

    <para>さらに、Linux モードは状況に応じて<emphasis>ファイルシステム本来のルートマウントポイントを置き換えて</emphasis>ファイルの参照を行ないます。
      これは、<literal>union</literal> オプションを指定してマウントされたファイルシステム
      (unionfs では<emphasis>ありません!</emphasis>)が行なっていることと同じです。
      ファイルを検索する際にはまず
      <filename>/compat/linux/<replaceable>original-path</replaceable></filename>
      ディレクトリを、<emphasis>それから</emphasis>見つけられなかったときにのみ、
      <filename>/<replaceable>original-path</replaceable></filename>
      を調べます。
      こうすることで、他のバイナリを要求するバイナリの実行を可能にしています
      (したがって、Linux 用プログラムツールは Linux ABI サポート環境下で完全に動作するわけです)。
      またこれは、もし対応する Linux バイナリが存在しない場合に
      Linux バイナリが FreeBSD バイナリをロードしたり、実行したりすることが可能であること、
      その Linux バイナリに自分自身が Linux 上で実行されていないことを
      気付かせないようにする目的で、&man.uname.1; コマンドを
      <filename>/compat/linux</filename> ディレクトリに置くことができる、
      ということを意味します。
    </para>

    <para>要するに、Linux カーネルが FreeBSD カーネルの内部に存在しているわけです。
      カーネルによって提供されるサービス全ての実装の基礎となるさまざまな関数は
      FreeBSD システムコールテーブルエントリと
      Linux システムコールテーブルエントリの両方で共通に利用されています。
      これらにはファイルシステム処理、仮想メモリ処理、シグナル伝送、System V IPC
      などが含まれますが、
      FreeBSD バイナリは FreeBSD <emphasis>グルー</emphasis> (訳注: glue;
      二者の間を仲介するという意味) 関数群、
      そして Linux バイナリは Linux <emphasis>グルー</emphasis>関数群を用いる、
      という点だけが異なります (過去に存在したほとんどの OS は、
      自分自身のための<emphasis>グルー</emphasis>関数群しか備えていません。
      前述したように、システムコールを発行する際、
      各々のプロセスの <literal>proc</literal> 構造体内にある、
      ローダによって動的に初期化されるポインタを参照してアドレスを得る代わりに、
      静的でグローバルな <literal>sysent[]</literal> 構造体の配列に
      システムコール関数のアドレスが直接格納されているのです)。</para>

    <para>さて、どちらを本来の FreeBSD ABI (訳注: Applications Binary Interface;
      同じ CPU を利用したコンピュータ間でバイナリを共有するための規約のこと)
      と呼ぶべきなのでしょうか?
      実は、どちらが本来のものであるかということを論ずることに意味はありません。
      基本的に、FreeBSD <emphasis>グルー</emphasis>関数群はカーネルの中に静的にリンクされていて、
      Linux <emphasis>グルー</emphasis>関数群は静的にリンクすることも、
      カーネルモジュールを介して利用することもできるようになっている、
      という違いがあるだけ (ただしこれは現時点においての話であり、
      将来のリリースで変更される可能性がありますし、
      おそらく実際に変更されるでしょう) です。</para>
                       
    <para>あ、「でもこれは本当にエミュレーションと呼べるのか」って?
      答えは「いいえ」です。これは ABI の実装であり、
      エミュレーションとは異なります。エミュレータが呼び出されているわけではありません
      (シミュレータでもないことをあらかじめ断っておきましょう)。</para>

    <para>では、これがよく <quote>Linux エミュレーション</quote>と呼ばれるのは何故でしょうか?
     それはもちろん FreeBSD の売りにするため <!-- smiley -->8-) でもあるのですが、
     実際には、次のような理由によります。
     この機能が初めて実装された頃、
     動作原理を説明する以外にこの機能を表現する言葉はありませんでした。
     しかし、コードをコンパイルしたりモジュールをロードしない場合、
     「FreeBSD 上で Linux バイナリを実行する」という表現は、
     厳密に考えると適切ではありません。
     そこで、その際にロードされているもの自身を表現する言葉 &mdash; すなわち
     <quote>Linux エミュレータ</quote>が必要だったのです。</para>
    </sect2>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->
