Linux binary compatibility is not turned on by default. The
easiest way to enable this functionality is to load the
linux
KLD object („Kernel LoaDable
object”). You can load this module by typing the
following as root
:
#
kldload linux
If you would like Linux compatibility to always be enabled,
then you should add the following line to
/etc/rc.conf
:
linux_enable="YES"
The kldstat(8) command can be used to verify that the KLD is loaded:
%
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 KLD,
then you may statically link Linux binary compatibility into the kernel
by adding options COMPAT_LINUX
to your kernel
configuration file. Then install your new kernel as described in
Rozdział 8, Konfiguracja jądra FreeBSD.
This can be done one of two ways, either by using the linux_base port, or by installing them manually.
This is by far the easiest method to use when installing the runtime libraries. It is just like installing any other port from the Ports Collection. Simply do the following:
#
cd /usr/ports/emulators/linux_base-fc4
#
make install distclean
You should now have working Linux binary compatibility. Some programs may complain about incorrect minor versions of the system libraries. In general, however, this does not seem to be a problem.
There may be multiple versions of the emulators/linux_base port available, corresponding to different versions of various Linux distributions. You should install the port most closely resembling the requirements of the Linux applications you would like to install.
If you do not have the „ports” collection
installed, 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, it will then 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.
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.
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).
If you have access to a Linux system, see what shared libraries the application needs, and copy them to your FreeBSD system. Look at the following example:
Let us assume you used FTP to get the Linux binary of
Doom, and put it on a Linux system you have access to. You
then can check which shared libraries it needs by running
ldd linuxdoom
, like so:
%
ldd linuxdoom
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
Uwaga:
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.27and 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.29If 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 thelibc.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
Uwaga:
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.
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:
%
./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 brandelf(1) utility.
%
brandelf -t Linux my-linux-elf-binary
The GNU toolchain now places the appropriate branding information into ELF binaries automatically, so this step should become increasingly unnecessary in the future.
If DNS does not work or you get this message:
resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword
You will need to configure a
/compat/linux/etc/host.conf
file
containing:
order hosts, bind multi on
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.
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.