11.3. Weiterführende Themen

Dieser Abschnitt beschreibt wie die Linux®-Binärkompatibilität funktioniert. Die folgenden Informationen stammen aus einer E-Mail, die von Terry Lambert () an FreeBSD chat geschrieben wurde (Message ID: <199906020108.SAA07001@usr09.primenet.com>).

FreeBSD verfügt über eine execution class loader genannte Abstraktion. Dabei handelt es sich um einen Eingriff in den execve(2) Systemaufruf.

Historisch gesehen untersuchte der einzige, auf UNIX®-Plattformen vorhandene Lader die magische Zahl (in der Regel die ersten 4 oder 8 Bytes der Datei), um festzustellen, ob der Binärtyp dem System bekannt war. War dies der Fall, wurde der Binärlader aufgerufen.

Wenn es sich nicht um den zum System gehörigen Binärtyp handelte, gab execve(2) einen Fehler zurück, und die Shell versuchte stattdessen, die Datei als Shell-Befehl auszuführen. Dabei wurde als Standardeinstellung was auch immer die aktuelle Shell ist festgelegt.

Später wurde ein Hack in sh(1) eingefügt, der die zwei ersten Zeichen untersuchte. Wenn diese :\n entsprachen, wurde stattdessen die csh(1)-Shell aufgerufen.

FreeBSD verfügt über eine Liste von Ladern, anstelle eines einzigen, auf #! zurückgreifenden Laders, um Shell-Interpreter oder Shell-Skripte auszuführen.

Für die Linux® ABI-Unterstützung erkennt FreeBSD die magische Zahl als ELF-Binärdatei. Der ELF-Lader sucht nach einer speziellen Kennzeichnung, die aus einem Kommentarabschnitt in der ELF-Datei besteht, und die in SVR4/Solaris™ ELF Binärdateien nicht vorhanden ist.

Damit Linux®-Binärdateien unter FreeBSD funktionieren, müssen sie mit brandelf(1) als Linux gekennzeichnet werden:

# brandelf -t Linux file

Wenn der ELF-Lader die Linux-Kennzeichnung sieht, wird ein Zeiger in der proc-Struktur ersetzt. Alle Systemaufrufe werden durch diesen Zeiger indiziert. Der Prozess wird weiterhin speziell gekennzeichnet, so dass der Trap-vector im Signal-trampoline-code eine spezielle Behandlung erfährt und das Linux®-Kernelmodul verschiedene kleinere Korrekturen vornehmen kann.

Der Linux®-Systemaufrufvektor enthält neben anderen Dingen eine Liste der sysent[]-Einträge, deren Adressen sich im Kernelmodul befinden.

Wenn ein Linux®-Programm einen Systemaufruf ausführt, dereferenziert die Trap-Behandlungsroutine den Zeiger für den Systemaufruf aus der proc-Struktur und erhält damit die Linux®-Eintrittspunkte für den Systemaufruf.

Zusätzlich verändert der Linux®-Modus die Systempfade dynamisch; genauso, wie dies die Option union beim Einbinden von Dateisystemen macht. Zuerst wird die Datei im Verzeichnis /compat/linux/Originalpfad gesucht, wenn sie dort nicht gefunden wurde, wird sie im Verzeichnis /Originalpfad gesucht. Dadurch wird sichergestellt, dass Binärdateien, die zur Ausführung andere Binärdateien benötigen, ausgeführt werden können (so dass alle Linux®-Werkzeuge unter der ABI laufen). Dies bedeutet auch, dass Linux®-Binärdateien FreeBSD-Binärdateien laden und ausführen können, wenn keine passenden Linux®-Binärdateien vorhanden sind. Ein in /compat/linux plaziertes uname(1) kann damit Linux®-Programmen vorgaukeln, dass sie auf einem Linux®-System laufen.

Im Endeffekt gibt es einen Linux®-Kernel innerhalb des FreeBSD-Kernels. Die Sprungtabellen für Linux®- beziehungsweise FreeBSD-Systemaufrufe verweisen allerdings auf dieselben Funktionen, die Kerneldienste wie Dateisystemoperationen, Operationen für den virtuellen Speicher, Signalübermittlung und System V IPC bereitstellen. Der einzige Unterschied ist, dass Binärdateien unter FreeBSD FreeBSD-glue-Funktionen verwendet werden. Linux®-Binärdateien hingegen verwenden die Linux®-glue-Funktionen. FreeBSD-glue-Funktionen sind statisch in den Kernel gelinkt, Linux®-glue-Funktionen sind statisch gelinkt oder können über ein ladbares Kernelmodul eingebunden werden.

Technisch gesehen ist dies nicht wirklich eine Emulation, sondern eine ABI-Implementation. Es wird manchmal Linux® Emulation genannt, da es zu einer Zeit implementiert wurde, in der es kein anderes Wort gab, das beschrieb, was vor sich ging. Es war falsch zu behaupten, FreeBSD würde Linux®-Binärprogramme ausführen, da der Code nicht unter FreeBSD übersetzt wurde.

Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an <de-bsd-questions@de.FreeBSD.org>.

Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <de-bsd-translators@de.FreeBSD.org>.