diff --git a/en_US.ISO8859-1/books/handbook/linuxemu/chapter.sgml b/en_US.ISO8859-1/books/handbook/linuxemu/chapter.sgml index f1e37175af..61a3ed1159 100644 --- a/en_US.ISO8859-1/books/handbook/linuxemu/chapter.sgml +++ b/en_US.ISO8859-1/books/handbook/linuxemu/chapter.sgml @@ -1,997 +1,996 @@ Linux Mode Contributed by &a.handy; and &a.rich; How to Install the Linux Mode Linux binary compatibility 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 compatibility 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 Oracle8, - WordPerfect, StarOffice, Acrobat, Quake, Abuse, IDL, + WordPerfect, StarOffice, Acrobat, Quake, Abuse, IDL, and netrek for Linux and a whole host of other programs. There are some Linux-specific operating system features that are not supported on FreeBSD. Linux binaries will not work on FreeBSD if they overly use the Linux /proc filesystem (which is different from the optional FreeBSD /proc filesystem) or i386-specific calls, such as enabling virtual 8086 mode. Depending on which version of FreeBSD you are running, how you get - Linux-mode up will vary somewhat: + Linux mode up will vary somewhat: Installing Linux Mode in 3.0-RELEASE and later It is no longer necessary to specify options LINUX or options COMPAT_LINUX. Linux binary compatibility is done with an KLD object (“Kernel LoaDable object”) so it can be installed on the fly without having to reboot. You will need the following things in your startup files, however: In /etc/rc.conf, you need the following line: linux_enable=YES This, in turn, triggers the following action in /etc/rc.i386: # Start the Linux binary compatibility if requested. if [ "X${linux_enable}" = X"YES" ]; then echo -n ' linux'; linux > /dev/null 2>&1 fi - If you want to verify that the KLD is loaded, kldstat will do that: + If you want to verify that the KLD is loaded, kldstat will do that: &prompt.user; kldstat Id Refs Address Size Name 1 2 0xc0100000 16bdb8 kernel 7 1 0xc24db000 d000 linux.ko If for some reason you do not want to or cannot load the Linux KLD, then statically link the binary compatibility in the kernel by adding options LINUX - to your kernel config file. Then run config and install the new + to your kernel config file. Then run config and install the new kernel as described in the kernel configuration section. Installing Linux Mode in 2.2.2-RELEASE and later 2.2.x versions It is no longer necessary to specify options LINUX or options COMPAT_LINUX. Linux binary compatibility 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: In /etc/rc.conf, you need the following line: linux_enable=YES This, in turn, triggers the following action in /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 - If you want to verify that the LKM is running, modstat will do that: + If you want to verify that the LKM is running, modstat will do that: &prompt.user; modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 4 f09e6000 001c f09ec010 1 linux_mod 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 Linux compatibility in the kernel by adding options LINUX - to your kernel config file. Then run config and install the new + to your kernel config file. Then run config and install the new kernel as described in the kernel configuration section. Installing Linux Mode in 2.1-STABLE The GENERIC 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 binary compatibility statically in the kernel itself and 2. configuring your kernel to dynamically load the Linux loadable kernel module (LKM). To enable Linux binary compatibility, add the following to your configuration file (c.f. /sys/i386/conf/LINT): options COMPAT_LINUX If you want to run doom or other applications that need shared memory, also add the following. options SYSVSHM The Linux system calls require 4.3BSD system call compatibility. So make sure you have the following. options "COMPAT_43" If you prefer to statically link the binary compatibility in the kernel rather than use the loadable kernel module (LKM), then add options LINUX Then run config and install the new kernel as described in the kernel configuration section. 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. &prompt.root; cd /usr/src/lkm/linux &prompt.root; make all install Once you have installed the kernel and the LKM, you can invoke linux as root to load the LKM. &prompt.root; linux Linux emulator installed Module loaded as ID 0 To see whether the LKM is loaded, run modstat. &prompt.user; modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 3 f0baf000 0018 f0bb4000 1 linux_emulator 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 /etc/sysconfig linux=YES - by changing it from NO to YES. FreeBSD 2.1 RELEASE and earlier do not + 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 /etc/rc.local to add the following line. linux Installing Linux Runtime Libraries Installing using the linux_base port 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_base port: &prompt.root; cd /usr/ports/emulators/linux_base &prompt.root; make all install and you should have working Linux binary compatibility. Legend (and the mail archives :-) seems to hold that Linux mode 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 Linux mode 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. Installing libraries manually 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, /compat/linux, 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, /lib/libc.so, FreeBSD will first try to open /compat/linux/lib/libc.so, and if that does not exist then it will try /lib/libc.so. Shared libraries should be installed in the shadow tree /compat/linux/lib rather than the paths that the Linux ld.so reports. FreeBSD-2.2-RELEASE and later works slightly differently with respect to /compat/linux: all files, not just libraries, are searched for from the “shadow root” /compat/linux. 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. How to install additional shared libraries What if you install the linux_base 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). 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 ldd linuxxdoom: &prompt.user; 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 You would need to get all the files from the last column, and put them under /compat/linux, with the names in the first column as symbolic links pointing to them. This means you eventually have these files on your FreeBSD system: /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 that if you already have a Linux shared library with a matching major revision number to the first column of the ldd 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: /compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27 and you find a new binary that claims to require a later version according to the output of ldd: libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29 If it is only one or two versions out of date in the in the trailing digit then do not worry about copying /lib/libc.so.4.6.29 too, because the program should work fine with the slightly older version. However, if you like you can decide to replace the libc.so anyway, and that should leave you with: /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29 The symbolic link mechanism is only 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. Configuring the <filename>ld.so</filename> — for FreeBSD 2.2-RELEASE and later This section applies only to FreeBSD 2.2-RELEASE and later. Those running 2.1-STABLE should skip this section. 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 /compat/linux tree): /compat/linux/lib/ld.so /compat/linux/etc/ld.so.config 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. Retrieve the following files (all from the same ftp site to avoid any version mismatches), and install them under /compat/linux (i.e. /foo/bar is installed as /compat/linux/foo/bar): /sbin/ldconfig /usr/bin/ldd /lib/libc.so.x.y.z /lib/ld.so ldconfig and ldd do not necessarily need to be under /compat/linux; 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 /usr/local/bin as ldconfig-linux and ldd-linux. Create the file /compat/linux/etc/ld.so.conf, containing the directories in which the Linux runtime linker should look for shared libraries. It is a plain text file, containing a directory name on each line. /lib and /usr/lib are standard, you could add the following: /usr/X11/lib /usr/local/lib When a Linux binary opens a library such as /lib/libc.so the Linux ABI support maps the name to /compat/linux/lib/libc.so internally. All Linux libraries should be installed under /compat/linux (e.g. /compat/linux/lib/libc.so, /compat/linux/usr/X11/lib/libX11.so, etc.) in order for the Linux ABI loader to find them. - Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig + Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig program. &prompt.root cd /compat/linux/lib &prompt.root; /compat/linux/sbin/ldconfig ldconfig is statically linked, so it does not need any shared libraries to run. It creates the file /compat/linux/etc/ld.so.cache which contains the names of all the shared libraries and should be rerun to recreate this file whenever you install additional shared libraries. On 2.1-STABLE do not install /compat/linux/etc/ld.so.cache or run ldconfig; in 2.1-STABLE the syscalls are implemented differently and ldconfig is not needed or used. You should now be set up for Linux binaries which only need a shared libc. You can test this by running the Linux ldd on itself. Supposing that you have it installed as ldd-linux, it should produce something like: &prompt.root; ldd-linux `which ldd-linux` libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29 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 /compat/linux tree. To do this, you run the Linux version ldd on the new program, and watch its output. ldd (see also the manual page for &man.ldd.1;) will print a list of shared libraries that the program depends on, in the form majorname (jumpversion) => fullname. If it prints not found instead of fullname it means that you need an extra library. The library needed is shown in majorname and will be of the form libXXXX.so.N. You will need to find a libXXXX.so.N.mm on a Linux ftp site, and install it on your system. The XXXX (name) and N (major revision number) should match; the minor number(s) mm are less important, though it is advised to take the most recent version. Installing Linux ELF binaries 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; &prompt.user; ./my-linux-elf-binary ELF binary type not known Abort To help the FreeBSD kernel distinguish between a FreeBSD ELF binary from a Linux binary, use the &man.brandelf.1; utility. &prompt.user; brandelf -t Linux my-linux-elf-binary 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. Configuring the host name resolver If DNS does not work or you get the messages resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword then you need to configure a /compat/linux/etc/host.conf file containing: order hosts, bind multi on where the order here specifies that /etc/hosts is searched first and DNS is searched second. When /compat/linux/etc/host.conf is not installed linux applications find FreeBSD's /etc/host.conf and complain about the incompatible FreeBSD syntax. You should remove bind if you have not configured a name-server using the /etc/resolv.conf file. Lastly, those who run 2.1-STABLE need to set an the RESOLV_HOST_CONF 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 /bin/csh shell use: &prompt.user; setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf For /bin/sh use: &prompt.user; RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF Finding the necessary files 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. 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: sunsite.unc.edu:/pub/Linux/distributions tsx-11.mit.edu:/pub/linux/distributions Some European mirrors: ftp.luth.se:/pub/linux/distributions ftp.demon.co.uk:/pub/unix/linux src.doc.ic.ac.uk:/packages/linux/distributions 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 contents subdirectory 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: 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 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 PACKAGE LOCATION, 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: Package Location ldso diska2 shlibs diska2 oldlibs diskx6 xf_lib diskx9 The locations called “diskXX” refer to the slakware/XX subdirectories of the distribution, others may be found in the contrib 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): slakware/a2/ldso.tgz slakware/a2/shlibs.tgz slakware/x6/oldlibs.tgz slakware/x9/xf_lib.tgz Extract the files from these gzipped tarfiles in your /compat/linux directory (possibly omitting or afterwards removing files you do not need), and you are done. See also: ftp://ftp.FreeBSD.org/pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README and /usr/src/sys/i386/ibcs2/README.iBCS2 How to Install Mathematica on FreeBSD Contributed by &a.rich; and &a.chuck; This document shows how to install the Linux binary distribution of Mathematica 2.2 on FreeBSD 2.1. 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. 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. Unpacking the Mathematica distribution 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 LINUX.TAR. You can, for example, unpack this into /usr/local/Mathematica: &prompt.root; cd /usr/local &prompt.root; mkdir Mathematica &prompt.root; cd Mathematica &prompt.root; tar -xvf /cdrom/LINUX.TAR Obtaining your Mathematica Password Before you can run Mathematica you will have to obtain a password from Wolfram that corresponds to your “machine ID”. Once you have installed the Linux compatibility runtime libraries and unpacked Mathematica you can obtain the “machine ID” by running the program mathinfo in the Install directory. &prompt.root; cd /usr/local/Mathematica/Install &prompt.root; mathinfo LINUX: 'ioctl' fd=5, typ=0x89(), num=0x27 not implemented richc.isdn.bcm.tmc.edu 9845-03452-90255 So, for example, the “machine ID” of richc is 9845-03452-90255. 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. 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. You can do this by invoking: &prompt.root; cd /usr/local/Mathematica/Install &prompt.root; math.install 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 + math.install fails, that is OK; you can simply edit the file mathpass in this same directory to correct the info manually. - After getting past the password, math.install will ask you if you + 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 + 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 math.install program. The directories we chose to create beforehand and specify to math.install were: /usr/local/Mathematica/bin for binaries /usr/local/Mathematica/man/man1 for man pages /usr/local/Mathematica/lib/X11 for the XKeysymb file You can also tell it to use /tmp/math.record for the system record file, where it puts logs of sessions. After this math.install will continue on to unpacking things and placing everything where it should go. 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 /usr/local/Mathematica/FrontEnd directory and execute the xfe.install 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 + created for math.install. When it finishes, there should be a new shell script in /usr/local/Mathematica/bin called mathematica. Lastly, you need to modify each of the shell scripts that Mathematica has installed. At the beginning of every shell script in /usr/local/Mathematica/bin add the following line: &prompt.user; XKEYSYMDB=/usr/local/Mathematica/lib/X11/XKeysymDB; export XKEYSYMDB This tells Mathematica were to find its own version of the key mapping file XKeysymDB. Without this you will get pages of error messages about missing key mappings. On 2.1-STABLE you need to add the following as well: &prompt.user; RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF - 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 + 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 /etc/host.conf if you leave this out. You might also want to modify your /etc/manpath.config file to read the new man directory, and you may need to edit your ~/.cshrc file to add /usr/local/Mathematica/bin to your path. That is about all it takes. With this you should be able to type mathematica 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! Bugs The Notebook front end is known to hang sometimes when reading notebook files with an error messages similar to: File .../Untitled-1.mb appears to be broken for OMPR.257.0 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 + the command line interface invoked by math is unaffected by this bug. Acknowledgments A well-deserved thanks should go to &a.sos; and &a.peter; who made Linux mode 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! :-) How does the Linux mode work? This section is based heavily on an e-mail written to the chat@FreeBSD.org mailing list, written by Terry Lambert tlambert@primenet.com (Message ID: <199906020108.SAA07001@usr09.primenet.com>). FreeBSD has an abstraction called an “execution class loader”. This is a wedge into the &man.execve.2; system call. What happens is that FreeBSD has a list of loaders, instead of a single loader with a fallback to the #! loader for running any shell interpreters or shell scripts. 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. 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. The assumption was a default of “whatever the current shell is”. Later, a hack was made for &man.sh.1; to examine the first two characters, and if they were :\n, then it invoked the - &man.csh.1; shell instead (I believe SCO first made this hack, but am - willing to be corrected). + &man.csh.1; shell instead (we believe SCO first made this hack). What FreeBSD does now is go through a list of loaders, with a generic #! loader that knows about interpreters as the characters which follow to the next whitespace next to last, followed by a fallback to /bin/sh. For the Linux ABI support, 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 type, at this point). The ELF loader looks for a specialized brand, which is a comment section in the ELF image, and which is not present on SVR4/Solaris ELF binaries. For Linux binaries to function, they must be branded as type Linux; from &man.brandelf.1;: &prompt.root; brandelf -t Linux file When this is done, the ELF loader will see the Linux brand on the file. When the ELF loader sees the Linux brand, the loader replaces a pointer in the proc structure. All system calls are indexed through this pointer (in a traditional UNIX system, this would be the sysent[] 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) fix-ups that are handled by the Linux kernel module. The Linux system call vector contains, among other things, a list of sysent[] entries whose addresses reside in the kernel module. When a system call is called by the Linux binary, the trap code dereferences the system call function pointer off the proc structure, and gets the Linux, not the FreeBSD, system call entry points. In addition, the Linux mode dynamically reroots lookups; this is, in effect, what the union option to FS mounts ( not the unionfs!) does. First, an attempt is made to lookup the file in the /compat/linux/original-path directory, then only if that fails, the lookup is done in the /original-path directory. This makes sure that binaries that require other binaries can run (e.g., the Linux toolchain can all run under Linux ABI support). 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 /compat/linux directory tree to ensure that the Linux binaries could not tell they were not running on Linux. 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 glue functions, and Linux binaries get the Linux glue functions (most older OS's only had their own glue functions: addresses of functions in a static global sysent[] structure array, instead of addresses of functions dereferenced off a dynamically initialized pointer in the proc structure of the process making the call). 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 glue 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. 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. So why is it sometimes called “Linux emulation”? To make it hard to sell FreeBSD! 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”. diff --git a/en_US.ISO_8859-1/books/handbook/linuxemu/chapter.sgml b/en_US.ISO_8859-1/books/handbook/linuxemu/chapter.sgml index f1e37175af..61a3ed1159 100644 --- a/en_US.ISO_8859-1/books/handbook/linuxemu/chapter.sgml +++ b/en_US.ISO_8859-1/books/handbook/linuxemu/chapter.sgml @@ -1,997 +1,996 @@ Linux Mode Contributed by &a.handy; and &a.rich; How to Install the Linux Mode Linux binary compatibility 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 compatibility 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 Oracle8, - WordPerfect, StarOffice, Acrobat, Quake, Abuse, IDL, + WordPerfect, StarOffice, Acrobat, Quake, Abuse, IDL, and netrek for Linux and a whole host of other programs. There are some Linux-specific operating system features that are not supported on FreeBSD. Linux binaries will not work on FreeBSD if they overly use the Linux /proc filesystem (which is different from the optional FreeBSD /proc filesystem) or i386-specific calls, such as enabling virtual 8086 mode. Depending on which version of FreeBSD you are running, how you get - Linux-mode up will vary somewhat: + Linux mode up will vary somewhat: Installing Linux Mode in 3.0-RELEASE and later It is no longer necessary to specify options LINUX or options COMPAT_LINUX. Linux binary compatibility is done with an KLD object (“Kernel LoaDable object”) so it can be installed on the fly without having to reboot. You will need the following things in your startup files, however: In /etc/rc.conf, you need the following line: linux_enable=YES This, in turn, triggers the following action in /etc/rc.i386: # Start the Linux binary compatibility if requested. if [ "X${linux_enable}" = X"YES" ]; then echo -n ' linux'; linux > /dev/null 2>&1 fi - If you want to verify that the KLD is loaded, kldstat will do that: + If you want to verify that the KLD is loaded, kldstat will do that: &prompt.user; kldstat Id Refs Address Size Name 1 2 0xc0100000 16bdb8 kernel 7 1 0xc24db000 d000 linux.ko If for some reason you do not want to or cannot load the Linux KLD, then statically link the binary compatibility in the kernel by adding options LINUX - to your kernel config file. Then run config and install the new + to your kernel config file. Then run config and install the new kernel as described in the kernel configuration section. Installing Linux Mode in 2.2.2-RELEASE and later 2.2.x versions It is no longer necessary to specify options LINUX or options COMPAT_LINUX. Linux binary compatibility 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: In /etc/rc.conf, you need the following line: linux_enable=YES This, in turn, triggers the following action in /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 - If you want to verify that the LKM is running, modstat will do that: + If you want to verify that the LKM is running, modstat will do that: &prompt.user; modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 4 f09e6000 001c f09ec010 1 linux_mod 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 Linux compatibility in the kernel by adding options LINUX - to your kernel config file. Then run config and install the new + to your kernel config file. Then run config and install the new kernel as described in the kernel configuration section. Installing Linux Mode in 2.1-STABLE The GENERIC 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 binary compatibility statically in the kernel itself and 2. configuring your kernel to dynamically load the Linux loadable kernel module (LKM). To enable Linux binary compatibility, add the following to your configuration file (c.f. /sys/i386/conf/LINT): options COMPAT_LINUX If you want to run doom or other applications that need shared memory, also add the following. options SYSVSHM The Linux system calls require 4.3BSD system call compatibility. So make sure you have the following. options "COMPAT_43" If you prefer to statically link the binary compatibility in the kernel rather than use the loadable kernel module (LKM), then add options LINUX Then run config and install the new kernel as described in the kernel configuration section. 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. &prompt.root; cd /usr/src/lkm/linux &prompt.root; make all install Once you have installed the kernel and the LKM, you can invoke linux as root to load the LKM. &prompt.root; linux Linux emulator installed Module loaded as ID 0 To see whether the LKM is loaded, run modstat. &prompt.user; modstat Type Id Off Loadaddr Size Info Rev Module Name EXEC 0 3 f0baf000 0018 f0bb4000 1 linux_emulator 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 /etc/sysconfig linux=YES - by changing it from NO to YES. FreeBSD 2.1 RELEASE and earlier do not + 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 /etc/rc.local to add the following line. linux Installing Linux Runtime Libraries Installing using the linux_base port 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_base port: &prompt.root; cd /usr/ports/emulators/linux_base &prompt.root; make all install and you should have working Linux binary compatibility. Legend (and the mail archives :-) seems to hold that Linux mode 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 Linux mode 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. Installing libraries manually 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, /compat/linux, 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, /lib/libc.so, FreeBSD will first try to open /compat/linux/lib/libc.so, and if that does not exist then it will try /lib/libc.so. Shared libraries should be installed in the shadow tree /compat/linux/lib rather than the paths that the Linux ld.so reports. FreeBSD-2.2-RELEASE and later works slightly differently with respect to /compat/linux: all files, not just libraries, are searched for from the “shadow root” /compat/linux. 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. How to install additional shared libraries What if you install the linux_base 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). 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 ldd linuxxdoom: &prompt.user; 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 You would need to get all the files from the last column, and put them under /compat/linux, with the names in the first column as symbolic links pointing to them. This means you eventually have these files on your FreeBSD system: /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 that if you already have a Linux shared library with a matching major revision number to the first column of the ldd 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: /compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27 and you find a new binary that claims to require a later version according to the output of ldd: libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29 If it is only one or two versions out of date in the in the trailing digit then do not worry about copying /lib/libc.so.4.6.29 too, because the program should work fine with the slightly older version. However, if you like you can decide to replace the libc.so anyway, and that should leave you with: /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29 The symbolic link mechanism is only 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. Configuring the <filename>ld.so</filename> — for FreeBSD 2.2-RELEASE and later This section applies only to FreeBSD 2.2-RELEASE and later. Those running 2.1-STABLE should skip this section. 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 /compat/linux tree): /compat/linux/lib/ld.so /compat/linux/etc/ld.so.config 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. Retrieve the following files (all from the same ftp site to avoid any version mismatches), and install them under /compat/linux (i.e. /foo/bar is installed as /compat/linux/foo/bar): /sbin/ldconfig /usr/bin/ldd /lib/libc.so.x.y.z /lib/ld.so ldconfig and ldd do not necessarily need to be under /compat/linux; 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 /usr/local/bin as ldconfig-linux and ldd-linux. Create the file /compat/linux/etc/ld.so.conf, containing the directories in which the Linux runtime linker should look for shared libraries. It is a plain text file, containing a directory name on each line. /lib and /usr/lib are standard, you could add the following: /usr/X11/lib /usr/local/lib When a Linux binary opens a library such as /lib/libc.so the Linux ABI support maps the name to /compat/linux/lib/libc.so internally. All Linux libraries should be installed under /compat/linux (e.g. /compat/linux/lib/libc.so, /compat/linux/usr/X11/lib/libX11.so, etc.) in order for the Linux ABI loader to find them. - Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig + Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig program. &prompt.root cd /compat/linux/lib &prompt.root; /compat/linux/sbin/ldconfig ldconfig is statically linked, so it does not need any shared libraries to run. It creates the file /compat/linux/etc/ld.so.cache which contains the names of all the shared libraries and should be rerun to recreate this file whenever you install additional shared libraries. On 2.1-STABLE do not install /compat/linux/etc/ld.so.cache or run ldconfig; in 2.1-STABLE the syscalls are implemented differently and ldconfig is not needed or used. You should now be set up for Linux binaries which only need a shared libc. You can test this by running the Linux ldd on itself. Supposing that you have it installed as ldd-linux, it should produce something like: &prompt.root; ldd-linux `which ldd-linux` libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29 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 /compat/linux tree. To do this, you run the Linux version ldd on the new program, and watch its output. ldd (see also the manual page for &man.ldd.1;) will print a list of shared libraries that the program depends on, in the form majorname (jumpversion) => fullname. If it prints not found instead of fullname it means that you need an extra library. The library needed is shown in majorname and will be of the form libXXXX.so.N. You will need to find a libXXXX.so.N.mm on a Linux ftp site, and install it on your system. The XXXX (name) and N (major revision number) should match; the minor number(s) mm are less important, though it is advised to take the most recent version. Installing Linux ELF binaries 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; &prompt.user; ./my-linux-elf-binary ELF binary type not known Abort To help the FreeBSD kernel distinguish between a FreeBSD ELF binary from a Linux binary, use the &man.brandelf.1; utility. &prompt.user; brandelf -t Linux my-linux-elf-binary 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. Configuring the host name resolver If DNS does not work or you get the messages resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword then you need to configure a /compat/linux/etc/host.conf file containing: order hosts, bind multi on where the order here specifies that /etc/hosts is searched first and DNS is searched second. When /compat/linux/etc/host.conf is not installed linux applications find FreeBSD's /etc/host.conf and complain about the incompatible FreeBSD syntax. You should remove bind if you have not configured a name-server using the /etc/resolv.conf file. Lastly, those who run 2.1-STABLE need to set an the RESOLV_HOST_CONF 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 /bin/csh shell use: &prompt.user; setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf For /bin/sh use: &prompt.user; RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF Finding the necessary files 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. 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: sunsite.unc.edu:/pub/Linux/distributions tsx-11.mit.edu:/pub/linux/distributions Some European mirrors: ftp.luth.se:/pub/linux/distributions ftp.demon.co.uk:/pub/unix/linux src.doc.ic.ac.uk:/packages/linux/distributions 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 contents subdirectory 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: 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 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 PACKAGE LOCATION, 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: Package Location ldso diska2 shlibs diska2 oldlibs diskx6 xf_lib diskx9 The locations called “diskXX” refer to the slakware/XX subdirectories of the distribution, others may be found in the contrib 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): slakware/a2/ldso.tgz slakware/a2/shlibs.tgz slakware/x6/oldlibs.tgz slakware/x9/xf_lib.tgz Extract the files from these gzipped tarfiles in your /compat/linux directory (possibly omitting or afterwards removing files you do not need), and you are done. See also: ftp://ftp.FreeBSD.org/pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README and /usr/src/sys/i386/ibcs2/README.iBCS2 How to Install Mathematica on FreeBSD Contributed by &a.rich; and &a.chuck; This document shows how to install the Linux binary distribution of Mathematica 2.2 on FreeBSD 2.1. 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. 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. Unpacking the Mathematica distribution 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 LINUX.TAR. You can, for example, unpack this into /usr/local/Mathematica: &prompt.root; cd /usr/local &prompt.root; mkdir Mathematica &prompt.root; cd Mathematica &prompt.root; tar -xvf /cdrom/LINUX.TAR Obtaining your Mathematica Password Before you can run Mathematica you will have to obtain a password from Wolfram that corresponds to your “machine ID”. Once you have installed the Linux compatibility runtime libraries and unpacked Mathematica you can obtain the “machine ID” by running the program mathinfo in the Install directory. &prompt.root; cd /usr/local/Mathematica/Install &prompt.root; mathinfo LINUX: 'ioctl' fd=5, typ=0x89(), num=0x27 not implemented richc.isdn.bcm.tmc.edu 9845-03452-90255 So, for example, the “machine ID” of richc is 9845-03452-90255. 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. 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. You can do this by invoking: &prompt.root; cd /usr/local/Mathematica/Install &prompt.root; math.install 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 + math.install fails, that is OK; you can simply edit the file mathpass in this same directory to correct the info manually. - After getting past the password, math.install will ask you if you + 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 + 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 math.install program. The directories we chose to create beforehand and specify to math.install were: /usr/local/Mathematica/bin for binaries /usr/local/Mathematica/man/man1 for man pages /usr/local/Mathematica/lib/X11 for the XKeysymb file You can also tell it to use /tmp/math.record for the system record file, where it puts logs of sessions. After this math.install will continue on to unpacking things and placing everything where it should go. 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 /usr/local/Mathematica/FrontEnd directory and execute the xfe.install 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 + created for math.install. When it finishes, there should be a new shell script in /usr/local/Mathematica/bin called mathematica. Lastly, you need to modify each of the shell scripts that Mathematica has installed. At the beginning of every shell script in /usr/local/Mathematica/bin add the following line: &prompt.user; XKEYSYMDB=/usr/local/Mathematica/lib/X11/XKeysymDB; export XKEYSYMDB This tells Mathematica were to find its own version of the key mapping file XKeysymDB. Without this you will get pages of error messages about missing key mappings. On 2.1-STABLE you need to add the following as well: &prompt.user; RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF - 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 + 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 /etc/host.conf if you leave this out. You might also want to modify your /etc/manpath.config file to read the new man directory, and you may need to edit your ~/.cshrc file to add /usr/local/Mathematica/bin to your path. That is about all it takes. With this you should be able to type mathematica 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! Bugs The Notebook front end is known to hang sometimes when reading notebook files with an error messages similar to: File .../Untitled-1.mb appears to be broken for OMPR.257.0 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 + the command line interface invoked by math is unaffected by this bug. Acknowledgments A well-deserved thanks should go to &a.sos; and &a.peter; who made Linux mode 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! :-) How does the Linux mode work? This section is based heavily on an e-mail written to the chat@FreeBSD.org mailing list, written by Terry Lambert tlambert@primenet.com (Message ID: <199906020108.SAA07001@usr09.primenet.com>). FreeBSD has an abstraction called an “execution class loader”. This is a wedge into the &man.execve.2; system call. What happens is that FreeBSD has a list of loaders, instead of a single loader with a fallback to the #! loader for running any shell interpreters or shell scripts. 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. 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. The assumption was a default of “whatever the current shell is”. Later, a hack was made for &man.sh.1; to examine the first two characters, and if they were :\n, then it invoked the - &man.csh.1; shell instead (I believe SCO first made this hack, but am - willing to be corrected). + &man.csh.1; shell instead (we believe SCO first made this hack). What FreeBSD does now is go through a list of loaders, with a generic #! loader that knows about interpreters as the characters which follow to the next whitespace next to last, followed by a fallback to /bin/sh. For the Linux ABI support, 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 type, at this point). The ELF loader looks for a specialized brand, which is a comment section in the ELF image, and which is not present on SVR4/Solaris ELF binaries. For Linux binaries to function, they must be branded as type Linux; from &man.brandelf.1;: &prompt.root; brandelf -t Linux file When this is done, the ELF loader will see the Linux brand on the file. When the ELF loader sees the Linux brand, the loader replaces a pointer in the proc structure. All system calls are indexed through this pointer (in a traditional UNIX system, this would be the sysent[] 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) fix-ups that are handled by the Linux kernel module. The Linux system call vector contains, among other things, a list of sysent[] entries whose addresses reside in the kernel module. When a system call is called by the Linux binary, the trap code dereferences the system call function pointer off the proc structure, and gets the Linux, not the FreeBSD, system call entry points. In addition, the Linux mode dynamically reroots lookups; this is, in effect, what the union option to FS mounts ( not the unionfs!) does. First, an attempt is made to lookup the file in the /compat/linux/original-path directory, then only if that fails, the lookup is done in the /original-path directory. This makes sure that binaries that require other binaries can run (e.g., the Linux toolchain can all run under Linux ABI support). 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 /compat/linux directory tree to ensure that the Linux binaries could not tell they were not running on Linux. 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 glue functions, and Linux binaries get the Linux glue functions (most older OS's only had their own glue functions: addresses of functions in a static global sysent[] structure array, instead of addresses of functions dereferenced off a dynamically initialized pointer in the proc structure of the process making the call). 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 glue 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. 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. So why is it sometimes called “Linux emulation”? To make it hard to sell FreeBSD! 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”.