Drei Kernelgenerationen – Auf der Suche nach der modernen Novena
Am Ende des ersten Teils stand eine scheinbar einfache Frage:
Was braucht eine Novena im Jahr 2026, um mit einem modernen Linux-Kernel vollständig zu funktionieren?
Inzwischen hatte ich drei sehr unterschiedliche Bezugspunkte:
Linux 3.19
↓
die alte funktionierende Novena-Referenz
Linux 5.7
↓
der Beweis, dass ein wesentlich modernerer Kernel funktioniert
Linux 6.x
↓
der Weg zu einer heutigen, reproduzierbaren Novena
Was zunächst wie eine Suche nach dem richtigen Kernel aussah, entwickelte sich schnell zu einer Untersuchung der gesamten Bootkette.
Eine der wichtigsten Meldungen dabei lautete:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Das klingt zunächst nach einem gescheiterten Kernelstart.
Tatsächlich beweist die Meldung aber bereits etwas Wichtiges: Der Kernel läuft.
Er ist nur noch nicht in der Lage, sein Root-Dateisystem zu finden oder einzubinden.
Und genau dieser Unterschied wurde für die weitere Fehlersuche entscheidend.
Linux 3.19 als Referenz
Der Ausgangspunkt war das alte, funktionierende System:
Linux 3.19.0-00485-gc5f2138
Mit diesem Kernel konnte die Novena Debian 12 vollständig von der SATA-SSD starten.
Damit hatte ich etwas ausgesprochen Wertvolles: eine funktionierende Referenz.
Der bekannte Bootpfad brauchte keine initrd. Der Kernel brachte alles mit, was er benötigte, um den SATA-Controller anzusprechen, die SSD zu erkennen und das ext4-Root-Dateisystem einzubinden.
Das alte System war deshalb mehr als nur ein Relikt.
Es war eine Kontrollprobe.
Wenn ein neuer Kernel an derselben Stelle scheiterte, konnte ich vergleichen:
- Welche Hardware wird erkannt?
- Welche Treiber sind eingebaut?
- Welche werden als Module geladen?
- Wie wird das Root-Dateisystem angegeben?
- Welche Rolle spielen Device Tree und Bootloader?
Der alte Kernel zeigte also nicht, wie die Novena in Zukunft betrieben werden sollte.
Er zeigte, was grundsätzlich funktionieren musste.
Warum der Debian-Kernel nicht einfach ein Ersatz war
Der naheliegendste Versuch war zunächst der Debian-Kernel:
linux-image-6.1.0-52-armmp
Paketversion:
6.1.180-1
Architektur:
armhf
Zunächst lag ein Verdacht nahe: Vielleicht konnte das alte U-Boot den Debian-Kernel gar nicht direkt starten.
Die Datei hieß schließlich:
/boot/vmlinuz-6.1.0-52-armmp
während die funktionierende Novena einen zImage-Kernel verwendete.
Doch eine Überprüfung mit file ergab:
Linux kernel ARM boot executable zImage (kernel >=v4.15) (little-endian)
Der vermeintliche Formatunterschied war also keiner.
Auch die historische Novena-Dokumentation zeigt, dass vmlinuz und zImage in diesem Zusammenhang nicht zwangsläufig unterschiedliche Kernelabbilder bedeuten.
Das war eine kleine, aber wichtige Lektion:
Ein plausibler Verdacht ist noch kein Befund.
Der eigentliche Unterschied lag an einer anderen Stelle.
Das Henne-Ei-Problem
Ein Blick in die Debian-Kernelkonfiguration zeigte unter anderem:
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
CONFIG_ATA=m
CONFIG_SATA_AHCI_PLATFORM=m
CONFIG_AHCI_IMX=m
CONFIG_EXT4_FS=m
Das =m ist hier entscheidend.
Diese Komponenten sind nicht fest in den Kernel eingebaut. Sie stehen als Kernelmodule zur Verfügung.
Das ist bei modernen Linux-Distributionen völlig normal.
Beim Start von einem SATA-Root-Dateisystem entsteht dadurch aber ein klassisches Henne-Ei-Problem:
Der Kernel benötigt Module, um die SATA-SSD und das ext4-Dateisystem vollständig benutzen zu können.
Die Module befinden sich jedoch normalerweise auf dem Root-Dateisystem.
Das Root-Dateisystem kann wiederum erst eingebunden werden, wenn die dafür notwendigen Treiber vorhanden sind.
Genau dafür gibt es den frühen Benutzerraum.
Bei Debian ist das üblicherweise ein initramfs, das beim Booten als initiales RAM-Dateisystem geladen wird. Historisch und in Bootloader-Kommandos begegnet einem dafür häufig auch der Begriff initrd. Technisch sind beide Konzepte nicht identisch, erfüllen an dieser Stelle aber dieselbe grundlegende Aufgabe: Sie stellen dem Kernel vor dem Einbinden des eigentlichen Root-Dateisystems die benötigten Werkzeuge und Module zur Verfügung.
Der alte 3.19-Kernel benötigte diesen Umweg für den bekannten SATA-Bootpfad nicht.
Der Debian-6.1-Kernel schon.
Damit war klar: Nur den Kernel auszutauschen konnte nicht genügen.
Drei Dateien, drei Adressen und eine Kommandozeile
Für einen manuellen Start mussten Kernel, initrd und Device Tree separat in den Speicher geladen werden.
Der vorbereitete U-Boot-Ablauf sah so aus:
setenv bootargs 'init=/lib/systemd/systemd root=PARTUUID=338c080c-02 rootwait rw console=tty0'
fatload sata 0 0x12000000 vmlinuz-6.1.0-52-armmp
fatload sata 0 0x13000000 initrd.img-6.1.0-52-armmp
fatload sata 0 0x11ff0000 imx6q-novena.dtb
bootz 0x12000000 0x13000000 0x11ff0000
Dabei liegen drei verschiedene Objekte an drei verschiedenen Speicheradressen:
0x12000000 Kernel
0x13000000 initrd
0x11ff0000 Device Tree
Der eigentliche Start erfolgt anschließend mit:
bootz
Wird keine initrd verwendet, kann an der entsprechenden Stelle ein Minuszeichen stehen:
bootz 0x12000000 - 0x11ff0000
Damit wurde immer deutlicher, dass „einen Kernel booten“ auf der Novena keineswegs nur bedeutet, eine Kerneldatei zu laden.
Kernelabbild, Device Tree, Kernel-Kommandozeile, Root-Gerät, initrd und Bootloader müssen zusammenpassen.
Für den Debian-6.1-Versuch ist in meinen erhaltenen Aufzeichnungen allerdings kein vollständig erfolgreicher Boot bis in den Benutzerraum dokumentiert.
Deshalb wäre es falsch, aus diesem Versuch entweder einen Erfolg oder eine grundsätzliche Inkompatibilität abzuleiten.
Die wesentlich aussagekräftigere Testreihe begann mit Linux 5.7.
Linux 5.7: Aus Fehlern wird eine Messreihe
Für die Novena existiert ein interessantes Kernel-Repository:
https://github.com/novena-next/linux.git
Der untersuchte Stand war:
Branch: nvn_v5.7-rc2
Commit: 1fda06deecb61538ca3d07d256eb7c43d4e3432a
Kernel: 5.7.0-rc2
Damit lag zwischen dem alten 3.19-Kernel und dem späteren 6.x-Ziel ein sehr nützlicher Zwischenstand.
Die folgende Abfolge ist aus den erhaltenen Bootlogs und der Projektdokumentation rekonstruiert. Sie beschreibt die Linux-5.7-Testreihe. Daraus folgt nicht, dass jeder einzelne Zwischenschritt mit exakt demselben SD-Image durchgeführt wurde.
Der erste Startversuch erfolgte ohne initrd:
bootz 0x12000000 - 0x11ff0000
Der Kernel startete:
Linux version 5.7.0-rc2
und erkannte das Board:
Machine model: Kosagi Novena Dual/Quad
Dann kam:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Die Kernel-Kommandozeile enthielt zu diesem Zeitpunkt lediglich:
init=/lib/systemd/systemd rootwait rw
Die entscheidende Information fehlte:
root=
Der Kernel wusste also schlicht nicht, welches Gerät sein Root-Dateisystem enthielt.
Von (0,0) zu (179,34)
Im nächsten Schritt wurde das Root-Dateisystem explizit angegeben:
root=PARTUUID=2178694e-02
Nun änderte sich die Fehlermeldung:
unknown-block(179,34)
Das sieht zunächst nur wie eine andere Zahl aus.
Für die Diagnose war es aber ein erheblicher Fortschritt.
Bei Linux steht die Block-Geräte-Hauptnummer 179 für MMC-Blockgeräte. Die Testreihe hatte also nicht mehr den völlig unspezifischen Zustand (0,0) erreicht, sondern einen konkreten Gerätepfad aus dem MMC-/SD-Bereich.
Die Zahlen allein reichen nicht aus, um daraus jede Einzelheit der Partitionszuordnung abzuleiten.
Aber sie zeigen, dass sich der Fehler verschoben hatte.
Der Kernel wusste jetzt, wonach er suchen sollte.
Damit war die nächste Frage nicht mehr:
Welches Root-Dateisystem soll überhaupt benutzt werden?
sondern:
Warum kann dieses Root-Dateisystem noch nicht erfolgreich eingebunden werden?
Der nächste Fehler kommt von U-Boot
Als Nächstes kam eine NixOS-initrd hinzu.
Damit tauchte ein neuer Fehler auf:
Wrong Ramdisk Image Format
Diesmal stammte die Meldung nicht vom Linux-Kernel.
Sie kam von U-Boot.
Das ist ein gutes Beispiel dafür, warum man beim Debuggen einer Bootkette genau darauf achten muss, welche Komponente eine Fehlermeldung erzeugt.
Die initrd war vorhanden.
Aber das vorhandene U-Boot akzeptierte ihr Format nicht in dieser Form.
Nachdem sie in ein für diesen Bootpfad passendes Legacy-U-Boot-Image verpackt worden war, stand eine Datei initrd.uimg zur Verfügung.
Nun konnte der Start mit drei Komponenten erfolgen:
bootz 0x12000000 0x13000000 0x11ff0000
Und plötzlich kam die Novena deutlich weiter.
NixOS Stage 1
Im seriellen Log erschien:
>
Das war ein entscheidender Punkt.
Denn damit war eine ganze Kette von Voraussetzungen bereits erfüllt:
U-Boot
↓
Kernel + Device Tree + initrd
↓
Linux 5.7
↓
MMC-/SD-Pfad
↓
früher NixOS-Benutzerraum
↓
Stage 1
Die nächste Fehlermeldung lautete:
fsck.ext4: Read-only file system
und außerdem:
Disk write-protected
Wieder war der Fehler lästig.
Aber wieder war er gleichzeitig ein Fortschritt.
Denn jetzt scheiterte das System nicht mehr beim Start des Kernels, nicht mehr an einem unbekannten Root-Gerät und nicht mehr am initrd-Format.
Es arbeitete bereits am Dateisystem.
Nach der Korrektur des Root-Dateisystems ging es weiter:
>
Und schließlich:
>
nixos login: nixos (automatic login)
[nixos@nixos:~]$
Damit war der vollständige Start bis in einen NixOS-Benutzerraum gelungen.
Ein Fehler kann Fortschritt bedeuten
Die Linux-5.7-Testreihe zeigte etwas, das bei der Fehlersuche leicht übersehen wird.
Nicht jeder neue Fehler ist ein Rückschritt.
Die Folge sah ungefähr so aus:
unknown-block(0,0)
↓
Root-Gerät angeben
↓
unknown-block(179,34)
↓
initrd hinzufügen
↓
Wrong Ramdisk Image Format
↓
initrd.uimg
↓
NixOS Stage 1
↓
Root-Dateisystem korrigieren
↓
NixOS Stage 2
↓
Login
Jeder Fehler markierte eine neue Grenze.
Und jede verschobene Grenze zeigte, dass die vorherige überwunden worden war.
Ohne serielle Konsole wäre ein großer Teil dieser Entwicklung kaum sichtbar gewesen. Auf dem internen Display hätte man häufig nur gesehen, dass das System „nicht bootet“.
Das serielle Log zeigte dagegen genau, wie weit es bootete.
Linux 5.7 lieferte damit einen wichtigen Beweis:
Die Novena war nicht an Linux 3.19 gebunden.
Ein deutlich modernerer Kernel konnte auf der realen Hardware bis in einen vollständigen Linux-Benutzerraum starten.
Damit änderte sich die Aufgabe erneut.
Jetzt ging es nicht mehr darum herauszufinden, ob ein modernerer Kernel möglich war.
Es ging darum, daraus einen heutigen und reproduzierbaren Systemaufbau zu entwickeln.
Von Linux 5.7 zu Linux 6.18
Linux 5.7 war ein wertvoller Zwischenschritt.
Das eigentliche Ziel lag aber weiter vorne.
Ich wollte nicht einfach irgendein historisches Image erhalten, das zufällig auf meiner Novena startete. Ich wollte nachvollziehen können, welche Bestandteile benötigt werden, woher sie stammen und wie daraus ein reproduzierbares System entsteht.
Damit kam NixOS erneut ins Spiel.
Nicht nur als Distribution, sondern als Werkzeug zur Reproduzierbarkeit.
Der nächste große Referenzpunkt wurde:
Linux 6.18.49
Und dieser Kernel erreichte auf der realen Novena erneut den vollständigen NixOS-Benutzerraum.
Linux 6.18.49 übernimmt
Im Bootlog erschien:
Linux version 6.18.49
und erneut:
Machine model: Kosagi Novena Dual/Quad
NixOS erreichte Stage 1, band das Root-Dateisystem ein und startete anschließend bis zum regulären Login.
Doch diesmal kam noch etwas hinzu.
Das interne Display funktionierte.
Der IT6251-Display-Bridge-Chip wurde erkannt:
IT6251 detected: vendor ca15 device 6251
Die Displayparameter wurden korrekt ermittelt:
hactive: 1920
vactive: 1080
und der Link meldete:
is_stable: stable 1920x1080
display link stable
bridge_enable: exit success
Damit lief das interne Display stabil mit 1920 × 1080 Pixeln.
Bild 1: Die Novena während des erfolgreichen Tests mit Linux 6.18.49. NixOS bootete bis in den vollständigen Benutzerraum; das interne Display arbeitete stabil mit 1920 × 1080.
Das war ein wesentlich stärkeres Ergebnis als ein Kernel, der lediglich bis zu einer Shell auf der seriellen Konsole kommt.
Meine Novena konnte mit einem modernen Linux-Kernel betrieben werden.
Aber die Geschichte war damit noch nicht beendet.
Ein funktionierendes System mit verdächtigen Meldungen
Im Bootlog tauchten weiterhin Meldungen auf, die nicht ignoriert werden konnten:
stmpe-i2c 0-0044: failed to read regs 0xb: -11
Außerdem:
i2c i2c-0: NOVENA-I2C: arbitration lost in bus_busy
und:
i2c i2c-0: write timedout
Später erschienen auch Fehler wie -110 und -6.
Das System bootete.
Das Display funktionierte.
Aber zu diesem Zeitpunkt waren Teile der I²C-Kommunikation offensichtlich noch nicht zuverlässig.
Das war eine interessante Situation.
Ein System kann oberflächlich betrachtet funktionieren und trotzdem Fehler enthalten, die später relevant werden können.
Für die weitere Arbeit bedeutete das: Der erfolgreiche Boot war kein Grund, die Untersuchung abzubrechen.
Er war vielmehr eine neue Ausgangsbasis.
Wann funktioniert ein Kernel?
Damit lässt sich auch die Frage beantworten, warum man auf einem bereits laufenden Linux nicht einfach einen neueren Kernel baut und diesen anschließend startet.
Natürlich kann man einen Kernel kompilieren.
Aber ein bootfähiges System besteht auf dieser Hardware nicht nur aus dem Kernel.
Vereinfacht sieht die Kette so aus:
U-Boot
↓
Kernel
↓
Device Tree
↓
Kernel-Kommandozeile
↓
initrd / initramfs
↓
Root-Gerät und benötigte Treiber
↓
Root-Dateisystem
↓
Benutzerraum
Dazu kommen noch praktische Details wie die Speicheradressen, an die U-Boot Kernel, Device Tree und initrd lädt, sowie die Formate, die der vorhandene Bootloader versteht.
Wenn nur ein Glied dieser Kette nicht passt, kann ein völlig funktionsfähiger Kernel trotzdem in einem nicht bootfähigen System enden.
Genau das machten die verschiedenen Fehlermeldungen sichtbar.
unknown-block(0,0) bedeutete etwas anderes als unknown-block(179,34).
Wrong Ramdisk Image Format kam aus einer anderen Schicht als ein VFS-Kernel-Panic.
NixOS Stage 1 wiederum bewies bereits wesentlich mehr als ein gestarteter Kernel.
Die Frage lautet deshalb nicht nur:
Funktioniert dieser Kernel?
Sondern:
Funktioniert dieser Kernel innerhalb der gesamten Bootkette dieser Maschine?
Drei Kernelgenerationen
Nach diesen Versuchen ergab sich ein deutlich klareres Bild:
| Kernel | Ergebnis |
|---|---|
| Linux 3.19 | vollständiger Debian-12-Start von SATA |
| Linux 5.7 | vollständiger NixOS-Start bis zum Login |
| Linux 6.18.49 | vollständiger NixOS-Start und funktionierendes internes Display |
Der Debian-6.1-Versuch fehlt bewusst in dieser Tabelle.
Nicht weil er unwichtig war, sondern weil in meinen erhaltenen Aufzeichnungen kein vollständiger erfolgreicher Boot dokumentiert ist.
Sein Wert lag vor allem darin, die Abhängigkeiten zwischen Kernelmodulen, initrd und Root-Dateisystem sichtbar zu machen.
Die drei anderen Kernelstände liefern dagegen jeweils einen klar dokumentierten Referenzpunkt.
Damit war die ursprüngliche Frage weitgehend beantwortet.
Die Novena kann auch mit einem modernen Linux-Kernel betrieben werden.
Doch damit entstand sofort die nächste Frage.
Eine bootfähige Zeitkapsel
Während der Tests war ein historisches NixOS-Image zu einer wichtigen technischen Referenz geworden.
Es enthielt bereits viele Bestandteile einer funktionierenden Bootkette.
Damit wurde es plötzlich interessant, nicht nur mit diesem Image zu arbeiten, sondern es systematisch zu untersuchen.
Was befindet sich vor der ersten Partition?
Wo liegt U-Boot?
Wie ist die SD-Karte partitioniert?
Welche Kernel-, Device-Tree- und initrd-Dateien werden verwendet?
Welche Speicheradressen erwartet der Bootloader?
Und welche Teile davon sind allgemeine ARM-Linux-Mechanismen – und welche sind Besonderheiten der Novena?
Die ersten Antworten zeigten bereits eine bemerkenswerte Struktur:
Bootloader-Bereich vor der ersten Partition
↓
FAT-Partition "FIRMWARE"
↓
SPL / U-Boot
Kernel
Device Tree
initrd
Boot-Skript
↓
ext4-Partition "NIXOS_SD"
↓
NixOS
Damit wurde aus einem alten SD-Karten-Image etwas anderes.
Eine bootfähige Zeitkapsel.
Nicht als Endprodukt.
Sondern als technische Quelle.
Die nächste Aufgabe lautete deshalb:
Kann man aus einer funktionierenden historischen SD-Karte eine nachvollziehbare Bauanleitung für ein neues Novena-System gewinnen?
Weiter in Teil 3: Eine bootfähige Zeitkapsel – das historische NixOS-Image unter der Lupe
Hinweis zur Entstehung dieses Artikels: Bei der Arbeit an der Novena nutze ich ChatGPT als Werkzeug zur Analyse von Bootlogs und Quellcode, zur Planung und Auswertung von Tests sowie zur technischen Dokumentation. Auch bei der Strukturierung, sprachlichen Überarbeitung und Ausarbeitung dieser Artikelserie unterstützt mich ChatGPT. Die Arbeiten an der realen Hardware, die Tests und die dokumentierten Beobachtungen stammen von mir; technische Aussagen gleiche ich soweit möglich mit den Projektaufzeichnungen und den angegebenen Quellen ab.
Die verwendeten Fotos zeigen die reale Novena; KI-generierte Bilder werden in diesem Artikel nicht verwendet.
Quellen und weiterführende Links
Linux-Kernel-Dokumentation
Linux Kernel Documentation – Using the initial RAM disk (initrd)
https://docs.kernel.org/admin-guide/initrd.html
Linux Kernel Documentation – Ramfs, rootfs and initramfs
https://docs.kernel.org/filesystems/ramfs-rootfs-initramfs.html
Linux Kernel Documentation – Linux allocated devices
https://docs.kernel.org/admin-guide/devices.html
U-Boot
U-Boot Documentation – bootz command
https://docs.u-boot.org/en/v2022.07/usage/cmd/bootz.html
Novena
Novena Guide – Common Tasks
https://git.bnewbold.net/novena-guide/tree/tasks.rst?h=pvt2&id=e8e02bba612bc1fcbcb14680ee2e4b2a34006e23
Projektinterne Quellen
Eigene Bootlogs, Kernelkonfigurationen, Prüfsummen, Testprotokolle und Projektdokumentation aus den Linux-3.19-, Debian-6.1-, Linux-5.7- und Linux-6.18.49-Untersuchungen.
Quellen:
Eigene Fotos und eigene Projektdokumentation des Autors. Die technischen Quellen und weiterführenden Links sind am Ende des Artikels aufgeführt.

