Linux – bald 40 Millionen Codezeilen schwer

Die Quellen des Linux genannten Kernels bestanden bei der Freigabe von Linux 6.13 zum Wochenanfang am 20. Jänner aus exakt 39.819.522 Zeilen – Code-Kommentare, Leerzeilen, Dokumentation, Build-Infrastruktur und Ähnliches mitgezählt. Da alle neun oder zehn Wochen durchschnittlich grob vierhunderttausend Codezeilen dazu kommen, wird der Kernel voraussichtlich Ende Jänner 2025 in der Hauptentwicklungsphase von Version 6.14 die 40-Millionen-Zeilen-Marke durchbrechen.

Dieses Wachstum ist so manchem ein massiver Dorn im Auge, wie Forenbeiträge zeigen. Bedenken sind bis zu einem gewissen Grad auch berechtigt. Zugleich gilt es aber, nicht zu vergessen, was für ein miserabler Maßstab die Zahl der Codezeilen vielfach ist. Funktionen oder Treiber rauswerfen würde zudem sicherlich die Menge des Kernel-Codes immens senken, während zugleich jedoch Nutzerfreundlichkeit, Codequalität und Sicherheit litten. All das zeigt sich bei einem genaueren Blick.

Die Schwächen des Maßstabs offenbaren sich bereits beim Blick auf den Code für verschiedene Hardware-Architekturen: er allein summiert sich derzeit in Summe auf knapp 4,4 Millionen Zeilen. Das Gros davon schaut sich der Compiler beim Übersetzen von Linux aber gar nicht erst an, schließlich unterstützt ein von ihm erzeugter Kernel ohnehin nur eine Prozessorarchitektur.

Für heute gängige x86-64-CPUs ist daher vor allem der x86-Architekturcode relevant, der sich derzeit auf 493010 Zeilen beläuft. Aber selbst weite Teile davon erfahren keine nähere Beachtung, denn das Verzeichnis enthält neben dem Code für moderne 64-Bit-x86-Prozessoren auch jenen für ihre 32-Bit-Vorläufer.

Auch viel anderen Code lässt der Compiler links liegen, schließlich verwendet Linux ein eher monolithisches Kernel-Design – neben essenziellen Funktionen moderner Betriebssystem-Kernel enth&aul;lt es daher auch Treiber. Nicht nur ein paar, sondern Zehntausende, die sich auf rund 25 Millionen Zeilen summieren.

Beim Bau eines Kernels für die eigenen Systeme ist viel von diesem Treibercode indes irrelevant. Denn genau wie der Architektur-Code erfordern manche Treiber bestimmte Plattformen, lassen sich also auf 64-Bit-x86-Systemen gar nicht erst übersetzen. Selbst, wenn das möglich ist, heißt das keineswegs, daß ein Treiber auch kompiliert wird: darüber entscheidet ein Mensch, der vor dem Bau eines Kernels den Bauplan (die ".config"-Datei) über Schritte wie make menuconfig oder make xconfig festlegt.

Linux-Kenner denken jetzt womöglich: damit ist viel des Treibercodes dennoch relevant und ein potenzielles Sicherheitsrisiko, schließlich aktivieren Mainstream-Distributionen wie Debian das Gros der für die jeweiligen Plattformen verfügbaren Treiber. Ein relevanter Einwand, den es aber auch nicht überzubewerten gilt: diese Treiber werden schließlich fast immer als Module übersetzt, von denen der Kernel die meisten gar nicht erst lädt.

Eine Gnome-Desktop-Installation von Debian GNU/Linux 12.8 in einer VM hievt von viertausend Kernel-Modulen daher nur etwas mehr als hundert in den Arbeitsspeicher. Direkt auf der Hardware laufend sind es schnell mal doppelt so viele – aber selbst dann sind es nur rund fünf Prozent aller Module, die der Kernel lädt.

Bei allerlei Modulen verweigert Linux das Laden sogar, wenn es die von den Treibern unterstützte Hardware nicht vorfindet. Bei solchen für Dateisysteme, Netzwerkprotokolle oder andere Hardware-unabhängige Funktionen hilft das allerdings nicht. Wer Schutz vor Lücken in deren Code sucht, kann den Kernel nach dem Systemstart aber durch ein simples echo 1 > /proc/sys/kernel/modules_disabled leicht untersagen, weitere Module nachzuladen.

Das Wachstum indes wird weitergehen, schließlich erscheinen immer wieder neue Produkte und Technologien, bei denen meist irgendwer für Unterstützung in Linux sorgt. Gegen diese nicht enden wollende Schwemme sind gelegentliche Aufräumarbeiten regelmäßig ein Tropfen auf den heißen Stein, schließlich schmeißen die Kernel-Entwickler alte Treiber normalerweise erst raus, wenn wahrscheinlich niemand die unterstützte Hardware mehr produktiv einsetzt. Was ein Grund ist, warum viele Leute Linux schätzen, denn dadurch kann es auch weit über ein Jahrzehnt alte PCs oft zu einem zweiten Frühling verhelfen.

Immerhin scheint sich das Wachstum seit einigen Jahren bei grob vierhundertausend Codezeilen alle neun oder zehn Wochen eingependelt zu haben. Einzelne Versionen weichen von diesem Durchschnitt aber immer stark ab: in seltenen Fällen schrumpft der Kernel mit einer neuen Version sogar mal, während er bei anderen über eine Million Zeilen zulegt.

Hauptschuld an solch schneller Gewichtszunahme sind meist computergenerierte Header-Dateien mit Definitionen zum Ansprechen der Hardware: diese umfassen gerne mehrere Megabyte. Allein die in Linux enthaltenen Include-Dateien für moderne Grafikchips von AMD summieren sich mittlerweile auf fünf Millionen Zeilen – von denen der Compiler die meisten weitgehend ignoriert, denn sie sind auch eine lebende Dokumentation von Eigenschaften des Grafikchips.

Die Entwickler diskutieren dennoch gerade, ungenutzte Definitionen dieses Treibers auszulagern. Der Kernel könnte dadurch enorm schrumpfen. Advokaten von "weniger Code ist besser" würden das sicher begrüßen. Das ist aber ja kein Selbstzweck, sondern verspricht Sicherheit, Wartung und Performance zu verbessern – Vorteile, die bei dieser angedachten Schrumpfkur nicht oder wenn überhaupt marginal wären.

Diesen Zielen wäre es auch abträglich, wenn man selten verwendete, ältere oder wie von manchen gefordert alle Treiber rauswerfen würde. Der Bedarf an den Treibern ist ja weiter da. Viele würden somit extern gepflegt. Das beschränkt das Viele-Augen-Prinzip erheblich, denn Code und Änderungen an ihm durchliefen dann vor der Aufnahme keine Qualitätskontrolle mehr durch erfahrene Kernel-Maintainer.

Er würde auch die ganzen Testsysteme nicht erreichen, die den offiziellen Kernel ständig rauf und runter kompilieren oder nach Performance-Änderungen suchen. Außerdem entzöge er sich Entwicklern von Bestrebungen wie dem "Kernel Self Protection Project", die ständig verschiedenste Areale des Linux-Codes verbessern, um Systemsicherheit und Robustheit des Kernels zu verbessern.

In einigen Fällen würde ein Auslagern zu einem Mehr an externem Kernel-Code führen, wie Praxiserfahrungen mit außerhalb der offiziellen Kernelquellen von Hardware-Herstellern gewarteten Treibern zeigen. Denn statt etwa einen WLAN-Treiber um Support für eine neuere Generation eines WLAN-Chips zu erweitern, wie es die Linux-Kernel-Entwickler wann immer halbwegs sinnvoll machen, erstellen Hersteller viel eher neue Treiber auf Basis des vorherigen. Fehlerkorrekturen oder Optimierungen müssen sie dann statt an einer an mehreren Stellen vornehmen – was selbst bei guten Vorsätzen erfahrungsgemäß am Ende zumeist mehr schlecht als recht gelingt. Ein Grund, warum viele Hersteller die Treiber unzureichend oder zumeist nur wenige Jahre pflegen.

Extern gewartete Kernel-Treiber würde Anwendern zudem die Installation und Pflege von Treibern erheblich erschweren, da sie diese nicht mehr einfach über den Kernel frei Haus erhalten. Distributionen können diese zwar wieder einfangen und beilegen, aber das macht natürlich bei jeder viel Extra-Arbeit. Am Ende wäre sehr wahrscheinlich nichts gewonnen, aber vieles schlechter als zurzeit.

Einige der erwähnten Nachteile ließen sich vermeiden, wenn man eine andere zentrale Stelle für Treiber schaffen würde – aber das hätte ja kaum Vorteile gegenüber der zentralen Stelle, die wir jetzt haben. Zumindest gäbe es keine, solange niemand Linux stabile Schnittstellen verpasst, um Treiber vom Rest des Kernels zu entkoppeln. Das ist eine alte und immer wieder gehörte Forderung, die Anwendern vermeintlich Installation und Handling von Treiber erleichtern soll, weil sie dann Treiber und den Rest des Kernels unabhängig voneinander aktualisieren können, wie man es von Windows kennt.

Ob diese Vorteile überhaupt eintreten würden und welche enormen Nachteile das für die Entwicklung von Linux bedeuten würde, ist kein so einfaches Thema. Aber klar ist: solche Schnittstellen erfordern für Abwärts- und Vorwärtskompatibilität viel zusätzlichen Code. Noch dazu Code, der leicht Fehler enthalten kann, der zu Sicherheitslücken führt, wie die Erfahrung anderswo lehrt. Im Hinblick auf "möglichst schlanker Kernel" wäre es somit kontraproduktiv.

Die angeführten Argumente mögen den Eindruck erwecken, als gäbe es beim Kernel keine Gründe, den Code irgendwo zu verschlanken. Das ist mitnichten so, denn wie bei jeder komplexen Software gibt es deren auch bei Linux reichlich. Genau wie anderswo steigt auch der Overhead an vielen Stellen schleichend an. Dadurch laufen beispielsweise neuere Kernel mit der Zeit immer schlechter auf Systemen mit wenigen Megabyte Arbeitsspeicher.

Aber diese Probleme sind kleiner und die Lage komplizierter, als es auf den ersten Blick erscheinen mag. Eine Form des "Bikeshedding" in gewisser Weise also: wie beim viel zitierten Fahrradständer für ein neu gebautes Atomkraftwerk glaubt aber halt jeder, bei diesem Thema mitreden zu können. Aber weil es komplizierter ist, entpuppen sich einige vermeintlich einfache Sparmöglichkeiten als kontraproduktiv oder Augenwischerei. Ähnlich also, wie schnelle Diät-Versprechungen mancher Zeitschriften.

Genau wie bei Kilos auf den Hüften ist aber natürlich durchaus möglich, daß eine Gewichtszunahme irgendwann auch bei Linux zu Gesundheitsproblemen führt. Derweil deutet indes nichts darauf hin, daß das in nähere Zukunft passiert, obwohl Leute das schon seit mehr als zwei Jahrzehnten postulieren. Im Gegenteil: Linux ist trotz oder vielleicht sogar wegen seiner Größe nach wie vor unangefochten der erfolgreichste Betriebssystem-Kernel dieser Welt.