FreeBSD, Inc. now owes me a new keyboard as I've seemed to have worn out my "shift" and "`" key from sending vi so many "~"s. :->
947 lines
39 KiB
Text
947 lines
39 KiB
Text
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$Id: chapter.sgml,v 1.15 1999-06-20 21:19:13 billf Exp $
|
|
-->
|
|
|
|
<chapter id="linuxemu">
|
|
<title>Linux Emulation</title>
|
|
|
|
<para><emphasis>Contributed by &a.handy; and &a.rich;</emphasis></para>
|
|
|
|
<sect1>
|
|
<title>How to Install the Linux Emulator</title>
|
|
|
|
<para>Linux emulation in FreeBSD has reached a point where it is possible
|
|
to run a large fraction of Linux binaries in both a.out and ELF format.
|
|
The linux emulation in the 2.1-STABLE branch is capable of running Linux
|
|
DOOM and Mathematica; the version present in &rel.current;-RELEASE is
|
|
vastly more capable and runs all these as well as Quake, Abuse, IDL,
|
|
netrek for Linux and a whole host of other programs.</para>
|
|
|
|
<para>There are some Linux-specific operating system features that are not
|
|
supported on FreeBSD. Linux binaries will not work on FreeBSD if they
|
|
use the Linux <filename>/proc</filename> filesystem (which is different
|
|
from the optional FreeBSD <filename>/proc</filename> filesystem) or
|
|
i386-specific calls, such as enabling virtual 8086 mode.</para>
|
|
|
|
<para>Depending on which version of FreeBSD you are running, how you get
|
|
Linux-emulation up will vary slightly:</para>
|
|
|
|
<sect2>
|
|
<title>Installing Linux Emulation in 2.1-STABLE</title>
|
|
|
|
<para>The <filename>GENERIC</filename> kernel in 2.1-STABLE is not
|
|
configured for linux compatibility so you must reconfigure your kernel
|
|
for it. There are two ways to do this: 1. linking the emulator
|
|
statically in the kernel itself and 2. configuring your kernel to
|
|
dynamically load the linux loadable kernel module (LKM).</para>
|
|
|
|
<para>To enable the emulator, add the following to your configuration
|
|
file (c.f. <filename>/sys/i386/conf/LINT</filename>):</para>
|
|
|
|
<programlisting>
|
|
options COMPAT_LINUX</programlisting>
|
|
|
|
<para>If you want to run doom or other applications that need shared
|
|
memory, also add the following.</para>
|
|
|
|
<programlisting>
|
|
options SYSVSHM</programlisting>
|
|
|
|
<para>The linux system calls require 4.3BSD system call compatibility.
|
|
So make sure you have the following.</para>
|
|
|
|
<programlisting>
|
|
options "COMPAT_43"</programlisting>
|
|
|
|
<para>If you prefer to statically link the emulator in the kernel rather
|
|
than use the loadable kernel module (LKM), then add</para>
|
|
|
|
<programlisting>
|
|
options LINUX</programlisting>
|
|
|
|
<para>Then run config and install the new kernel as described in the
|
|
<link linkend="kernelconfig">kernel configuration</link>
|
|
section.</para>
|
|
|
|
<para>If you decide to use the LKM you must also install the loadable
|
|
module. A mismatch of versions between the kernel and loadable module
|
|
can cause the kernel to crash, so the safest thing to do is to
|
|
reinstall the LKM when you install the kernel.</para>
|
|
|
|
<screen>&prompt.root; <userinput>cd /usr/src/lkm/linux</userinput>
|
|
&prompt.root; <userinput>make all install</userinput></screen>
|
|
|
|
<para>Once you have installed the kernel and the LKM, you can invoke
|
|
`linux' as root to load the LKM.</para>
|
|
|
|
<screen>&prompt.root; <userinput>linux</userinput>
|
|
Linux emulator installed
|
|
Module loaded as ID 0</screen>
|
|
|
|
<para>To see whether the LKM is loaded, run
|
|
<command>modstat</command>.</para>
|
|
|
|
<screen>&prompt.user; modstat
|
|
Type Id Off Loadaddr Size Info Rev
|
|
Module Name EXEC 0 3 f0baf000 0018 f0bb4000 1 linux_emulator</screen>
|
|
|
|
<para>You can cause the LKM to be loaded when the system boots in either
|
|
of two ways. In FreeBSD 2.2.1-RELEASE and 2.1-STABLE enable it in
|
|
<filename>/etc/sysconfig</filename>
|
|
|
|
<programlisting>
|
|
linux=YES</programlisting>
|
|
|
|
by changing it from NO to YES. FreeBSD 2.1 RELEASE and earlier do not
|
|
have such a line and on those you will need to edit
|
|
<filename>/etc/rc.local</filename> to add the following line.</para>
|
|
|
|
<programlisting>
|
|
linux</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Installing Linux Emulation in 2.2.2-RELEASE and later</title>
|
|
|
|
<para>It is no longer necessary to specify <literal>options
|
|
LINUX</literal> or <literal>options COMPAT_LINUX</literal>. Linux
|
|
emulation is done with an LKM (“Loadable Kernel Module”)
|
|
so it can be installed on the fly without having to reboot. You will
|
|
need the following things in your startup files, however:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>In <filename>/etc/rc.conf</filename>, you need the following
|
|
line:</para>
|
|
|
|
<programlisting>
|
|
linux_enable=YES</programlisting>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>This, in turn, triggers the following action in
|
|
<filename>/etc/rc.i386</filename>:</para>
|
|
|
|
<programlisting>
|
|
# Start the Linux binary emulation if requested.
|
|
if [ "X${linux_enable}" = X"YES" ]; then echo -n '
|
|
linux'; linux > /dev/null 2>&1
|
|
fi</programlisting>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>If you want to verify it is running, modstat will do that:</para>
|
|
|
|
<screen>&prompt.user; modstat
|
|
Type Id Off Loadaddr Size Info Rev Module Name
|
|
EXEC 0 4 f09e6000 001c f09ec010 1 linux_mod</screen>
|
|
|
|
<para>However, there have been reports that this fails on some
|
|
2.2-RELEASE and later systems. If for some reason you cannot load the
|
|
linux LKM, then statically link the emulator in the kernel by
|
|
adding
|
|
|
|
<programlisting>
|
|
options LINUX</programlisting>
|
|
|
|
to your kernel config file. Then run config and install the new
|
|
kernel as described in the <link linkend="kernelconfig">kernel
|
|
configuration</link> section.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Installing Linux Runtime Libraries</title>
|
|
|
|
<sect3>
|
|
<title>Installing using the linux_lib port</title>
|
|
|
|
<para>Most linux applications use shared libraries, so you are still
|
|
not done until you install the shared libraries. It is possible to
|
|
do this by hand, however, it is vastly simpler to just grab the
|
|
linux_lib port:</para>
|
|
|
|
<screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_lib</userinput>
|
|
&prompt.root; <userinput>make all install</userinput></screen>
|
|
|
|
<para>and you should have a working linux emulator. Legend (and the
|
|
mail archives <!-- smiley -->:-) seems to hold that Linux emulation
|
|
works best with linux binaries linked against the ZMAGIC libraries;
|
|
QMAGIC libraries (such as those used in Slackware V2.0) may tend to
|
|
give the Linuxulator heartburn. Also, expect some programs to
|
|
complain about incorrect minor versions of the system libraries. In
|
|
general, however, this does not seem to be a problem.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Installing libraries manually</title>
|
|
|
|
<para>If you do not have the “ports” distribution, you can
|
|
install the libraries by hand instead. You will need the Linux
|
|
shared libraries that the program depends on and the runtime linker.
|
|
Also, you will need to create a "shadow root" directory,
|
|
<filename>/compat/linux</filename>, for Linux libraries on your
|
|
FreeBSD system. Any shared libraries opened by Linux programs run
|
|
under FreeBSD will look in this tree first. So, if a Linux program
|
|
loads, for example, <filename>/lib/libc.so</filename>, FreeBSD will
|
|
first try to open <filename>/compat/linux/lib/libc.so</filename>,
|
|
and if that does not exist then it will try
|
|
<filename>/lib/libc.so</filename>. Shared libraries should be
|
|
installed in the shadow tree <filename>/compat/linux/lib</filename>
|
|
rather than the paths that the Linux <command>ld.so</command>
|
|
reports.</para>
|
|
|
|
<para>FreeBSD-2.2-RELEASE and later works slightly differently with
|
|
respect to <filename>/compat/linux</filename>: all files, not just
|
|
libraries, are searched for from the “shadow root”
|
|
<filename>/compat/linux</filename>.</para>
|
|
|
|
<para>Generally, you will need to look for the shared libraries that
|
|
Linux binaries depend on only the first few times that you install
|
|
a Linux program on your FreeBSD system. After a while, you will
|
|
have a sufficient set of Linux shared libraries on your system to be
|
|
able to run newly imported Linux binaries without any extra
|
|
work.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>How to install additional shared libraries</title>
|
|
|
|
<para>What if you install the <filename>linux_lib</filename> port and
|
|
your application still complains about missing shared libraries? How
|
|
do you know which shared libraries Linux binaries need, and where to
|
|
get them? Basically, there are 2 possibilities (when following these
|
|
instructions: you will need to be root on your FreeBSD system to do
|
|
the necessary installation steps).</para>
|
|
|
|
<para>If you have access to a Linux system, see what shared libraries
|
|
the application needs, and copy them to your FreeBSD system.
|
|
Example: you have just ftp'ed the Linux binary of Doom. Put it on
|
|
the Linux system you have access to, and check which shared
|
|
libraries it needs by running <command>ldd
|
|
linuxxdoom</command>:</para>
|
|
|
|
<screen>&prompt.user; <userinput>ldd linuxxdoom</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>
|
|
|
|
<para>You would need to get all the files from the last column, and
|
|
put them under <filename>/compat/linux</filename>, with the names in
|
|
the first column as symbolic links pointing to them. This means you
|
|
eventually have these files on your FreeBSD system:</para>
|
|
|
|
<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>
|
|
|
|
<note>
|
|
<para>Note that if you already have a Linux shared library with a
|
|
matching major revision number to the first column of the
|
|
<command>ldd</command> output, you will not need to copy the file
|
|
named in the last column to your system, the one you already have
|
|
should work. It is advisable to copy the shared library anyway if
|
|
it is a newer version, though. You can remove the old one, as
|
|
long as you make the symbolic link point to the new one. So, if
|
|
you have these libraries on your system:</para>
|
|
|
|
<screen>/compat/linux/lib/libc.so.4.6.27
|
|
/compat/linux/lib/libc.so.4 -> libc.so.4.6.27</screen>
|
|
|
|
<para>and you find a new binary that claims to require a later
|
|
version according to the output of <command>ldd</command>:</para>
|
|
|
|
<screen>libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29</screen>
|
|
|
|
<para>If it is only one or two versions out of date in the in the
|
|
trailing digit then do not worry about copying
|
|
<filename>/lib/libc.so.4.6.29</filename> too, because the program
|
|
should work fine with the slightly older version. However, if you
|
|
like you can decide to replace the <filename>libc.so</filename>
|
|
anyway, and that should leave you with:</para>
|
|
|
|
<screen>/compat/linux/lib/libc.so.4.6.29
|
|
/compat/linux/lib/libc.so.4 -> libc.so.4.6.29</screen>
|
|
</note>
|
|
|
|
<note>
|
|
<para>The symbolic link mechanism is <emphasis>only</emphasis>
|
|
needed for Linux binaries. The FreeBSD runtime linker takes care
|
|
of looking for matching major revision numbers itself and you do
|
|
not need to worry about it.</para>
|
|
</note>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Configuring the <filename>ld.so</filename> — for FreeBSD
|
|
2.2-RELEASE and later</title>
|
|
|
|
<para>This section applies only to FreeBSD 2.2-RELEASE and later.
|
|
Those running 2.1-STABLE should skip this section.</para>
|
|
|
|
<para>Finally, if you run FreeBSD 2.2-RELEASE you must make sure that
|
|
you have the Linux runtime linker and its config files on your
|
|
system. You should copy these files from the Linux system to their
|
|
appropriate place on your FreeBSD system (to the
|
|
<filename>/compat/linux</filename> tree):</para>
|
|
|
|
<screen>/compat/linux/lib/ld.so
|
|
/compat/linux/etc/ld.so.config</screen>
|
|
|
|
<para>If you do not have access to a Linux system, you should get the
|
|
extra files you need from various ftp sites. Information on where
|
|
to look for the various files is appended below. For now, let us
|
|
assume you know where to get the files.</para>
|
|
|
|
<para>Retrieve the following files (all from the same ftp site to
|
|
avoid any version mismatches), and install them under
|
|
<filename>/compat/linux</filename> (i.e.
|
|
<filename>/foo/bar</filename> is installed as
|
|
<filename>/compat/linux/foo/bar</filename>):</para>
|
|
|
|
<screen>/sbin/ldconfig
|
|
/usr/bin/ldd
|
|
/lib/libc.so.x.y.z
|
|
/lib/ld.so</screen>
|
|
|
|
<para><command>ldconfig</command> and <command>ldd</command> do not
|
|
necessarily need to be under <filename>/compat/linux</filename>; you
|
|
can install them elsewhere in the system too. Just make sure they
|
|
do not conflict with their FreeBSD counterparts. A good idea would
|
|
be to install them in <filename>/usr/local/bin</filename> as
|
|
<command>ldconfig-linux</command> and
|
|
<command>ldd-linux</command>.</para>
|
|
|
|
<para>Create the file
|
|
<filename>/compat/linux/etc/ld.so.conf</filename>, containing the
|
|
directories in which the Linux runtime linker should look for shared
|
|
libs. It is a plain text file, containing a directory name on each
|
|
line. <filename>/lib</filename> and <filename>/usr/lib</filename>
|
|
are standard, you could add the following:</para>
|
|
|
|
<programlisting>
|
|
/usr/X11/lib
|
|
/usr/local/lib</programlisting>
|
|
|
|
<para>When a linux binary opens a library such as
|
|
<filename>/lib/libc.so</filename> the emulator maps the name to
|
|
<filename>/compat/linux/lib/libc.so</filename> internally. All
|
|
linux libraries should be installed under /compat/linux (e.g.
|
|
<filename>/compat/linux/lib/libc.so</filename>,
|
|
<filename>/compat/linux/usr/X11/lib/libX11.so</filename>, etc.) in
|
|
order for the emulator to find them.</para>
|
|
|
|
<para>Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig
|
|
program.</para>
|
|
|
|
<screen>&prompt.root <userinput>cd /compat/linux/lib</userinput>
|
|
&prompt.root; <userinput>/compat/linux/sbin/ldconfig</userinput></screen>
|
|
|
|
<para><command>ldconfig</command> is statically linked, so it does not
|
|
need any shared libraries to run. It creates the file
|
|
<filename>/compat/linux/etc/ld.so.cache</filename> which contains
|
|
the names of all the shared libraries and should be rerun to
|
|
recreate this file whenever you install additional shared
|
|
libraries.</para>
|
|
|
|
<para>On 2.1-STABLE do not install
|
|
<filename>/compat/linux/etc/ld.so.cache</filename> or run
|
|
<command>ldconfig</command>; in 2.1-STABLE the syscalls are
|
|
implemented differently and <command>ldconfig</command> is not
|
|
needed or used.</para>
|
|
|
|
<para>You should now be set up for Linux binaries which only need a
|
|
shared libc. You can test this by running the Linux
|
|
<command>ldd</command> on itself. Supposing that you have it
|
|
installed as <command>ldd-linux</command>, it should produce
|
|
something like:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ldd-linux `which ldd-linux`</userinput>
|
|
libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29</screen>
|
|
|
|
<para>This being done, you are ready to install new Linux binaries.
|
|
Whenever you install a new Linux program, you should check if it
|
|
needs shared libraries, and if so, whether you have them installed
|
|
in the <filename>/compat/linux</filename> tree. To do this, you run
|
|
the Linux version <command>ldd</command> on the new program, and
|
|
watch its output. <command>ldd</command> (see also the manual page
|
|
for &man.ldd.1;) will print a list of shared libraries
|
|
that the program depends on, in the form
|
|
<literal><replaceable>majorname</replaceable>
|
|
(<replaceable>jumpversion</replaceable>) =>
|
|
<replaceable>fullname</replaceable></literal>.</para>
|
|
|
|
<para>If it prints <literal>not found</literal> instead of
|
|
<replaceable>fullname</replaceable> it means that you need an extra
|
|
library. The library needed is shown in majorname and will be of
|
|
the form
|
|
<literal>lib<replaceable>XXXX</replaceable>.so.<replaceable>N</replaceable></literal>.
|
|
You will need to find a
|
|
<filename>lib<replaceable>XXXX</replaceable>.so.N.mm</filename> on a
|
|
Linux ftp site, and install it on your system. The
|
|
<replaceable>XXXX</replaceable> (name) and
|
|
<replaceable>N</replaceable> (major revision number) should match;
|
|
the minor number(s) <replaceable>mm</replaceable> are less
|
|
important, though it is advised to take the most recent
|
|
version.</para>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Installing Linux ELF binaries</title>
|
|
|
|
<para>ELF binaries sometimes require an extra step of
|
|
“branding”. If you attempt to run an unbranded ELF
|
|
binary, you will get an error message like the following;</para>
|
|
|
|
<screen>&prompt.user; <userinput>./my-linux-elf-binary</userinput>
|
|
ELF binary type not known
|
|
Abort</screen>
|
|
|
|
<para>To help the FreeBSD kernel distinguish between a FreeBSD ELF
|
|
binary from a Linux binary, use the &man.brandelf.1; utility.</para>
|
|
|
|
<screen>&prompt.user; <userinput>brandelf -t Linux my-linux-elf-binary</userinput></screen>
|
|
|
|
<para>The GNU toolchain now places the appropriate branding information
|
|
into ELF binaries automatically, so you should be needing to do this
|
|
step increasingly rarely in future.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Configuring the host name resolver</title>
|
|
|
|
<para>If DNS does not work or you get the messages
|
|
|
|
<screen>resolv+: "bind" is an invalid keyword resolv+:
|
|
"hosts" is an invalid keyword</screen>
|
|
|
|
then you need to configure a
|
|
<filename>/compat/linux/etc/host.conf</filename> file containing:
|
|
|
|
<programlisting>
|
|
order hosts, bind
|
|
multi on</programlisting>
|
|
|
|
where the order here specifies that <filename>/etc/hosts</filename> is
|
|
searched first and DNS is searched second. When
|
|
<filename>/compat/linux/etc/host.conf</filename> is not installed
|
|
linux applications find FreeBSD's <filename>/etc/host.conf</filename>
|
|
and complain about the incompatible FreeBSD syntax. You should remove
|
|
<literal>bind</literal> if you have not configured a name-server using
|
|
the <filename>/etc/resolv.conf</filename> file.</para>
|
|
|
|
<para>Lastly, those who run 2.1-STABLE need to set an the
|
|
<envar>RESOLV_HOST_CONF</envar> environment variable so that
|
|
applications will know how to search the host tables. If you run
|
|
FreeBSD 2.2-RELEASE or later, you can skip this. For the
|
|
<filename>/bin/csh</filename> shell use:</para>
|
|
|
|
<screen>&prompt.user; <userinput>setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf</userinput></screen>
|
|
|
|
<para>For <filename>/bin/sh</filename> use:</para>
|
|
|
|
<screen>&prompt.user; <userinput>RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF</userinput></screen>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Finding the necessary files</title>
|
|
|
|
<note>
|
|
<para>The information below is valid as of the time this document was
|
|
written, but certain details such as names of ftp sites, directories
|
|
and distribution names may have changed by the time you read
|
|
this.</para>
|
|
</note>
|
|
|
|
<para>Linux is distributed by several groups that make their own set of
|
|
binaries that they distribute. Each distribution has its own name,
|
|
like “Slackware” or “Yggdrasil”. The
|
|
distributions are available on a lot of ftp sites. Sometimes the
|
|
files are unpacked, and you can get the individual files you need, but
|
|
mostly they are stored in distribution sets, usually consisting of
|
|
subdirectories with gzipped tar files in them. The primary ftp sites
|
|
for the distributions are:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>sunsite.unc.edu:/pub/Linux/distributions</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>tsx-11.mit.edu:/pub/linux/distributions</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>Some European mirrors:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>ftp.luth.se:/pub/linux/distributions</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>ftp.demon.co.uk:/pub/unix/linux</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>src.doc.ic.ac.uk:/packages/linux/distributions</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>For simplicity, let us concentrate on Slackware here. This
|
|
distribution consists of a number of subdirectories, containing
|
|
separate packages. Normally, they are controlled by an install
|
|
program, but you can retrieve files “by hand” too. First
|
|
of all, you will need to look in the <filename>contents</filename>
|
|
subdir of the distribution. You will find a lot of small text files
|
|
here describing the contents of the separate packages. The fastest
|
|
way to look something up is to retrieve all the files in the contents
|
|
subdirectory, and grep through them for the file you need. Here is an
|
|
example of a list of files that you might need, and in which
|
|
contents-file you will find it by grepping through them:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Library</entry>
|
|
<entry>Package</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><filename>ld.so</filename></entry>
|
|
<entry>ldso</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>ldconfig</filename></entry>
|
|
<entry>ldso</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>ldd</filename></entry>
|
|
<entry>ldso</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>libc.so.4</filename></entry>
|
|
<entry>shlibs</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>libX11.so.6.0</filename></entry>
|
|
<entry>xf_lib</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>libXt.so.6.0</filename></entry>
|
|
<entry>xf_lib</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>libX11.so.3</filename></entry>
|
|
<entry>oldlibs</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>libXt.so.3</filename></entry>
|
|
<entry>oldlibs</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>So, in this case, you will need the packages ldso, shlibs, xf_lib
|
|
and oldlibs. In each of the contents-files for these packages, look
|
|
for a line saying <literal>PACKAGE LOCATION</literal>, it will tell
|
|
you on which “disk” the package is, in our case it will
|
|
tell us in which subdirectory we need to look. For our example, we
|
|
would find the following locations:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<thead
|
|
<row>
|
|
<entry>Package</entry>
|
|
<entry>Location</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>ldso</entry>
|
|
<entry>diska2</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>shlibs</entry>
|
|
<entry>diska2</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>oldlibs</entry>
|
|
<entry>diskx6</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>xf_lib</entry>
|
|
<entry>diskx9</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>The locations called
|
|
“disk<replaceable>XX</replaceable>” refer to the
|
|
<filename>slakware/<replaceable>XX</replaceable></filename>
|
|
subdirectories of the distribution, others may be found in the
|
|
<filename>contrib</filename> subdirectory. In this case, we could now
|
|
retrieve the packages we need by retrieving the following files
|
|
(relative to the root of the Slackware distribution tree):</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><filename>slakware/a2/ldso.tgz</filename></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><filename>slakware/a2/shlibs.tgz</filename></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><filename>slakware/x6/oldlibs.tgz</filename></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><filename>slakware/x9/xf_lib.tgz</filename></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Extract the files from these gzipped tarfiles in your
|
|
<filename>/compat/linux</filename> directory (possibly omitting or
|
|
afterwards removing files you do not need), and you are done.</para>
|
|
|
|
<para><emphasis>See also:</emphasis>
|
|
<filename>ftp://ftp.FreeBSD.org/pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README</filename> and <filename>/usr/src/sys/i386/ibcs2/README.iBCS2</filename></para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="mathematica">
|
|
<title>How to Install Mathematica on FreeBSD</title>
|
|
|
|
<para><emphasis>Contributed by &a.rich; and &a.chuck;</emphasis></para>
|
|
|
|
<para>This document shows how to install the Linux binary distribution of
|
|
Mathematica 2.2 on FreeBSD 2.1.</para>
|
|
|
|
<para>Mathematica supports Linux but not FreeBSD as it stands. So once
|
|
you have configured your system for Linux compatibility you have most of
|
|
what you need to run Mathematica.</para>
|
|
|
|
<para>For those who already have the student edition of Mathematica for
|
|
DOS the cost of upgrading to the Linux version at the time this was
|
|
written, March 1996, was $45.00. It can be ordered directly from
|
|
Wolfram at (217) 398-6500 and paid for by credit card.</para>
|
|
|
|
<sect2>
|
|
<title>Unpacking the Mathematica distribution</title>
|
|
|
|
<para>The binaries are currently distributed by Wolfram on CDROM. The
|
|
CDROM has about a dozen tar files, each of which is a binary
|
|
distribution for one of the supported architectures. The one for
|
|
Linux is named <filename>LINUX.TAR</filename>. You can, for example,
|
|
unpack this into <filename>/usr/local/Mathematica</filename>:</para>
|
|
|
|
<screen>&prompt.root; <userinput>cd /usr/local</userinput>
|
|
&prompt.root; <userinput>mkdir Mathematica</userinput>
|
|
&prompt.root; <userinput>cd Mathematica</userinput>
|
|
&prompt.root; <userinput>tar -xvf /cdrom/LINUX.TAR</userinput></screen>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Obtaining your Mathematica Password</title>
|
|
|
|
<para>Before you can run Mathematica you will have to obtain a password
|
|
from Wolfram that corresponds to your “machine ID”.</para>
|
|
|
|
<para>Once you have installed the linux compatibility runtime libraries
|
|
and unpacked the mathematica you can obtain the “machine
|
|
ID” by running the program <command>mathinfo</command> in the
|
|
Install directory.</para>
|
|
|
|
<screen>&prompt.root; <userinput>cd /usr/local/Mathematica/Install</userinput>
|
|
&prompt.root; <userinput>mathinfo</userinput>
|
|
LINUX: 'ioctl' fd=5, typ=0x89(), num=0x27 not implemented
|
|
richc.isdn.bcm.tmc.edu 9845-03452-90255</screen>
|
|
|
|
<para>So, for example, the “machine ID” of
|
|
<hostid>richc</hostid> is <literal>9845-03452-90255</literal>. You
|
|
can ignore the message about the ioctl that is not implemented. It
|
|
will not prevent Mathematica from running in any way and you can
|
|
safely ignore it, though you will see the message every time you run
|
|
Mathematica.</para>
|
|
|
|
<para>When you register with Wolfram, either by email, phone or fax, you
|
|
will give them the “machine ID” and they will respond with
|
|
a corresponding password consisting of groups of numbers. You need to
|
|
add them both along with the machine name and license number in your
|
|
mathpass file.</para>
|
|
|
|
<para>You can do this by invoking:</para>
|
|
|
|
<screen>&prompt.root; <userinput>cd /usr/local/Mathematica/Install</userinput>
|
|
&prompt.root; <userinput>math.install</userinput></screen>
|
|
|
|
<para>It will ask you to enter your license number and the Wolfram
|
|
supplied password. If you get them mixed up or for some reason the
|
|
math.install fails, that is OK; you can simply edit the file
|
|
<filename>mathpass</filename> in this same directory to correct the
|
|
info manually.</para>
|
|
|
|
<para>After getting past the password, math.install will ask you if you
|
|
accept the install defaults provided, or if you want to use your own.
|
|
If you are like us and distrust all install programs, you probably
|
|
want to specify the actual directories. Beware. Although the
|
|
math.install program asks you to specify directories, it will not
|
|
create them for you, so you should perhaps have a second window open
|
|
with another shell so that you can create them before you give them to
|
|
the install program. Or, if it fails, you can create the directories
|
|
and then restart the <command>math.install</command> program. The
|
|
directories we chose to create beforehand and specify to
|
|
<command>math.install</command> were:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<tbody>
|
|
<row>
|
|
<entry><filename>/usr/local/Mathematica/bin</filename></entry>
|
|
<entry>for binaries</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><filename>/usr/local/Mathematica/man/man1</filename></entry>
|
|
<entry>for man pages</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>/usr/local/Mathematica/lib/X11</entry>
|
|
<entry>for the XKeysymb file</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>You can also tell it to use <filename>/tmp/math.record</filename>
|
|
for the system record file, where it puts logs of sessions. After
|
|
this <command>math.install</command> will continue on to unpacking
|
|
things and placing everything where it should go.</para>
|
|
|
|
<para>The Mathematica Notebook feature is included separately, as the X
|
|
Front End, and you have to install it separately. To get the X Front
|
|
End stuff correctly installed, cd into the
|
|
<filename>/usr/local/Mathematica/FrontEnd</filename> directory and
|
|
execute the <command>xfe.install</command> shell script. You will
|
|
have to tell it where to put things, but you do not have to create any
|
|
directories because it will use the same directories that had been
|
|
created for math.install. When it finishes, there should be a new
|
|
shell script in <filename>/usr/local/Mathematica/bin</filename> called
|
|
<filename>mathematica</filename>.</para>
|
|
|
|
<para>Lastly, you need to modify each of the shell scripts that
|
|
Mathematica has installed. At the beginning of every shell script in
|
|
<filename>/usr/local/Mathematica/bin</filename> add the following
|
|
line:</para>
|
|
|
|
<screen>&prompt.user; <userinput>XKEYSYMDB=/usr/local/Mathematica/lib/X11/XKeysymDB; export XKEYSYMDB</userinput></screen>
|
|
|
|
<para>This tells Mathematica were to find its own
|
|
version of the key mapping file <filename>XKeysymDB</filename>.
|
|
Without this you will get pages of error messages about missing
|
|
key mappings.</para>
|
|
|
|
<para>On 2.1-STABLE you need to add the following as well:</para>
|
|
|
|
<screen>&prompt.user; <userinput>RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF</userinput></screen>
|
|
|
|
<para>This tells Mathematica to use the linux version of host.conf.
|
|
This file has a different syntax from FreeBSD's host.conf, so you will
|
|
get an error message about <filename>/etc/host.conf</filename> if you
|
|
leave this out.</para>
|
|
|
|
<para>You might also want to modify your
|
|
<filename>/etc/manpath.config</filename> file to read the new man
|
|
directory, and you may need to edit your <filename>~/.cshrc</filename>
|
|
file to add <filename>/usr/local/Mathematica/bin</filename> to your
|
|
path.</para>
|
|
|
|
<para>That is about all it takes. With this you should be able to type
|
|
<command>mathematica</command> and get a really slick looking
|
|
Mathematica Notebook screen up. Mathematica has included the Motif
|
|
user interfaces, but it is compiled in statically, so you do not need
|
|
the Motif libraries. Good luck doing this yourself!</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Bugs</title>
|
|
|
|
<para>The Notebook front end is known to hang sometimes when reading
|
|
notebook files with an error messages similar to:</para>
|
|
|
|
<screen><errorname>File .../Untitled-1.mb appears to be broken for OMPR.257.0</errorname></screen>
|
|
|
|
<para>We have not found the cause for this, but it only affects the
|
|
Notebook's X Window front end, not the mathematica engine itself. So
|
|
the command line interface invoked by 'math' is unaffected by this
|
|
bug.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Acknowledgments</title>
|
|
|
|
<para>A well-deserved thanks should go to &a.sos; and &a.peter; who made
|
|
linux emulation what it is today, and Michael Smith who drove these
|
|
two guys like dogs to get it to the point where it runs Linux binaries
|
|
better than linux! <!-- smiley -->:-)</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>How does the emulation work?</title>
|
|
|
|
<para>This section is based heavily on an e-mail written to the
|
|
<email>chat@FreeBSD.org</email> mailing list, written by Terry Lambert
|
|
<email>tlambert@primenet.com</email> (Message ID:
|
|
<literal><199906020108.SAA07001@usr09.primenet.com></literal>).</para>
|
|
|
|
<para>FreeBSD has an abstraction called an “execution class
|
|
loader”. This is a wedge into the &man.execve.2; system
|
|
call.</para>
|
|
|
|
<para>What happens is that FreeBSD has a list of loaders, instead of a
|
|
single loader with a failback to the <literal>#!</literal> loader for
|
|
running any shell interpreters or shell scripts.</para>
|
|
|
|
<para>Historically, the only loader on the UNIX platform examined the
|
|
magic number (generally the first 4 or 8 bytes of the file) to see if it
|
|
was a binary known to the system, and if so, invoked the binary
|
|
loader.</para>
|
|
|
|
<para>If it was not the binary type for the system, the &man.execve.2;
|
|
call returned a failure, and the shell attempted to start executing it
|
|
as shell commands.</para>
|
|
|
|
<para>The assumption was a default of “whatever the current shell
|
|
is”.</para>
|
|
|
|
<para>Later, a hack was made for &man.sh.1; to examine the first two
|
|
characters, and if they were <literal>:\n</literal>, then it invoked the
|
|
&man.csh.1; shell instead (I believe SCO first made this hack, but am
|
|
willing to be corrected).</para>
|
|
|
|
<para>What FreeBSD does now is go through a list of loaders, with a
|
|
generic <literal>#!</literal> loader that knows about interpreters as
|
|
the characters which follow to the next whitespace next to last,
|
|
followed by a fallback to <filename>/bin/sh</filename>.</para>
|
|
|
|
<para>For the Linux binary emulation, FreeBSD sees the magic number as an
|
|
ELF binary (it makes no distinction between FreeBSD, Solaris, Linux, or
|
|
any other OS which has an ELF image tpye, at this point).</para>
|
|
|
|
<para>The ELF loader looks for a specialized <emphasis>brand</emphasis>,
|
|
which is a comment section in the ELF image, and which is not present on
|
|
SVR4/Solaris ELF binaries.</para>
|
|
|
|
<para>For Linux binaries to function, they must be
|
|
<emphasis>branded</emphasis> as type <literal>Linux</literal>; from
|
|
&man.brandelf.1;:</para>
|
|
|
|
<screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen>
|
|
|
|
<para>When this is done, the ELF loader will see the
|
|
<literal>Linux</literal> brand on the file.</para>
|
|
|
|
<para>When the ELF loader sees the <literal>Linux</literal> brand, the
|
|
loader replaces a pointer in the <literal>proc</literal>
|
|
structure. All system calls are indexed through this pointer (in a
|
|
traditional UNIX system, this would be the <literal>sysent[]</literal> structure array, containing the system
|
|
calls). In addition, the process is flagged for special handling of the
|
|
trap vector for the signal trampoline code, and sever other (minor)
|
|
fixups that are handled by the Linux kernel module.</para>
|
|
|
|
<para>The Linux system call vector contains, among other things, a list of
|
|
<literal>sysent[]</literal> entries whose addresses reside in the kernel
|
|
module.</para>
|
|
|
|
<para>When a system call is called by the Linux binary, the trap code
|
|
dereferences the system call function pointer off the
|
|
<literal>proc</literal> structure, and gets the Linux, not the FreeBSD,
|
|
system call entry points.</para>
|
|
|
|
<para>In addition, the Linux emulation dynamically
|
|
<emphasis>reroots</emphasis> lookups; this is, in effect, what the
|
|
<literal>union</literal> option to FS mounts ( <emphasis>not</emphasis>
|
|
the unionfs!) does. First, an attempt is made to lookup the file in the
|
|
<filename>/compat/linux/<replaceable>original-path</replaceable></filename>
|
|
directory, <emphasis>then</emphasis> only if that fails, the lookup is
|
|
done in the
|
|
<filename>/<replaceable>original-path</replaceable></filename>
|
|
directory. This makes sure that binaries that require other binaries
|
|
can run (e.g., the Linux toolchain can all run under emulation). It
|
|
also means that the Linux binaries can load and exec FreeBSD binaries,
|
|
if there are no corresponding Linux binaries present, and that you could
|
|
place a &man.uname.1; command in the <filename>/compat/linux</filename>
|
|
directory tree to ensure that the Linux binaries could not tell they
|
|
were not running on Linux.</para>
|
|
|
|
<para>In effect, there is a Linux kernel in the FreeBSD kernel; the
|
|
various underlying functions that implement all of the services provided
|
|
by the kernel are identical to both the FreeBSD system call table
|
|
entries, and the Linux system call table entries: file system
|
|
operations, virtual memory operations, signal delivery, System V IPC,
|
|
etc… The only difference is that FreeBSD binaries get the FreeBSD
|
|
<emphasis>glue</emphasis> functions, and Linux binaries get the Linux
|
|
<emphasis>glue</emphasis> functions (most older OS's only had their own
|
|
<emphasis>glue</emphasis> functions: addresses of functions in a static
|
|
global <literal>sysent[]</literal> structure array, instead of addresses
|
|
of functions dereferenced off a dynamically initialized pointer in the
|
|
<literal>proc</literal> structure of the process making the
|
|
call).</para>
|
|
|
|
<para>Which one is the native FreeBSD ABI? It does not matter. Basically
|
|
the only difference is that (currently; this could easily be changed in
|
|
a future release, and probably will be after this) the FreeBSD
|
|
<emphasis>glue</emphasis> functions are statically linked into the
|
|
kernel, and the Linux glue functions can be statically linked, or they
|
|
can be accessed via a kernel module.</para>
|
|
|
|
<para>Yeah, but is this really emulation? No. It is an ABI
|
|
implementation, not an emulation. There is no emulator (or simulator,
|
|
to cut off the next question) involved.</para>
|
|
|
|
<para>So why is it called “Linux emulation”? To make it hard
|
|
to sell FreeBSD! <!-- smiley -->8-). Really, it is because the
|
|
historical implementation was done at a time when there was really no
|
|
word other than that to describe what was going on; saying that FreeBSD
|
|
ran Linux binaries was not true, if you did not compile the code in or
|
|
load a module, and there needed to be a word to describe what was being
|
|
loaded—hence “the Linux emulator”.</para>
|
|
</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: ("../handbook.sgml" "part" "chapter")
|
|
End:
|
|
-->
|
|
|