Erstellung von NetBSD aus den Quellen

Erstellung von NetBSD aus den Quellen
By Matthias Petermann / on 13.01.2026

Systemnähe beginnt beim Build

Im ersten Artikel dieser Serie habe ich beschrieben, warum ich wieder näher an die Systeme heran will. Weniger Plattform, mehr Betriebssystem. Weniger Konsum, mehr Konstruktion. Nicht aus Ablehnung gegenüber modernen Ansätzen, sondern aus dem Wunsch heraus, die Dinge wieder vollständig zu durchdringen.

Dieser Anspruch lässt sich nicht einlösen, wenn man bei vorgefertigten Artefakten stehen bleibt.

Ein System wirklich zu verstehen bedeutet, seinen Entstehungsprozess zu kennen. Zu sehen, welche Werkzeuge beteiligt sind, wo Abhängigkeiten entstehen und an welchen Stellen Entscheidungen getroffen werden. Erst wenn Kernel, Toolchain und Userspace nicht mehr als gegebene Blackbox erscheinen, sondern als Ergebnis konkreter Build-Schritte, wird ein System greifbar.

Ein selbstgebautes Betriebssystem verändert den Blick. Build-Abhängigkeiten werden sichtbar, Versionsstände bekommen Bedeutung, und „das System“ wird wieder zu etwas, das man erklären kann – nicht nur benutzen.

Genau deshalb beginne ich dieses Projekt nicht mit der Installation eines fertigen Images, sondern mit dem bewussten Aufbau von NetBSD aus dem offiziellen Source-Tree. Nicht als Selbstzweck und nicht als sportliche Übung, sondern als konsequente Fortsetzung der im ersten Artikel formulierten Haltung: Systeme bauen, nicht nur betreiben.


Reproduzierbarkeit als Ausgangspunkt

NetBSD bringt ein sehr leistungsfähiges Cross-Build-System mit. Es ist explizit dafür entworfen, auf fremden Hosts zu laufen und komplette Zielsysteme inklusive Toolchain zu erzeugen. In der Praxis heißt das: Man kann NetBSD auf Linux, macOS oder anderen BSDs bauen und dabei beliebige Zielarchitekturen ansprechen.

Theoretisch könnte ich den gesamten Build also direkt von meinem Linux-Notebook aus durchführen.

ℹ️ Cross-Build-Fähigkeit von NetBSD

Das NetBSD-Buildsystem ist dafür ausgelegt, auf nicht-NetBSD-Systemen zu laufen.
Linux, macOS, andere BSDs – alles wird offiziell unterstützt.

Dokumentation:
https://www.netbsd.org/docs/guide/en/chap-build.html

Ich entscheide mich hier bewusst anders. Für dieses Projekt nutze ich ein altes ThinkPad X230 als dedizierte Build-Maschine – mein „Basecamp“. Nicht, weil es technisch notwendig wäre, sondern weil ich den gesamten Stack in einer Hand haben möchte: Firmware, Betriebssystem, Toolchain und Build-Umgebung.


Schritt 1: Offizielles NetBSD installieren

Bevor ich irgendetwas selbst baue, installiere ich zunächst ein offizielles, unverändertes NetBSD 10.1 auf dem X230. Diese Installation dient mir als saubere Referenzbasis, ohne eigene Anpassungen, ohne selbstgebaute Artefakte und ohne implizite Abhängigkeiten.

Ich orientiere mich dabei an der offiziellen Installationsanleitung von NetBSD, benutze allerdings EFI-Boot und entscheide mich für eine vollständige Installation statt einzelner Distributionskomponenten.

ℹ️ Offizielle Installationsanleitung (Bare Metal)
NetBSD Installation Guide (amd64):
https://www.netbsd.org/docs/guide/en/chap-exinst.html
📝 Bewusste Reihenfolge
Ich verwende hier bewusst keine selbstgebauten Images.
Erst offizielles Release, dann eigener Build.

Nach der Installation liegt ein vollständig unterstütztes, unverändertes NetBSD 10.1 auf dem System. Das ist der Ausgangspunkt für alle weiteren Schritte.


Einordnung: Releases, Stable und Branches

Bevor wir in den Build einsteigen, ist ein kurzer Blick auf die Release-Politik von NetBSD sinnvoll. Sie unterscheidet klar zwischen formalen Releases, Stable-Branches und den jeweils aktuellen Ständen innerhalb dieser Branches.

NetBSD arbeitet unter anderem mit:

  • formalen Releases wie 10.1
  • Stable-Branches wie netbsd-10
  • aktuellen Ständen innerhalb des Branches, zum Beispiel 10.1_STABLE
ℹ️ NetBSD Release-Politik

Beispiel:

  • NetBSD 10.1 → offizielles, veröffentlichtes Release
  • netbsd-10 → Stable-Branch für die 10er-Serie
  • NetBSD 10.1_STABLE → aktueller Stand des netbsd-10-Branches

Der Stable-Branch ist weiter als das letzte Release, garantiert ABI-stabil und wird kontinuierlich gepflegt.

Dokumentation:
https://www.netbsd.org/releases/release-map.html

Für dieses Projekt bedeutet das: Ich arbeite nicht auf dem Entwicklungs-Head und auch nicht auf einem eingefrorenen Release, sondern gezielt auf dem stabilen, gepflegten netbsd-10-Branch.


Schritt 2: Quellen beziehen

NetBSD wird primär in CVS entwickelt, stellt aber einen offiziellen Git-Mirror bereit. Für meinen Workflow ist Git deutlich praktischer, da es sich nahtlos in meine gewohnte Arbeitsweise einfügt.

ℹ️ NetBSD Source Repositories
$ git clone https://github.com/NetBSD/src.git
$ git clone https://github.com/NetBSD/xsrc.git

Schritt 3: Auf den Stable-Branch wechseln

Nach dem Klonen wechsle ich in beiden Repositories gezielt auf den netbsd-10-Branch. Damit ist klar definiert, welcher Code-Stand gebaut wird und welche Stabilitätsannahmen gelten.

$ (cd src; git checkout netbsd-10)
$ (cd xsrc; git checkout netbsd-10)
📝 Bewusste Branch-Wahl
Kein Rolling-Head, kein Snapshot, kein Experiment.
Ein stabiler, nachvollziehbarer Stand.

Schritt 4: Build des gesamten Systems

Der eigentliche Build erfolgt über das zentrale build.sh-Skript. Dieses Skript ist der definierte Einstiegspunkt für alle Build-Schritte und kapselt den kompletten Prozess von der Toolchain bis zu den Installationsmedien.

Ich baue in dieser Reihenfolge:

  • Toolchain
  • Kernel, Userspace, X11
  • Release-Sets
  • Archive des verwendeten Quellcodes
  • Installationsmedien

Der Build erfolgt in einem separaten Objektverzeichnis, um Quellen und Artefakte sauber zu trennen.

$ cd src
$ ./build.sh -m amd64 -x -X ../xsrc -O ../obj -j 2 -U tools
$ ./build.sh -m amd64 -x -X ../xsrc -O ../obj -j 2 -U release
$ ./build.sh -m amd64 -x -X ../xsrc -O ../obj -j 2 -U sourcesets
$ ./build.sh -m amd64 -x -X ../xsrc -O ../obj -j 2 -U iso-image
$ ./build.sh -m amd64 -x -X ../xsrc -O ../obj -j 2 -U install-image
ℹ️ build.sh als zentrales Interface
Ein Skript, ein klarer Einstiegspunkt und ein gut strukturierter Ablauf.
Toolchain → World → Release → Images.
💡 Reproducible Builds in NetBSD

Reproducible Builds sind Build-Prozesse, die sicherstellen, dass aus dem gleichen Quellcode unter identischen Bedingungen bit-für-bit identische Binärartefakte entstehen. Dadurch lässt sich verifizieren, dass ein bestimmter Build wirklich aus dem angegebenen Quellcode stammt und weder in der Build-Umgebung noch im Build-Prozess verändert wurde.

NetBSD hat seit einigen Jahren an diesem Thema gearbeitet. Ab der amd64- und SPARC64-Architektur erreicht das Build-System heute reproduzierbare Builds, indem es deterministische Timestamps, geordnete Build-Schritte und stabile Build-Environment-Parameter verwendet. Ein spezielles Build-Flag (-P in build.sh) setzt intern Variablen wie MKREPRO und MKREPRO_TIMESTAMP, sodass die Artefakte auf Basis des neuesten Quellcode-Zeitstempels erzeugt werden – sehr ähnlich dem Standard SOURCE_DATE_EPOCH.

Technisch ist das im Wesentlichen eine Kombination aus:

  • kontrollierten Timestamps (z. B. über MKREPRO_TIMESTAMP/SOURCE_DATE_EPOCH statt der aktuellen Uhrzeit)
  • deterministischem Dateisystem- und Build-Verhalten
  • kein Einbetten von Build-Host-Informationen, die bei jedem Build variieren würden
  • sortierten Build-Schritten und Artefakt-Listen

Das Ergebnis: Mehrere Builds aus dem gleichen Source-Tree ergeben identische Binaries.

Reproduzierbare Builds sind eine zusätzliche Qualitätssicherungsmaßnahme, die insbesondere bei sicherheitsrelevanten Systemen oder der Weitergabe von Artefakten an Dritte ihre Stärke ausspielen. Sie erhöhen die Transparenz des Build-Prozesses und ermöglichen es, Ergebnisse unabhängig nachzuvollziehen und zu verifizieren.

Dabei ist zu berücksichtigen, dass dieser Ansatz in der Praxis einen weiteren vollständigen Build-Durchlauf erfordert und sich die Gesamtbuildzeit entsprechend verlängert. Der zusätzliche Aufwand steht jedoch in einem klaren Verhältnis zum gewonnenen Vertrauen in die Artefakte und ist ein bewährtes Mittel, um Build-Prozesse noch robuster und überprüfbarer zu gestalten.


Ergebnis: Eigene Installationsmedien

Nach erfolgreichem Build liegen die erzeugten Artefakte im Verzeichnis obj/releasedir/images.

$ ls -la obj/releasedir/images

Beispiel:

-r--r--r--  1 mpeterma  wheel  445964077 NetBSD-10.1_STABLE-amd64-bios-install.img.gz
-r--r--r--  1 mpeterma  wheel  446075767 NetBSD-10.1_STABLE-amd64-install.img.gz
-r--r--r--  1 mpeterma  wheel  642115584 NetBSD-10.1_STABLE-amd64.iso

Das sind vollwertige Installationsimages, gebaut aus dem aktuellen Stable-Branch und mit meiner eigenen Toolchain.


Schritt 5: Boot-Datenträger erstellen

$ gunzip -k NetBSD-10.1_STABLE-amd64-install.img.gz
$ doas dd if=NetBSD-10.1_STABLE-amd64-install.img of=/dev/sd0 bs=4M
📝 Bewusst schlicht
Kein GUI-Tool, kein zusätzlicher Workflow, kein Umweg.
Ein Image, ein Blockdevice, ein Schreibvorgang.

Warum dieser Umweg?

Natürlich hätte ich auch einfach das offizielle Image verwenden können. Das wäre schneller und bequemer gewesen. Für dieses Projekt ist das aber nicht der Punkt.

Mir geht es darum, zu wissen, was in meinem System ist, woher es kommt und warum es so ist. Ein selbstgebautes System zwingt zu Klarheit und verhindert, dass sich implizite Annahmen einschleichen.

ℹ️ Systemnähe in der Praxis
Ein selbstgebautes System ist kein Statement.
Es ist eine bewusste Arbeitsweise.

Fazit

Mit diesem Schritt ist die Basis gelegt. Ein offizielles NetBSD 10.1 dient als Referenz, der aktuelle Stable-Branch ist gebaut, und eigene Installationsmedien liegen vor. Ab hier bewege ich mich vollständig innerhalb meines eigenen Systemraums.

Im nächsten Artikel geht es um die Installation des selbstgebauten Systems, das Disk-Layout, die Basiskonfiguration und die ersten strukturellen Entscheidungen.


Bildnachweis: Das NetBSD-Logo ist eine eingetragene Marke der NetBSD Foundation, Inc. Verwendung im Rahmen redaktioneller Berichterstattung gemäß den Richtlinien zur Logonutzung.