Date: Tue, 10 Jun 2014 07:15:24 +0000 (UTC) From: Fukang Chen <loader@FreeBSD.org> To: doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org Subject: svn commit: r45041 - head/zh_CN.UTF-8/books/handbook/linuxemu Message-ID: <201406100715.s5A7FOdT020964@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: loader Date: Tue Jun 10 07:15:24 2014 New Revision: 45041 URL: http://svnweb.freebsd.org/changeset/doc/45041 Log: MFen: linuxemu/chapter.xml r36653 -> r44899 Modified: head/zh_CN.UTF-8/books/handbook/linuxemu/chapter.xml Modified: head/zh_CN.UTF-8/books/handbook/linuxemu/chapter.xml ============================================================================== --- head/zh_CN.UTF-8/books/handbook/linuxemu/chapter.xml Tue Jun 10 03:35:04 2014 (r45040) +++ head/zh_CN.UTF-8/books/handbook/linuxemu/chapter.xml Tue Jun 10 07:15:24 2014 (r45041) @@ -2,298 +2,281 @@ <!-- The FreeBSD Documentation Project - Original Revision: 1.142 + Original Revision: r44899 $FreeBSD$ --> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="linuxemu"> - <info><title>Linux二进制兼容模式</title> +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" + xml:id="linuxemu"> + <info> + <title>&linux; 二进制兼容模式</title> + <authorgroup> - <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured and parts updated by </contrib></author> + <author> + <personname> + <firstname>Jim</firstname> + <surname>Mock</surname> + </personname> + <contrib>Restructured and parts updated by </contrib> + </author> <!-- 22 Mar 2000 --> </authorgroup> + <authorgroup> - <author><personname><firstname>Brian N.</firstname><surname>Handy</surname></personname><contrib>Originally contributed by </contrib></author> - <author><personname><firstname>Rich</firstname><surname>Murphey</surname></personname></author> + <author> + <personname> + <firstname>Brian N.</firstname> + <surname>Handy</surname> + </personname> + <contrib>Originally contributed by </contrib> + </author> + + <author> + <personname> + <firstname>Rich</firstname> + <surname>Murphey</surname> + </personname> + </author> </authorgroup> </info> - - <sect1 xml:id="linuxemu-synopsis"> <title>概述</title> - <indexterm><primary>Linux二进制兼容模式</primary></indexterm> + + <indexterm> + <primary>Linux 二进制兼容模式</primary> + </indexterm> <indexterm> <primary>二进制兼容模式</primary> <secondary>Linux</secondary> </indexterm> - <para>FreeBSD 提供了与其他几种类 - &unix; 操作系统, 包括 Linux, 的兼容性。 现在您可能会问, 为什么 - FreeBSD 需要能够运行 Linux 的可执行文件? 答案很简单。 - 许多公司和开发人员只为 Linux 开发程序, - 因为这是目前计算机世界 <quote>最热门</quote> 的技术。 - 这使得我们 FreeBSD 用户不得不去劝说这些公司和开发人员提供他们应用程序可以直接在 - FreeBSD 上运行的版本。 问题是, 许多这样的公司并不真的知道到底提供了 - FreeBSD 版本之后能带来多少用户, 因此许多仍然只开发 Linux - 的版本。 这时 FreeBSD 用户能做什么呢? 答案就是使用 FreeBSD - 所提供的 Linux 二进制兼容性。</para> - - <para>简而言之, 这种兼容性能够让 FreeBSD 用户不加修改地直接运行大约 90% - 的 Linux 应用程序。 这包括类似 <application>&staroffice;</application>, - Linux 版本的 <application>&netscape;</application>, - <application>&adobe; &acrobat;</application>, - <application>&realplayer;</application>, - <application>VMware</application>, - <application>&oracle;</application>, - <application>&wordperfect;</application>, - <application>Doom</application>, - <application>Quake</application>, 等等。 此外, 也有人说, - 某些情况下, 在 FreeBSD 上面运行的 Linux 程序的性能, - 甚至好于直接在 Linux 上面运行。</para> - - <para>然而, 仍然有一些只有 Linux 才有的操作系统特性在 FreeBSD 上并不被支持。 - 如果 Linux 程序过分地使用只能在 &i386; 上使用的特性, - 例如启用虚拟 8086 模式, 则也有可能无法在 FreeBSD 上运行。</para> + <para>&os; 提供了与 &linux; 32-bit 二进制兼容, + 允许用户在 &os; 系统上安装和运行大多数的 32-bit &linux; + 二进制程序而无需做任何修改。 据说在某些情况下, &os; 上运行的 + 32-bit &linux; 二进制程序能有更好的表现。</para> + + <para>然而, 仍然有一些 &linux; 操作系统特有的功能在 &os; + 上并不被支持。 例如, 要是 &linux; + 程序过度地使用了诸如启用虚拟 8086 模式 &i386; 特有的调用, + 则无法在 &os; 上运行。 另外, 目前还不支持 64-bit 的 &linux; + 二进制程序。</para> <para>读完这章,您将了解到:</para> + <itemizedlist> <listitem> - <para> 如何在您的系统中启用Linux兼容模式。</para> + <para>如何在 &os; 系统中启用 &linux; 二进制兼容模式。</para> </listitem> <listitem> - <para>如何安装额外的Linux共享库。</para> - </listitem> + <para>如何安装额外的 &linux; 共享库。</para> + </listitem> <listitem> - <para>如何在FreeBSD上安装Linux应用程序。</para> + <para>如何在 &os; 上安装 &linux; 应用程序。</para> </listitem> <listitem> - <para>在FreeBSD上,Linux兼容模式的执行细节。</para> + <para>&os; 上 &linux; 兼容模式的实现细节。</para> </listitem> </itemizedlist> - <para>阅读这章之前,您应该知道:</para> + <para>在阅读这章之前,您应该知道:</para> <itemizedlist> <listitem> - <para>如何安装第三方软件(<xref linkend="ports"/>)。</para> + <para>知道如何安装 <link linkend="ports"> + 额外的第三方软件</link>。</para> </listitem> </itemizedlist> </sect1> <sect1 xml:id="linuxemu-lbc-install"> - <title>安装</title> + <title>配置 &linux; 二进制兼容模式</title> - <indexterm><primary>KLD (kernel loadable object)</primary></indexterm> + <indexterm><primary>Ports Collection</primary></indexterm> - <para>默认情况下, 并不开启 Linux 二进制兼容支持。 - 启用这一功能最简单的方法是载入 - <literal>linux</literal> KLD 模块 (<quote>Kernel LoaDable - object</quote>)。 以 <systemitem class="username">root</systemitem> - 的身份, 键入下列命令即可:</para> + <para>默认情况下, &linux; 库并没有被安装而且 &linux; + 二进制兼容模式也没有被启动。 &linux; + 库可以通过手动安装或者使用 &os; 的 Ports Collection。</para> - <screen>&prompt.root; <userinput>kldload linux</userinput></screen> + <para>安装 <package>emulators/linux-base-f10</package> 包或者 + port 是最容易在 &os; 系统上获得一套基本的 &linux; 库的方法。 + 使用如下方法安装 port:</para> - <para>如果希望 Linux 兼容支持在系统初始化过程中自动启用, 则应在 - <filename>/etc/rc.conf</filename> 中增加:</para> + <screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base-f10</userinput> +&prompt.root; <userinput>make install distclean</userinput></screen> - <programlisting>linux_enable="YES"</programlisting> + <para>安装完成以后, 加载 <literal>linux</literal> + 模块启用 &linux; 二进制兼容模式:</para> - <para>&man.kldstat.8;可以用来检查KLD模块是否加载:</para> + <screen>&prompt.root; <userinput>kldload linux</userinput>userinput></screen> + + <para>查看模块是否已经被加载:</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>在 <filename>/etc/rc.conf</filename> 中加入以下这行后 + &linux; 兼容模式便会在系统启动时自动开启:</para> + + <programlisting>linux_enable="YES"</programlisting> + <indexterm> - <primary>kernel options (内核选项)</primary> + <primary>kernel options</primary> <secondary>COMPAT_LINUX</secondary> </indexterm> - <para>如果您不想或者无法将Linux KLD加载,您就需要在内核中静态链接进Linux二进制兼容模式。您必须在 - 您的内核配置文件里面加入<literal>options COMPAT_LINUX</literal>,然后按照<xref linkend="kernelconfig"/>重新编译内核。 - </para> + <para>想要在自制内核中静态链接 &linux; + 二进制兼容支持的用户可以在自定义的内核配置文件中加入 + <literal>options COMPAT_LINUX</literal>literal>。 + 然后按照 <xref linkend="kernelconfig"/> + 中所描述的方法编译并安装新内核。</para> + + <sect2 xml:id="linuxemu-libs-manually"> + <title>手动安装额外的库</title> - <sect2> - <title>安装Linux运行时库</title> <indexterm> - <primary>Linux</primary> - <secondary>安装Linux运行时库</secondary> + <primary>shared libraries</primary> </indexterm> - <para>有两种方法来安装Linux运行时库,要么使用<link linkend="linuxemu-libs-port">linux_base</link> port, - 要么<link linkend="linuxemu-libs-manually">手动</link>安装。</para> - - <sect3 xml:id="linuxemu-libs-port"> - <title>通过使用 linux_base Port 来安装</title> - <indexterm><primary>Ports Collection</primary></indexterm> - - <para>这是最容易的安装方法,只需要像安装其他port一样从 - <link xlink:href="file://localhost/usr/ports/">Ports Collection</link>来安装:</para> - - <screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base-f10</userinput> -&prompt.root; <userinput>make install distclean</userinput></screen> - - <note> - <para>对于 &os; 8.0 之前的版本的 &os; 系统, - 你需要使用 <package>emulators/linux_base-fc4</package> port - 而不是 <package>emulators/linux_base-f10</package>。</para> - </note> + <para>在配置了 &linux; 兼容模式之后, + 如果某个 &linux; 应用程序依然提示找不到共享库, + 需先找出此 &linux; 二进制程序需要的共享库再手动安装。</para> + + <para>在 &linux; 系统上使用 <command>ldd</command> + 找出应用程序所需的共享库文件。 比如, + 在安装有 <application>Doom</application> 的 &linux; + 系统上运行如下的命令列出 <command>linuxdoom</command> + 所需用到的共享库文件:</para> - <para> - 您现在应当是工作在Linux兼容模式下了。一些程序可能会提示系统库的版本不正确。通常,这不是问题。</para> - - <note><para>有多个版本的<package>emulators/linux_base</package> port,针对不同的版本的Linux。 - 您应该选择最接近Linux应用程序需要的那个版本来安装。</para></note> - - </sect3> - - <sect3 xml:id="linuxemu-libs-manually"> - <title>手动安装</title> - - <para>如果您没有安装 Ports Collection,您也可以通过手动来安装Linux运行时库。 - 您将需要这些程序依赖的Linux共享库,而且您需要创建一个<quote>shadow root</quote> - 目录<filename>/compat/linux</filename>,任何要被Linux程序打开的共享库都首先在这个目录里面查找。 - 所以,如果一个Linux程序加载了,例如,<filename>/lib/libc.so</filename>,FreeBSD 会首先尝试打开 - <filename>/compat/linux/lib/libc.so</filename>,如果不存在,它将尝试打开<filename>/lib/libc.so</filename>。 - 共享库应该安装在<filename>/compat/linux/lib</filename>而不是Linux <command>ld.so</command>报告的其他路径。</para> - - <para>通常,您需要寻找Linux程序依赖的共享库。 此后, - 你的系统上就会有一组 Linux 共享库, - 这组共享库足以用来运行新安装的 Linux 二进制程序。</para> - </sect3> - - <sect3> - <title>如何安装额外的共享库</title> - <indexterm><primary>共享库</primary></indexterm> - - <para>如果您安装了<filename>linux_base</filename> port,但是您的 - 您的应用程序仍会报告丢失共享库的信息?您如何知道Linux程序需要哪个共享库? - 基本上,有两种可能性(接下来的指令需要<systemitem class="username">root</systemitem>权限):</para> - - <para>如果您有可以访问的Linux系统, 看看应用程序需要什么共享库, - 把它们复制到您的FreeBSD系统。看下面的例子:</para> - - <informalexample> - <para>我们假设您通过FTP得到Linux程序<application>Doom</application>, - 并把它放在您能访问的Linux系统上。然后您可以通过<command>ldd linuxdoom</command>来检查需要哪些共享库, - 就像这样:</para> - - <screen>&prompt.user; <userinput>ldd linuxdoom</userinput> + <screen>&prompt.user; <userinput>ldd linuxdoom</userinput> 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</screen> - <indexterm><primary>符号链接</primary></indexterm> - <para>您需要得到上面输出的右列的所有文件,并把它们复制到 <filename>/compat/linux</filename>, - 第一列的名字用符号连接指向它们。这样您的FreeBSD系统上就有了这些文件:</para> + <indexterm> + <primary>symbolic links</primary> + </indexterm> + + <para>然后把上面输出中最后一列中的所有文件从 &linux; + 系统复制到 &os; 上的 <filename>/compat/linux</filename>。 + 复制完成之后, 建立指向第一栏中文件名的符号链接。 + 这样在 &os; 系统上将会有如下的文件:</para> - <screen>/compat/linux/usr/X11/lib/libXt.so.3.1.0 + <screen>/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</screen> - <blockquote> - <note> - <para>如果您已经有了一个与<command>ldd</command> 输出的第一列的主修订号相匹配的Linux共享库, - 您就已经完成了工作, 而不需要把右列命名的文件复制到您的系统上了。 - 如果有一个新的版本, 那无论如何都要复制一个共享库。 - 您可以删掉旧的, 您只要做一个符号连接到新的版本。 - 所以,如果有这些库在您的系统上: - </para> + <para>如果已经有了一个与 <command>ldd</command> + 输出中第一列的主修订号相同的 &linux; 共享库文件, + 则不再需要复制最后那列文件, 现有的共享库应该可以正常使用。 + 如果是更新版本的共享库通常建议复制。 + 只要有符号链接指向新的版本, 那么就可以删除旧版的了。</para> - <screen>/compat/linux/lib/libc.so.4.6.27 + <para>比如, &os; 系统中现有这些共享库文件:</para> + + <screen>/compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27</screen> - <para>如果您根据<command>ldd</command>输出的发现需要一个更新版本的库:</para> + <para>并且 <command>ldd</command> 指出某个二进制程序需要之后版本:</para> - <screen>libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29</screen> + <screen>libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29</screen> - <para>如果结尾的数字只有一到两个版本过期,那也不要担心复制 <filename>/lib/libc.so.4.6.29</filename>, - 因为程序在稍微旧一些的版本上也能很好地工作。 - 然而,如果喜欢的话,您可以替换<filename>libc.so</filename>,变成这样:</para> + <para>既然现有文件最后的版本号只相差一到两个版本, + 程序应该可以正常使用稍旧些的版本。 不管怎样, + 使用新版本替换现有 <filename>libc.so</filename> 都是安全的。</para> - <screen>/compat/linux/lib/libc.so.4.6.29 + <screen>/compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29</screen> - </note> - </blockquote> - <blockquote> - <note> - <para>符号链接机制 <emphasis>仅仅是</emphasis> Linux 程序需要的。 - FreeBSD 的运行时连接器会自己寻找匹配的主修订号,您不需要为此担心。</para> - </note> - </blockquote> - </informalexample> - </sect3> + <para>通常最初几次在 &os; 上安装 &linux; 程序时需要寻找 &linux; + 二进制程序所依赖的共享库文件。 在此之后, 系统里便会有足够多的 &linux; + 共享库文件来运行新安装的 &linux; 二进制程序而无需额外操作。</para> </sect2> <sect2> - <title>安装Linux ELF程序</title> + <title>安装 &linux; <acronym>ELF</acronym> + 二进制程序</title> + <indexterm> - <primary>Linux</primary> - <secondary>ELF程序</secondary> + <primary>Linux</primary> + <secondary>ELF binaries</secondary> </indexterm> - <para>ELF格式的程序需要一步额外的步骤<quote>标记</quote>。如果您尝试运行没有标记的ELF程序, - 您会得到像下面这样的错误信息:</para> + <para><acronym>ELF</acronym> 二进制程序有时需要额外的步骤。 + 当未被标记的 <acronym>ELF</acronym> 二进制程序被执行的时候, + 会生成如下的错误信息:</para> <screen>&prompt.user; <userinput>./my-linux-elf-binary</userinput> ELF binary type not known Abort</screen> - <para>为帮助 FreeBSD 内核分辨 FreeBSD ELF - 执行文件和 Linux 执行文件, 需要使用 &man.brandelf.1; - 工具。</para> + <para>为了帮助 &os; 内核分辨 &os; <acronym>ELF</acronym> + 二进制程序和 &linux; 二进制程序, 请使用 &man.brandelf.1;:</para> <screen>&prompt.user; <userinput>brandelf -t Linux my-linux-elf-binary</userinput></screen> - <indexterm><primary>GNU工具</primary></indexterm> - <para>GNU工具现在会自动把适当的标记信息放到ELF程序中,您以后遇到这个问题的机会越来越少。</para> + <indexterm> + <primary>GNU toolchain</primary> + </indexterm> + + <para>由于现在的 GNU 工具链能自动把适当的标记信息写入 <acronym>ELF</acronym> + 二进制程序中,这个步骤通常不是必须做的。</para> </sect2> <sect2> - <title>安装各种基于 RPM 的应用程序</title> + <title>安装基于 &linux; <acronym>RPM</acronym> 的应用程序</title> - <para>FreeBSD 使用自己的包数据库来跟踪所有的 ports (包括 &linux; ports)。 - 所以无法使用(不支持) &linux; RPM 数据库。</para> - - <para>如果你需要安装任意的一个基于 RPM 的 &linux; 应用程序, - 可以通过一下的步骤完成:</para> + <para>安装基于 &linux; <acronym>RPM</acronym> 的应用程序, + 首先需要安装 <package>archivers/rpm</package> 包或者 port。 + 安装好之后 <systemitem class="username">root</systemitem> + 用户就能使用此命令安装 <filename>.rpm</filename> 了:</para> <screen>&prompt.root; <userinput>cd /compat/linux</userinput> -&prompt.root; <userinput>rpm2cpio -q < /path/to/linux.archive.rpm | cpio -id</userinput></screen> +&prompt.root; <userinput>rpm2cpio < /path/to/linux.archive.rpm | cpio -id</userinput></screen> - <para>然后对已安装的 ELF 二进制程序(不包括库)运行 brandelf。 - 用此种方法安装的程序不能被完全卸载, 但是可能有助于做些测试。</para> + <para>如有必要的话使用 <command>brandelf</command> 标记安装好的 + <acronym>ELF</acronym> 二进制程序。 注意此项安装将无法干净卸载。</para> </sect2> <sect2> <title>配置主机名解析器</title> - <para>如果DNS不能正常工作或是您得到下列信息:</para> + <para>如果 <acronym>DNS</acronym> 不能正常工作或是出现以下的错误信息:</para> <screen>resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword</screen> - <para>您就需要配置<filename>/compat/linux/etc/host.conf</filename>文件,此文件包含:</para> + <para>请参照此方法配置 <filename>/compat/linux/etc/host.conf</filename>:</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>然后提示不兼容的FreeBSD语法。 - 如果您没有使用<filename>/etc/resolv.conf</filename> 文件设置DNS,应该删除<literal>bind</literal>。 - </para> + <para>这里指定了先查询 <filename>/etc/hosts</filename> + 再查询 <acronym>DNS</acronym>。 如果 + <filename>/compat/linux/etc/host.conf</filename> 不存在的话, + &linux; 程序便会读取 <filename>/etc/host.conf</filename> + 并提示与 &os; 的语法不兼容。 如果没有在 + <filename>/etc/resolv.conf</filename> 文件中配置域名服务器, + 可以删除 <literal>bind</literal>。</para> </sect2> </sect1> + <?ignore + + While the installer works, the binaries do not. As of Oct 2013, + Linux emulation is 32-bit but the trial version of Mathematica is + only available as 64-bit. This section should be revisited if Linux + emulation gets 64-bit binary support. + <sect1 xml:id="linuxemu-mathematica"> <info><title>安装&mathematica;</title> <authorgroup> @@ -438,7 +421,13 @@ done</programlisting> 您可以把<filename>MathType1</filename>改成<filename>Type1</filename>。</para> </sect2> </sect1> + --> + <!-- + As of October 2013, the trial version is only available in the + Professional and Academic editions (not the Student or Personal + editions) and requires a contact with a product specialist before + the evaluation download link is made available. <sect1 xml:id="linuxemu-maple"> <info><title>安装&maple;</title> <authorgroup> @@ -563,6 +552,11 @@ FEATURE Maple maplelmg 2000.0831 permane </itemizedlist> </sect2> </sect1> + --> + + <!-- + As of October, 2013, the Linux version of Matlab is only available + for 64-bit. <sect1 xml:id="linuxemu-matlab"> <info><title>安装&matlab;</title> @@ -1015,123 +1009,99 @@ export PATH</programlisting> <para>如果您已经按上面的指示去操作,您应该可以像在Linux下运行<application>&oracle;</application>了。 </para> </sect2> </sect1> + ?> <sect1 xml:id="linuxemu-advanced"> <title>高级主题</title> - <para>如果您对Linux兼容模式是如何工作的感到好奇,这节正是您所需要的。 下面的绝大部分内容是由 - Terry Lambert<email>tlambert@primenet.com</email> (Message ID: - <literal><199906020108.SAA07001@usr09.primenet.com></literal>)发表在邮件列表&a.chat;上的内容组成的。 - </para> - - <sect2> - <title>它是如何工作的?</title> - <indexterm><primary>可执行类加载器</primary></indexterm> - - <para>FreeBSD有一个<quote>可执行类加载器</quote>。它主要是嵌入了&man.execve.2;系统调用。 -</para> - - - <para>碰巧的是FreeBSD有一个引导器(loader)的列表,而不是一个简单的返回一个 - 符号 <literal>#!</literal>的引导器!</para> - - <para>从历史上来讲,只有&unix;平台的引导器会检查魔术(magic)数 - (通常是文件的前4个或8个字节)是否是二进制的, - 如果是,就调用二进制引导程序。</para> - - - - <para>如果它不是二进制类型的&man.execve.2;调用就会返回一个错误,shell就试图用shell命令执行它。 - </para> + <para>此章节将讲述是 &linux; 二进制兼容如何工作的, + 内容基于 Terry Lambert <email>tlambert@primenet.com</email> (Message ID: + <literal><199906020108.SAA07001@usr09.primenet.com></literal>) + 发表在 &a.chat; 的邮件。</para> - <para>缺省是使用<quote>当前设定的shell</quote>。</para> + <indexterm><primary>execution class loader</primary></indexterm> + <para>&os; 有一个叫 <quote>execution class loader</quote> 的抽象层。 + 它被嵌入进了 &man.execve.2; 系统调用。</para> + <para>历史上 &unix; 加载器会依靠查看魔数 + (通常是文件的开头 4 至 8 个字节)来确认是否是系统已知的的二进制程序, + 如果是的话, 就会调用二进制程序加载器。</para> - <para>随后,进行了一些hack, &man.sh.1;开始检查前两个字符,如果它们是<literal>:\n</literal>, - 那它就调用&man.csh.1;(我们相信是SCO最先做这个hack的)。</para> + <para>如果它不是二进制类型的程序, &man.execve.2; 调用会返回一个错误, + shell 则会把它当作 shell 命令执行。 + <quote>不论当前是哪一种 shell</quote> 都会默认做出此种假设。</para> - <para>FreeBSD现在所做的是用一个普通的<literal>#!</literal>引导器仔细检查引导器的列表, - 然后由解释程序一个接一个地解释,返回给<filename>/bin/sh</filename>。 - </para> - <indexterm><primary>ELF</primary></indexterm> - - <para>为了支持Linux ABI,FreeBSD就把魔术数看作为一个二进制ELF程序。( - 这样一来,它就使得在FreeBSD, &solaris;,Linux和其他任何操作系统之间只要使用ELF格式就都可以顺利运行)。 - </para> - <indexterm><primary>Solaris</primary></indexterm> - - <para>ELF引导器会寻找一个专门的<emphasis>标记</emphasis>, - 它是在ELF映像中的一个注释部分,但在SVR4/&solaris;的ELF中没有。 -</para> - - <para>为了执行Linux程序,它们必须被打上<literal>Linux</literal>类型的<emphasis>标记</emphasis>; - 使用&man.brandelf.1;:</para> - - <screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen> + <para>随后, &man.sh.1; 会检查开头的两个字符, + 如果它们是 <literal>:\n</literal>, 那么就调用 &man.csh.1;。</para> + <para>&os; 有一份加载器列表而不是一个单一的加载器, 并能回退到 + <literal>#!</literal> 加载器来运行 shell 解释器或者 shell 脚本。</para> + <indexterm> + <primary>ELF</primary> + </indexterm> - <para>做完之后,ELF引导器就会看到文件上的<literal>Linux</literal>的标记。 - </para> - <indexterm> - <primary>ELF</primary> - <secondary>标记</secondary> - </indexterm> - - <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>结构中解除, - 然后获得Linux,而不是FreeBSD,系统调用入口点。</para> - - <para>另外,Linux模式动态地<emphasis>reroots</emphasis>查找;这和启动文件系统的<option>union</option> - 选项是等效的(即时不是<literal>unionfs</literal>文件系统)。 - 首先会试图在<filename>/compat/linux/original-path</filename> - 目录查找文件,如果失败了,就会在<filename>/original-path</filename> - 目录下查找。这使得需要其它程序的程序可以运行(例如,Linux工具链都可以在Linux ABI的支持下工作)。 - 也就是说Linux程序可以加载和执行FreeBSD程序,如果当前没有相应的Linux程序, - 那您可以在<filename>/compat/linux</filename>目录树中放置一个&man.uname.1;,使 Linux 程序不易察觉它们并没有运行在 Linux 系统上。 - </para> - - <para>在FreeBSD内核中有一个Linux内核;由内核提供的能够提供所有服务的各种潜在功能 - 在FreeBSD系统调用表记录和Linux系统调用表记录之间是一样的: - 文件系统操作,虚拟内存操作,信号发送,System V IPC,…等等。 - 唯一的不同是FreeBSD会得到FreeBSD的<emphasis>胶合</emphasis>功能, - 而Linux程序会得到Linux的<emphasis>胶合</emphasis>功能 - (大部分老的操作系统只有它们自己的<emphasis>胶合</emphasis>函数, - 函数地址在静态全局变量<literal>sysent[]</literal>结构数据里面, - 而不是动态的初始化到进程的<literal>proc</literal>结构)。 - </para> - - - - <para>哪一个是FreeBSD自己的ABI呢?这无关紧要。基本上, - 唯一的不同是FreeBSD的<emphasis>胶合</emphasis>功能是被静态连接到内核, - 而Linux的<emphasis>胶合</emphasis>功能可能是被静态连接到内核, - 也可能它们通过一个内核模块来访问。 - </para> + <indexterm> + <primary>Solaris</primary> + </indexterm> + <para>为了支持 &linux; <acronym>ABI</acronym>, &os; 看到了二进制 ELF 程序的魔数。 + ELF 加载器会查找一个专用的 <emphasis>标记</emphasis>, + 那是在 ELF 镜像中的一个注释部分, + 此区域在 SVR4/&solaris; ELF 二进制中并不存在。</para> + + <para>要运行 &linux; 二进制程序, + 必须先使用 &man.brandelf.1; 命令 <emphasis>标记</emphasis> 为 + <literal>Linux</literal> 类型:</para> + <screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen> - <para>有一个真正的模拟器吗?没有,它只不过是一个ABI执行机制,不是一个模拟器。</para> + <indexterm> + <primary>ELF</primary> + <secondary>标记</secondary> + </indexterm> - <para>为什么有时它被叫做<quote>Linux模拟器</quote>? - 只是为了更容易地卖出FreeBSD罢了! - 实际上,历史上从来没有描述这样一种执行机制的名字,FreeBSD并不是真正地运行Linux程序,如果您不编译进代码, - 或加载一个模块。 - 就需要有一个名字来描述这样一种加载功能--因此就想出了<quote>Linux模拟器</quote>这样一个名字。 - </para> - </sect2> - </sect1> + <para>当 ELF 加载器看到了 <literal>Linux</literal> + 标记,便会替换 <literal>proc</literal> 结构中的一个指针。 + 所有的系统调用都通过此指针来索引。 除此以外, + 进程被标记以便对 signal trampoline 代码的陷阱向量做特殊处理, + 还有一些其他由 &linux; 内核模块来处理的(细微)修补。</para> + + <para>&linux; 系统调用向量包含一个 <literal>sysent[]</literal> + 记录的列表, 它的地址位于内核模块之中。</para> + + <para>当一个系统调用被 &linux; 二进制程序调用时, + 陷阱代码会把系统调用函数指针从 <literal>proc</literal> + 解引用至 &linux; 而不是 &os; 的系统调用入口。</para> + + <para>&linux; 模式会动态地 <emphasis>reroots</emphasis> 查找。 + 这与 <option>union</option> 文件系统选项是等效的。 + 首先会试图在 <filename + class="directory">/compat/linux/<replaceable>original-path</replaceable></filename> + 目录查找文件。 如果失败了, 就会在 <filename + class="directory">/<replaceable>original-path</replaceable></filename> + 目录下查找。 这使得需要其它程序的程序得以运行。 例如,&linux; + 工具链都可以在 &linux; <acronym>ABI</acronym> 的支持下运行。 + 也就是说 &linux; 二进制程序可以加载并执行 &os; 二进制程序, + 如果当前没有相应的 &linux; 二进制程序, + 可以在 <filename>/compat/linux</filename> 目录树中放置一个 + &man.uname.1; 命令, 使 &linux; 程序不易察觉它们并没有运行在 &linux; + 系统上。</para> + + <para>事实上, 在 &os; 内核中有一个 &linux; 内核。 + 所有由内核提供的服务的各种底层功能在 &os; 系统调用表的记录和 &linux; + 系统调用表的记录是一样的: 文件系统操作, 虚拟内存操作, + 信号发送, 和 System V IPC。 唯一的不同是 &os; 会得到 &os; 的 + <emphasis>glue</emphasis> 功能, 而 &linux; 程序会得到 &linux; + 的 <emphasis>glue</emphasis> 功能。 &os; 的 <emphasis>glue</emphasis> + 功能是静态链接入内核的, 而 &linux; 的 <emphasis>glue</emphasis> + 功能可以静态链接, 或者通过内核模块访问。</para> + + <para>严格说来其实并没有真正的模拟, 这是一种 <acronym>ABI</acronym> + 的实现。 有时这被称为 <quote>&linux; 模拟</quote> + 是因为在实现的时候还没有其他适合的词用来描述。 + 要说 &os; 运行 &linux; 二进制程序并不确切, + 因为当时代码并还没有被编译进去。</para> + </sect1> </chapter>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406100715.s5A7FOdT020964>