English Portuguese (Brazil)
FreeBSD has a list of loaders, instead of a single loader, with a fallback to the `#!` loader for running shell interpreters or shell scripts.
For the Linux(R) ABI support, FreeBSD sees the magic number as an ELF binary. 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(TM) ELF binaries.
For Linux(R) binaries to function, they must be _branded_ as type `Linux` using man:brandelf[1]:
# brandelf -t Linux 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 addition, the process is flagged for special handling of the trap vector for the signal trampoline code, and several other (minor) fix-ups that are handled by the Linux(R) kernel module.
The Linux(R) 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(R) binary, the trap code dereferences the system call function pointer off the `proc` structure, and gets the Linux(R), not the FreeBSD, system call entry points.
Linux(R) 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#. 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(R) toolchain can all run under Linux(R) ABI support. It also means that the Linux(R) binaries can load and execute FreeBSD binaries, if there are no corresponding Linux(R) binaries present, and that a man:uname[1] command can be placed in the [.filename]#/compat/linux# directory tree to ensure that the Linux(R) binaries cannot tell they are not running on Linux(R).
In effect, there is a Linux(R) 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(R) system call table entries: file system operations, virtual memory operations, signal delivery, and System V IPC. The only difference is that FreeBSD binaries get the FreeBSD _glue_ functions, and Linux(R) binaries get the Linux(R) _glue_ functions. The FreeBSD _glue_ functions are statically linked into the kernel, and the Linux(R) _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(R) 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(R) binaries was not true, since the code was not compiled in.