-description: FreeBSD provides binary compatibility with Linux®, allowing users to install and run most Linux® binaries on a FreeBSD system without having to first modify the binary
+description: FreeBSD provides binary compatibility with Linux, allowing users to install and run most Linux binaries on a FreeBSD system without having to first modify the binary
-FreeBSD provides binary compatibility with Linux(R), allowing users to install and run most Linux binaries on a FreeBSD system without having to first modify the binary.
-It has even been reported that, in some situations, Linux binaries perform better on FreeBSD than they do on Linux.
+FreeBSD provides optional binary compatibility with Linux(R), allowing users to install
+and run unmodified Linux binaries.
+It is available for i386, amd64, and arm64 architectures.
-However, some Linux-specific operating system features are not supported under FreeBSD.
-For example, Linux binaries will not work on FreeBSD if they overly use i386(TM) specific calls, such as enabling virtual 8086 mode.
-
-[NOTE]
-====
-Support for 64-bit binary compatibility with Linux was added in FreeBSD 10.3.
-====
+Some Linux-specific operating system features are not yet supported;
+this mostly happens with functionality specific to hardware or related
+to system management, such as cgroups or namespaces.
After reading this chapter, you will know:
@@ -76,76 +73,117 @@
[[linuxemu-lbc-install]]
== Configuring Linux Binary Compatibility
-By default, Linux libraries are not installed and Linux binary compatibility is not enabled.
-Linux libraries can either be installed manually or from the FreeBSD Ports Collection.
+By default, Linux binary compatibility is not enabled. To enable it at boot time,
+add this line to [.filename]#/etc/rc.conf#:
-Before attempting to build the port, load the Linux kernel module, otherwise the build will fail:
+[.programlisting]
+....
+linux_enable="YES"
+....
+To enable it without rebooting, run this command:
[source,shell]
....
-# kldload linux
+# service linux start
....
-For 64-bit compatibility:
+The [.filename]#/etc/rc.d/linux# script will load neccessary kernel modules and mount filesystems
+expected by Linux applications under [.filename]#/compat/linux#. This is enough for statically
+linked Linux binaries to work. They can be started in the same way native FreeBSD binaries can;
+they behave almost exactly like native processes and can be traced and debugged the usual way.
+
+Linux binaries linked dynamically (which is the vast majority) also require Linux shared libraries
+to be installed - they can run on top of FreeBSD kernel, but they cannot use FreeBSD libraries;
+this is similar to how 32-bit binaries cannot use native 64-bit libraries.
+There are several ways of providing those libraries: one can copy them over from existing
+Linux installation, install from FreeBSD packages, or install using deboostrap(8), and others.
+
+[[linuxemu-packages]]
+== CentOS Userspace from FreeBSD Packages
+
+The easiest way to install Linux libraries is to install package:emulators/linux_base-c7[]
+package or port:
[source,shell]
....
-# kldload linux64
+# pkg install linux_base-c7
....
-To verify that the module is loaded:
-
+FreeBSD provides packages for some Linux binary applications. For example, to install
+Sublime Text, run this command:
[source,shell]
....
-% kldstat
- Id Refs Address Size Name
- 1 2 0xc0100000 16bdb8 kernel
- 7 1 0xc24db000 d000 linux.ko
+# pkg install linux-sublime
....
-The package:emulators/linux_base-c7[] package or port is the easiest way to install a base set of Linux libraries and binaries on a FreeBSD system.
-To install the port:
+[[linuxemu-debootstrap]]
+== Debian / Ubuntu Userspace with deboostrap(8)
-[source,shell]
+An alternative way of providing Linux shared libraries is by using package:sysutils/debootstrap[].
+This has the advantage of providing a full Debian or Ubuntu distribution. To use it, follow the
+instructions at FreeBSD Wiki: https://wiki.freebsd.org/LinuxJails[FreeBSD Wiki - Linux Jails].
+
+It is possible to debootstrap into [.filename]#/compat/linux#, but it is discouraged to avoid
+collisions with files installed from FreeBSD ports and packages. Instead, derive the directory
+name from distribution or version name, e.g. [.filename]#/compat/ubuntu#. If you want to use
+it to provide Linux shared libraries without having to explicitly use chroot or jails,
+point the kernel at it by updating the `compat.linux.emul_path` sysctl and adding a line like
+this to [.filename]#/etc/sysctl.conf#:
+
+[.programlisting]
....
-# pkg install emulators/linux_base-c7
+compat.linux.emul_path="/compat/ubuntu"
....
-For Linux compatibility to be enabled at boot time, add this line to [.filename]#/etc/rc.conf#:
+Afterwards chroot(8) into the newly created directory and install software in a way typical
+for the Linux distribution you have debootstrapped, for example:
-[.programlisting]
+[source,shell]
....
-linux_enable="YES"
+# chroot /compat/ubuntu /bin/bash
+root@hostname:/# apt update
....
-On 64-bit machines, [.filename]#/etc/rc.d/abi# will automatically load the module for 64-bit emulation.
+[[linuxemu-advanced]]
+== Advanced Topics
-Since the Linux binary compatibility layer has gained support for running both 32- and 64-bit Linux binaries (on 64-bit x86 hosts), it is no longer possible to link the emulation functionality statically into a custom kernel.
+Linux compatibility layer is a work in progress. Consult
+https://wiki.freebsd.org/Linuxulator[FreeBSD Wiki - Linuxulator] for more information.
-For some applications, [.filename]#/compat/linux/proc#, [.filename]#/compat/linux/sys#, and [.filename]#/compat/linux/dev/shm# may need to be mounted.
-Add this line to [.filename]#/etc/fstab#:
+List of all sysctl knobs can be found in man:linux[4] man page.
+Some applications require specific filesystems to be mounted.
+This is normally handled by [.filename]#/etc/rc.d/linux# script, but can be disabled
+by adding this line to [.filename]#/etc/rc.conf#:
+Since the Linux binary compatibility layer has gained support for running both 32- and 64-bit Linux binaries (on 64-bit x86 hosts), it is no longer possible to link the emulation functionality statically into a custom kernel.
[[linuxemu-libs-manually]]
=== Installing Additional Libraries Manually
+[NOTE]
+====
+For userspaces created with debootstrap(8), use the instructions above instead.
+====
+
If a Linux application complains about missing shared libraries after configuring Linux binary compatibility, determine which shared libraries the Linux binary needs and install them manually.
-From a Linux system, `ldd` can be used to determine which shared libraries the application needs.
+From a Linux system using the same CPU architecture, `ldd` can be used to determine which shared libraries the application needs.
For example, to check which shared libraries `linuxdoom` needs, run this command from a Linux system that has Doom installed:
[source,shell]
@@ -202,10 +240,13 @@
Generally, one will need to look for the shared libraries that Linux binaries depend on only the first few times that a Linux program is installed on FreeBSD.
After a while, there will be a sufficient set of Linux shared libraries on the system to be able to run newly installed Linux binaries without any extra work.
-=== Installing Linux ELF Binaries
+=== Branding Linux ELF Binaries
-ELF binaries sometimes require an extra step.
-When an unbranded ELF binary is executed, it will generate an error message:
+FreeBSD kernel uses several methods to determine if the binary to be executed is a Linux
+one: it checks the brand in the ELF file header, looks for known ELF interpreter paths
+and checks ELF notes; finally, by default, unbranded ELF executables are assumed to be Linux
+anyway. Should all those methods fail, an attempt to execute the binary might result in error
+message:
[source,shell]
....
@@ -221,8 +262,6 @@
% brandelf -t Linux my-linux-elf-binary
....
-Since the GNU toolchain places the appropriate branding information into ELF binaries automatically, this step is usually not necessary.
-
=== Installing a Linux RPM Based Application
To install a Linux RPM-based application, first install the package:archivers/rpm4[] package or port.
@@ -260,14 +299,14 @@
Remove `bind` if a name server is not configured using [.filename]#/etc/resolv.conf#.
[[linuxemu-advanced]]
-== Advanced Topics
+=== Miscellaneous
This section describes how Linux binary compatibility works and is based on an email written to {freebsd-chat} by Terry Lambert mailto:tlambert@primenet.com[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.
-Historically, the UNIX(R) loader 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.
+Historically, the UNIX loader 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".
@@ -296,7 +335,7 @@
Linux mode dynamically _reroots_ lookups.
This is, in effect, equivalent to `union` to file system mounts.
-First, an attempt is made to lookup the file in [.filename]#/compat/linux/original-path#.
+First, an attempt is made to look up the file in [.filename]#/compat/linux/original-path#.
If that fails, the lookup is done in [.filename]#/original-path#.
This makes sure that binaries that require other binaries can run.
For example, the Linux toolchain can all run under Linux ABI support.
@@ -308,5 +347,5 @@
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.
Technically, this is not really emulation, it is an ABI implementation.
-It is sometimes called "Linux emulation" because the implementation was done at a time when there was no other word to describe what was going on.
+It is sometimes called "Linux emulation" because the implementation was done at a time when there was no other word to describe what was going on.
Saying that FreeBSD ran Linux binaries was not true, since the code was not compiled in.