Dieser Abschnitt beschreibt wie die
Linux®-Binärkompatibilität funktioniert. Die folgenden
Informationen stammen aus einer E-Mail, die von Terry Lambert
(<tlambert@primenet.com>
) 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>.