Das FreeBSD-Handbuch
Zurück | Kapitel 11. Linux-Binärkompatibilität | Weiter

# 11.7. Weiterführende Themen

Wenn Sie sich fragen, wie die Linux-Binärkompatibilität unter FreeBSD realisiert wurde, sollten Sie diesen Abschnitt lesen. Der Großteil der folgenden Informationen stammt aus einer E-Mail, die von Terry Lambert (`<tlambert@primenet.com>`) an die FreeBSD-Chat-Mailingliste (`<freebsd-chat@FreeBSD.org>`) geschrieben wurde (Message ID: `<199906020108.SAA07001@usr09.primenet.com>`).

## 11.7.1. Wie funktioniert es?

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

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

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 (wir glauben, dass dies zuerst von SCO umgesetzt wurde).

FreeBSD versucht heute eine Liste von Ladern, unter denen sich ein allgemeiner Lader für Interpreter befindet. Der auszuführende Interpreter wird im ersten, durch Leerzeichen getrennten Feld, der `#!`-Zeile angegeben. Lässt sich der Interpreter nicht ermitteln, wird auf `/bin/sh` zurückgegriffen.

Für die Linux ABI-Unterstützung erkennt FreeBSD die magische Zahl als ELF-Binärdatei (Zu diesem Zeitpunkt wird nicht zwischen FreeBSD, Solaris™, Linux oder anderen Systemen unterschieden, die über ELF-Binärdateien verfügen.).

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 als `Linux` gekennzeichnet werden, und zwar durch brandelf(1):

    # brandelf -t Linux file

Nachdem dies geschehen ist, erkennt der ELF-Lader die `Linux`-Kennzeichnung der Datei.

Wenn der ELF-Lader die `Linux`-Kennzeichnung sieht, wird ein Zeiger in der `proc`-Struktur ersetzt. Alle Systemaufrufe werden durch diesen Zeiger indiziert (in einem traditionellen UNIX® System wäre das ein `sysent[]`-Strukturfeld, das die Systemaufrufe enthält). 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 auf die Eintrittspunkte für die Systemaufrufe und erhält damit die Linux-Eintrittspunkte und nicht die FreeBSD-Eintrittspunkte.

Zusätzlich verändert der Linuxmodus die Systempfade dynamisch; genauso, wie dies die Option `union` beim Einbinden von Dateisystemen macht (Achtung: nicht das Dateisystem unionfs!). Zuerst wird die Datei im Verzeichnis `/compat/linux/`Originalpfad`` gesucht, danach, wenn sie dort nicht gefunden wurde, wird sie im FreeBSD-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 verwenden. Linux-Binärdateien hingegen verwenden die Linux-glue-Funktionen. Die meisten älteren Betriebssysteme hatten ihre eigenen glue-Funktionen: Funktionsadressen in einem globalen, statischen `sysent[]` Strukturfeld an Stelle von Funktionsadressen, die durch einen dynamisch initialisierten Zeiger aus der `proc` Struktur, die den Aufruf gemacht hatte, dereferenziert wurden.

Welche ist die echte FreeBSD-ABI? Das spielt keine Rolle. Grundsätzlich ist der einzige Unterschied (zurzeit ist das so; dies könnte sich in zukünftigen Versionen leicht ändern und wird sich wahrscheinlich auch ändern), dass die FreeBSD-glue-Funktionen statisch in den Kernel gelinkt sind, und dass die Linux-glue-Funktionen statisch gelinkt oder über ein Modul eingebunden werden können.

Ja, aber ist das wirkliche eine Emulation? Nein. Es ist eine Implementierung eines ABIs, keine Emulation. Es ist kein Emulator (oder Simulator, um der nächsten Frage zuvorzukommen) beteiligt.

Warum wird es manchmal “Linux-Emulation” genannt? Um es schwerer zu machen, FreeBSD zu verkaufen. Wirklich, das kommt daher, weil dies zu einer Zeit implemtiert wurde, in der es kein anderes Wort (als Emulation) gab, das beschrieb, was vor sich ging. Wenn der Kernel nicht entsprechend konfiguriert wurde oder das Modul geladen wurde, war es falsch zu behaupten, FreeBSD würde Linux-Binärprogramme ausführen. Man benötigte ein Wort, das beschrieb, was da geladen wurde – daher “Der Linux-Emulator”.

Zurück | Zum Anfang | Weiter
Oracle® installieren | Nach oben | Systemadministration

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>.