Vorige: , Nach oben: Bootstrapping   [Inhalt][Index]


20.2 Vorbereitung zur Verwendung der Bootstrap-Binärdateien

Abhängigkeitsgraph der frühen
Bootstrap-Ableitungen

Die Abbildung oben zeigt den Anfang des Abhängigkeitsgraphen der Distribution und entspricht den Paketdefinitionen im (gnu package bootstrap)-Modul. Eine ähnliche Grafik kann mit guix graph (siehe guix graph aufrufen) erzeugt werden:

guix graph -t derivation \
  -e '(@@ (gnu packages bootstrap) %bootstrap-gcc)' \
  | dot -Tps > gcc.ps

oder für das Bootstrapping mit noch kleinerem Seed:

guix graph -t derivation \
  -e '(@@ (gnu packages bootstrap) %bootstrap-mes)' \
  | dot -Tps > mes.ps

Bei diesem Detaillierungsgrad sind die Dinge recht komplex. Guile selbst besteht aus einer ausführbaren ELF-Datei neben vielen Quelldateien und kompilierten Scheme-Dateien, die dynamisch bei der Ausführung geladen werden. Das wird in dem im Graph gezeigten guile-2.0.7.tar.xz-Archiv gespeichert. Das Archiv ist Teil von Guix’ „Quelldistribution“ und wird in den Store mit add-to-store (siehe Der Store) eingefügt.

Doch wie schreibt man eine Ableitung, die dieses Tarball-Archiv entpackt und in den Store einfügt? Um dieses Problem zu lösen, benutzt die guile-bootstrap-2.0.drv-Ableitung – die erste, die erstellt wird – bash als Ersteller, welche wiederum build-bootstrap-guile.sh ausführt, was über einen Aufruf von tar den Tarball entpackt. Deswegen sind bash, tar, xz und mkdir als statisch gebundene Binärdateien auch Teil der Guix-Quelldistribution, die nur dazu da sind, dass der Guile-Tarball entpackt werden kann.

Sobald guile-bootstrap-2.0.drv erstellt worden ist, haben wir ein funktionierendes Guile zur Hand, mit dem nachfolgende Erstellungsprogramme ausgeführt werden können. Sein erster Auftrag ist, Tarballs mit den anderen vorerstellten Binärdateien herunterzuladen – das ist die Tätigkeit der .tar.xz.drv-Ableitungen. Wir verwenden zu diesem Zweck Guix-Module wie ftp-client.scm. Die module-import.drv-Ableitungen importieren solche Module und schreiben sie in derselben Verzeichnisstruktur in ein Verzeichnis im Store. Die module-import-compiled.drv-Ableitungen kompilieren die Module und schreiben sie in der richtigen Struktur in ein Ausgabeverzeichnis. Dies entspricht dem #:modules-Argument von build-expression->derivation (siehe Ableitungen).

Schließlich werden die verschiedenen Tarballs durch die Ableitungen gcc-bootstrap-0.drv, glibc-bootstrap-0.drv, oder bootstrap-mes-0.drv und bootstrap-mescc-tools-0.drv, entpackt. Zu diesem Zeitpunkt haben wir eine fertige Toolchain für C.

Die Erstellungswerkzeuge erstellen

Das Bootstrapping ist abgeschlossen, sobald eine vollständige Toolchain vorliegt, die von den oben erläuterten vorerstellten Bootstrapping-Werkzeugen nicht abhängt. Diese Voraussetzung, keine Abhängigkeiten zu haben, überprüft man, indem man schaut, ob die Dateien der endgültigen Toolchain frei von Referenzen auf die /gnu/store-Verzeichnisse der Bootstrapping-Eingaben sind. Der Vorgang, diese „finale“ Toolchain zu bekommen, wird von den Paketdefinitionen beschrieben, die Sie im Modul (gnu packages commencement) finden.

Mit dem Befehl guix graph können wir gegenüber dem obigen Graphen „herauszoomen“, indem wir alles auf der Ebene von Paketobjekten statt auf der von einzelnen Ableitungen betrachten – denken Sie daran, dass ein Paket zu mehreren Ableitungen führen kann; normalerweise einer, die seine Quelldateien herunterlädt, einer, die die benötigten Guile-Module erstellt, und einer, die das Paket dann tatsächlich aus seinem Quellcode heraus erstellt. Der Befehl

guix graph -t bag \
  -e '(@@ (gnu packages commencement)
          glibc-final-with-bootstrap-bash)' | xdot -

zeigt den Abhängigkeitsgraphen, der zur „finalen“ C-Bibliothek41 führt. Hier sehen Sie ihn:

Abhängigkeitsgraph der frühen Pakete

Das erste Werkzeug, das mit den Bootstrapping-Binärdateien erstellt wird, ist GNU Make – beachten Sie das oben sichtbare make-boot0 –, das eine Voraussetzung aller folgenden Pakete ist. Von da aus werden Findutils und Diffutils erstellt.

Es folgt die erste Stufe der Binutils und GCC, die pseudo-crosskompiliert werden – d.h. die --target-Befehlszeilenoption entspricht der --host-Option. Mit ihnen wird libc erstellt. Dank den Crosskompilierungstricks ist garantiert, dass diese libc keine Referenzen auf die anfängliche Toolchain enthält.

Damit werden die finalen Binutils und GCC erstellt (sie sind oben nicht zu sehen). GCC benutzt den ld aus den finalen Binutils und bindet Programme an die gerade erstellte libc. Mit dieser Toolchain erstellen wir die anderen Pakete, die Guix und das GNU-Erstellungssystem benutzen: Guile, Bash, Coreutils, etc.

Und voilà! Wenn das geschafft ist, haben wir die vollständige Menge von Erstellungswerkzeugen, die das GNU-Erstellungssystem erwartet. Sie sind in der Variablen %final-inputs des Moduls (gnu packages commencement) zu finden und werden von jedem Paket implizit benutzt, das das gnu-build-system verwendet (siehe gnu-build-system).

Die Bootstrapping-Binärdateien erstellen

Weil die finale Toolchain nicht von den Bootstrapping-Binärdateien abhängt, müssen diese nur selten aktualisiert werden. Es ist dennoch sinnvoll, sie automatisiert erzeugen zu können, wenn sie doch aktualisiert werden. Das Modul (gnu packages make-bootstrap) ermöglicht dies.

Mit dem folgenden Befehl werden die Tarball-Archive erstellt, die die Bootstrapping-Binärdateien enthalten (beim traditionellen Bootstrapping sind das Binutils, GCC und glibc; beim Bootstrapping mit kleinerem Seed sind es linux-libre-headers, bootstrap-mescc-tools, bootstrap-mes; dazu kommen Guile sowie ein Tarball mit einer Mischung aus Coreutils und anderen grundlegenden Befehlszeilenwerkzeugen):

guix build bootstrap-tarballs

Die erzeugten Tarballs sind es, auf die im Modul (gnu packages bootstrap) verwiesen werden sollte, das am Anfang dieses Abschnitts erwähnt wurde.

Können Sie noch folgen? Dann haben Sie vielleicht schon angefangen, sich zu fragen, wann wir denn einen Fixpunkt erreichen. Das ist eine interessante Frage! Leider wissen wir es nicht, aber wenn Sie es herausfinden wollen (und Ihnen die nennenswerten Rechen- und Speicherkapazitäten dafür zur Verfügung stehen), dann lassen Sie es uns wissen.

Die Menge an Bootstrapping-Binärdateien verkleinern

Zu unserem traditionellen Bootstrapping gehören GCC, GNU Libc, Guile, etc. Das ist ganz schön viel binärer Code! Warum ist das ein Problem? Es ist deswegen ein Problem, weil es praktisch unmöglich ist, solch große Klumpen binären Codes einem Audit zu unterziehen. Dadurch wird es schwer, nachzuvollziehen, welcher Quellcode ihn erzeugt hat. Jede ausführbare Binärdatei, für die kein Audit möglich ist, macht uns verwundbar gegenüber Hintertüren in Compilern, wie Ken Thompson sie in seiner Arbeit von 1984, Reflections on Trusting Trust, beschrieben hat.

Wir senken das Risiko, indem wir unsere Bootstrapping-Binärdateien immer mit einer früheren Guix-Version erzeugen. Trotzdem fehlt uns das Niveau an Transparenz, das wir am übrigen Paketabhängigkeitsgraphen wertschätzen, wo Guix immer vom Quellcode eindeutig auf die Binärdateien abbildet. Unser Ziel ist also, die Menge an Bootstrapping-Binärdateien so weit wie möglich zu verkleinern.

Auf dem Webauftritt von Bootstrappable.org werden laufende Projekte mit diesem Zweck aufgeführt. Bei einem davon geht es darum, den Bootstrapping-GCC durch eine Folge von Assemblern, Interpretierern und Compilern zunehmender Komplexität zu ersetzen, die von Anfang an aus Quellcode heraus erstellt werden kann, angefangen bei einem einfachen, überprüfbaren Assembler.

Unsere erste große Leistung stellt die Ersetzung von GCC, der GNU-C-Bibliothek und der Binutils durch die MesCC-Tools (einem einfachen Binder für hexadezimal dargestellte Maschinenprogramme und einem Makro-Assembler) und Mes dar (siehe Referenzhandbuch zu GNU Mes in GNU Mes, einem Scheme-Interpretierer und in Scheme geschriebenen C-Compiler). Weder MesCC-Tools noch Mes können bereits von Grund auf gebootstrapt werden, daher schleusen wir sie als binäre Seeds ein. Wir nennen das unser Bootstrapping mit kleinerem Seed, weil es die Größe unserer Bootstrapping-Binärdateien halbiert hat! Außerdem haben wir damit keinerlei Binärdatei für einen C-Compiler; auf i686-linux und x86_64-linux werden Guix-Pakete ganz ohne binären C-Compiler gebootstrapt.

Wir arbeiten daran, MesCC-Tools und Mes vollständig bootstrappen zu können, und behalten auch andere Bootstrapping-Binärdateien im Blick. Ihre Unterstützung ist willkommen!


Fußnoten

(41)

Ihnen könnte die glibc-intermediate-Markierung auffallen, die darauf hindeutet, dass sie noch nicht ganz final ist, aber annäherungsweise betrachten wir sie als final.


Vorige: Bootstrapping aus dem Quellcode allein, Nach oben: Bootstrapping   [Inhalt][Index]