Running Linux Applications on FreeBSD

FreeBSD users have long enjoyed the operating system's speed and
stability, but one area FreeBSD has always played "catch up" to
Linux in is new applications. While Linux has had the limelight,
software vendors have been prone to porting their applications to
Linux over FreeBSD.

Realizing this, FreeBSD made an end-run around
the situation and incorporated what is know as Linux Binary
Compatibility. This means that, without any sort or emulation
overhead, FreeBSD can run about 90 percent of all Linux applications
without modification. This includes applications such as StarOffice,
Netscape, Adobe Acrobat, RealPlayer, and more complicated applications
like VMWare and the Oracle database server. In some situations,
Linux binaries perform better on FreeBSD than they do on Linux.

How Does It Work?

Many people don't know it, but the ELF binary format allows for
what's called "branding," that is, you can mark binaries as being
for a certain operating system. Most operating systems don't bother
branding their binaries because they're designed to only run one
type.

FreeBSD makes good use of this feature by branding Linux
ELF binaries as such so that it can handle them slighty different
than FreeBSD binaries. Once you have the necessary parts of the
compatibility system installed you have all the libraries and
utilities that a Linux binary would rely on, they just live in a
different part of the file system. Since FreeBSD can distinguish
Linux binaries from its own, it can force the Linux binaries to
use this other set of libraries instead of the standard FreeBSD
libraries.

Installation and Configuration

An out-of-the-box install of FreeBSD does not have Linux Binary
Compatability enabled as the default. To do this you need to do two things,
configure your kernel so that it understands Linux binaries and
install the runtime libraries they depend on.

Kernel Configuration

The kernel part is pretty easy. There are two ways that you can go
about this. Your first option is to load the kernel module that
comes with the FreeBSD base system by running the linux command,
in which case you need to add this line to /etc/rc.conf to make
sure that the module gets loaded automatically at boot time:

linux_enable=YES

If you choose this option you should verify that the Linux module has
been loaded with the kldstat command:

If you do not want to or cannot load kernel modules for some reason,
you can use the second option and rebuild a new kernel with this
in your config file:

options LINUX

Either way that you choose to configure the kernel, you're only adding
about 10k to it so you shouldn't see any performance degradation.

Installing Runtime Libraries

After you have a kernel that understands Linux binaries, you need to
install the runtime libraries that they will depend on. This is
relatively straightforward as well. The easiest method is to install the
linux_base port:

# cd /usr/ports/emulators/linux_base
# make all install

This should leave you with all the necessary libraries installed in
/compat/linux

Running Linux ELF Binaries

If the Linux binary in question was compiled correctly, it should already
have the "Linux" brand on it. Some binaries will require an extra
step. If you run a Linux binary and you get an error like this:

$ ./some-linux-program
ELF binary type not known
Abort

you need to "brand" it as a Linux binary. This is done using the
brandelf program that is part of the FreeBSD base system.
Here is an example:

# brandelf -t Linux some-linux-program

Once you've completed these steps you should be able to run just about
any Linux binary.

It should be noted that 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 file system
(which is different from the optional FreeBSD /proc file system) or
i386-specific calls, such as enabling virtual 8086
mode.