Aus Linux-Magazin 03/2010

Kernel- und Treiberprogrammierung mit dem Kernel 2.6 - Folge 50

Zum Jubiläum: Pinguine, die ins Gefängnis kommen, und Anleitungen, die Programmierer verbrennen sollten: Der Linux-Kernel bietet auch Nicht-Entwicklern allerlei Kurzweiliges.

Was haben ein Mobiltelefon, ein Supercomputer, Fernseher, Netbooks und Armbanduhren, ein Flaschenrücknahme-Automat und Navigationsgeräte sowie der Rechner von Chefredakteur Jan Kleinert gemeinsam? Alle verwenden Linux als Betriebssystemkern. Diese wichtige Komponente liefert problemlos Stoff für jede Menge Magazinartikel. Nach 49 Folgen Technik wird es nun Zeit für eine Zäsur: Diese Kern-Technik befasst sich mit Sonderbarem, Kurzweiligem und Statistischem rund um den Kernel.

Von allem gibt es genug, schließlich ist es ein Projekt der Superlative: Gemäß der Studie “Linux Kernel Development”, herausgegeben im August 2009 von der Linux-Foundation [1], haben 5000 Programmierer aus allen Teilen der Welt rund sechs Millionen Zeilen Code erstellt, 500 Firmen sind beteiligt, darunter mit 20 000 Zeilen auch Microsoft, die Linux ehemals als Krebsgeschwür bezeichneten. Täglich kommen rund 12 000 Zeilen Code neu hinzu.

Netto beträgt der Zuwachs allerdings nur 7000 Zeilen, denn 5000 Zeilen entfernen die Maintainer täglich. 2500 Zeilen erfahren im 24-Stunden-Rhythmus eine Modifikation. Alle zwölf Minuten kommt ein neues Patch hinzu. Das summiert sich auf gut 10 000 Patches für eine neue Kernelversion (siehe Kasten “Abfallprodukt Git”).

Diese Codezeilen sind durchaus ein paar Blicke wert: Der aus Klassen und Objekten realisierte Kern ist ein Zeichen dafür, dass Objektorientierung nicht eine Sache der Programmiersprache ist, sondern primär eine des Kopfes. Die Objekte sind im Linux-Kernel als Datenstrukturen (»struct«) implementiert, Methoden als Funktionspointer.

Abfallprodukt Git

Torvalds hat nicht nur die Erfolgsstory “Linux-Kernel” geschrieben. Quasi als Abfallprodukt der Kernelentwicklung ist das Source-Control-System Git berühmt geworden. Der in Oregon lebende Finne hat mit Git nicht nur vorhandene Systeme nachgebaut und in Grundstrukturen oder Details verbessert, sondern hat mit seinen lokalen Repositories eine neue Art der Sourcecode-Verwaltung konzipiert und realisiert. Es vergeht kaum ein Monat, in dem nicht ein bekanntes Projekt auf Git umsteigt, um damit seine Quelltexte zu verwalten.

Code ordentlich notieren

Auch Linux-Interessierte, die nicht täglich zu Editor und Compiler greifen, entdecken bei genauem Hinschauen unterhalb von »/usr/src/linux-Version/« viel Interessantes. Selbst mit nur begrenzten Programmierkenntnissen finden sie sich recht gut zurecht, denn gemessen an der Zahl der beteiligten Entwickler herrscht ein erfreulich einheitlicher Stil. Das ist nicht zuletzt der Kodier-Richtlinie von Linus Torvalds zu verdanken, die er im Verzeichnis »Documentation/« unter dem Namen »CodingStyle« ablegte.

In der C-Welt konkurrieren – vereinfacht ausgedrückt – der GNU-Stil mit dem der C-Erfinder Kernighan und Ritchie [2]. Während Klammern bei im GNU-Stil geschriebener Software mittig zum Schlüsselwort stehen, ordnen Kernighan und Ritchie die schließende Klammer der jeweiligen Schlüsselwort-Ebene zu (siehe Listings 1 und 2). Vorteil: Der beim Programmieren sichtbare Bildschirmausschnitt zeigt mehr relevante Codezeilen. Linus Torvalds hat hierzu Stellung genommen: Wer sich für den Linux-Kern interessiert, sollte zumindest den Anfang des Dokuments lesen und seine Anweisungen befolgen (siehe Abbildung 1). Torvalds vielleicht größte Leistung dabei ist das Augenmaß: Trotz seiner Vorgaben toleriert der Linux-Erfinder auch gewisse Abweichungen.

Abbildung 1: Die Anweisung ist eindeutig und die Message klar: Der GNU-Programmierstil verträgt sich nicht mit dem Linux-Kernel. Im weiteren Text schlägt Torvalds jedoch auch versöhnlichere Töne an.

Abbildung 1: Die Anweisung ist eindeutig und die Message klar: Der GNU-Programmierstil verträgt sich nicht mit dem Linux-Kernel. Im weiteren Text schlägt Torvalds jedoch auch versöhnlichere Töne an.

Listing 1:
K&R-Stil

01 int f(int x, int y, int z)
02 {
03         if (x < foo(y, z)) {
04                 haha = bar[4] + 5;
05         } else {
06                 while (z) {
07                         haha += foo(z, z);
08                         z--;
09                 }
10                 return ++x + bar();
11         }
12 }

Listing 2: GNU-Stil

01 int f (int x, int y, int z)
02 {
03     if (x < foo (y, z))
04         haha = bar[4] + 5;
05     else
06       {
07         while (z)
08           {
09             haha += foo (z, z);
10             z--;
11           }
12         return ++x + bar ();
13       }
14 }

Rekordhalter

Wie es bei einem so umfangreichen Projekt zu erwarten ist, lesen nicht alle Programmierer die Kodier-Richtlinien, geschweige denn, dass sie sie verinnerlichen. Das verdeutlicht beispielsweise die Analyse der Codezeilen-Längen. Linus Torvalds wünscht sich keine Zeilen mit mehr als 80 Zeichen. Erfahrene Programmierer kennen das: Lange Zeilen sind nicht nur am Bildschirm unübersichtlich, insbesondere die gedruckte Version ist unbrauchbar.

Und im Linux-Kernel? Mit 1992 Zeichen in einer einzigen Zeile hält die Quellcodedatei »APCI1710_Tor.c« einen traurigen Rekord. Und einen weiteren außerdem, nämlich bezüglich der Anzahl der Bedingungen innerhalb einer einzelnen If-Abfrage (siehe Abbildung 2). Was die Entwickler zu diesem Superlativ geritten hat, ist nicht überliefert, doch zur Ehrenrettung von Linus und seinen Mannen: Die Datei befindet sich noch im Staging-Zweig des Kernels.

Abbildung 2: Abschreckend: Die längste Codezeile im Kernel 2.6.32 prüft eine Konfigurationseinstellung.

Abbildung 2: Abschreckend: Die längste Codezeile im Kernel 2.6.32 prüft eine Konfigurationseinstellung.

Ansonsten hat im Linux-Kernel eine Zeile im Durchschnitt eine Länge von 28 Zeichen, obwohl es außerhalb des Staging-Zweiges durchaus einzelne Dateien gibt, etwa die Registerdefinitionen eines Ethernet-Controllers in »arch/blackfin/mach-bf537/include/mach/defBF537.h«, die mit im Schnitt 90 Zeichen pro Zeile deutlich zu lang sind. Bezüglich der Länge einer einzelnen Quellcodedatei haben die Kernelentwickler keine Einschränkungen formuliert. Die längste Datei – betrachtet man die Anzahl der Zeilen – ist mit 17 664 Zeilen die Datei »sound/pci/hda/patch_realtek.c« (siehe Tabelle 1). Sie implementiert den Realtek-HD-Audio-Codec und initialisiert Datenstrukturen zur Konfiguration für verschiedenste Hardwareplattformen, vor allem auf diversen Notebooks.

Tabelle 1: Die
längsten Dateien im Kernel 2.6.32

 

Zeilenanzahl

Datei

17664

sound/pci/hda/patch_realtek.c

15071

drivers/isdn/hardware/eicon/message.c

14344

drivers/net/tg3.c

13947

fs/nls/nls_cp949.c

12826

drivers/scsi/advansys.c

12279

drivers/net/bnx2x_main.c

12020

drivers/net/wireless/ipw2x00/ipw2200.c

11727

drivers/scsi/lpfc/lpfc_sli.c

11260

drivers/video/sis/init301.c

11165

drivers/scsi/aic7xxx_old.c

Größenwahn

Ansonsten hält die automatisch generierte Quellcodedatei »fs/nls/nls_cp949.c« mit 875 265 Zeichen den Größenrekord. Sie enthält im Wesentlichen die Kodierung des koreanischen Zeichensatzes. Im Mittel hat jede Datei aber eine Länge von 12 KByte und implementiert in 440 Zeilen rund 17 Routinen. Die zentrale Quellcodedatei »kernel/sched.c« enthält mit 435 die meisten Funktionen (siehe Tabelle 2). Man findet im Linux-Kernel auch quasi leere Dateien oder Routinen, die Dummyfunktionen haben. Wer diejenigen mit echtem Inhalt betrachtet, misst die Datei »lib/reciprocal_div.c« als kürzeste. In neun Zeilen implementiert sie die Kernel-Bibliotheksfunktion »reciprocal_div(k)«. Eine der kürzesten sinnvollen Funktionen realisiert das Schreiben auf die Admins gut bekannte Gerätedatei »/dev/null« (siehe Listing 3).

Tabelle 2: Meiste
Funktionen pro Datei im Kernel 2.6.32

 

Anzahl Funktionen

Datei

435

kernel/sched.c

343

drivers/net/niu.c

342

drivers/net/wireless/ipw2x00/ipw2200.c

315

sound/pci/hda/patch_realtek.c

260

drivers/net/tg3.c

258

drivers/net/bnx2x_main.c

250

drivers/platform/x86/thinkpad_acpi.c

232

security/selinux/hooks.c

225

fs/nfs/nfs4xdr.c

223

mm/slub.c

Listing 3: Knappes
»/dev/null«

01 static ssize_t write_null(struct file * file,
02  const char __user * buf, size_t count, loff_t *ppos)
03 {
04         return count;
05 }

Gelegenheitsprogrammierer kommen im Code aber auch Unerwartetem auf die Spur. In jedem C-Kurs lernen Neulinge: Benutzt kein Goto, es führt zu unübersichtlichem Spaghetticode und widerspricht dem Paradigma des strukturierten Programmierens. Quellcode-Stöberer hingegen finden im Kernel 2.6.32 mehr als 72 000 Gotos, also mehr als eines auf 100 Codezeilen. Doch auch hier gibt es Entwarnung: Das ist kein Zeichen eines schlechten Programmierstils, sondern eine Hommage an effiziente Code-Generierung. Richtig eingesetzt wird der Quelltext zusätzlich übersichtlicher [3].

Geheimsprache

Bedenklicher sind da eher die “besonderen” Kommentare. Wenngleich nicht offiziell oder standardisiert, hat es sich unter richtigen Hackern eingebürgert, problematische Codestellen mit den Schlüsselwörtern »XXX«, »FIXME«, »Kludge« oder zumindest als »TODO« zu kennzeichnen. Insbesondere die ersten drei weisen auf einen Hack, auf eine Behelfsmethode, eine temporäre und typischerweise nicht glücklich konzipierte Lösung hin, die einer Überarbeitung bedarf.

What the F**k?

Eigentlich würde man diese Tags nicht in einer Produktivsoftware erwarten. Im Linux-Kernel kommt »Kludge« gut 100-mal, »XXX« 2000-mal, »TODO« 3000-mal und »FIXME« 4000-mal vor (siehe Abbildung 3). Diese finden sich mehr oder minder gleichmäßig über den Quellcode verteilt.

Abbildung 3: Durch Begriffe wie »Kludge«, »XXX«, »TODO« oder »FIXME« markieren Programmierer Code, der verbesserungswürdig ist. Knapp 10 000 solcher Stellen finden sich im aktuellen Kernel.

Abbildung 3: Durch Begriffe wie »Kludge«, »XXX«, »TODO« oder »FIXME« markieren Programmierer Code, der verbesserungswürdig ist. Knapp 10 000 solcher Stellen finden sich im aktuellen Kernel.

Es gibt aber auch andere Kommentare, die sich nicht nur statistisch auswerten lassen, sondern zudem zeigen, dass auch Programmierer Emotionen haben: Worte wie »shit« (auch in den Abwandlungen »apeshit« und »bullshit«) kommen im Kernel 2.6.32 etwa 130-mal vor, »piss« und »bastard« (ebenfalls mit Abwandlungen) jeweils 17-mal und »crap« 170-mal. Vidar Holen hat die Verwendung dieser Emotionskommentare über die verschiedenen Linux-Versionen hinweg untersucht [4]. Das Ergebnis zeigen die Abbildungen 4 und 5: Auch wenn die absolute Anzahl leicht steigt, die relative Häufigkeit nimmt ab.

Abbildung 4: Entwickler sind auch vor mitunter etwas wüsten Emotionen nicht gefeit. Kernelentwickler Vidar Holen hat zusammengetragen, wie häufig Verwünschungen in den Kernelversionen vorkommen.

Abbildung 4: Entwickler sind auch vor mitunter etwas wüsten Emotionen nicht gefeit. Kernelentwickler Vidar Holen hat zusammengetragen, wie häufig Verwünschungen in den Kernelversionen vorkommen.

Abbildung 5: Vidar Holen weist aber auch darauf hin, dass das Fluchen im Verhältnis zur Code-Menge weitgehend rückläufig ist. Eine Besserung der Umgangsformen ist also in Sicht (relative Häufigkeit in Promille).

Abbildung 5: Vidar Holen weist aber auch darauf hin, dass das Fluchen im Verhältnis zur Code-Menge weitgehend rückläufig ist. Eine Besserung der Umgangsformen ist also in Sicht (relative Häufigkeit in Promille).

Die Emotionslage der Programmierer ist jedoch nicht allein an der statistischen Auswertung einzelner Wörter ablesbar. Oft sind es einzelne Sätze, wie

// People celebrate: We love our President!

in der TCP-Implementation des Netzwerkcode, die zum Nachdenken oder auch Schmunzeln anregen. Die genaue Bedeutung des vorstehenden Kommentars bleibt im Übrigen verborgen. Wahrscheinlich ist es eine Art Gedankenstütze, den folgenden Code noch einmal zu überarbeiten. Eine Liste weiterer lesenswerter Kommentare enthält Tabelle 3.

Tabelle 3:
Ausgewählte Quellcode-Kommentare im Linux-Kernel
2.6.32

 

Datei

Zeile

Kommentar

./arch/sparc/include/asm/obio.h

76

/* My Penguins are burning. Are you able to smell it? */

./net/ipv4/tcp_input.c

2675

/* People celebrate: “We love our President!” */

./drivers/spi/spi_bfin5xx.c

830

/* oh man, here there be monsters … and i dont mean the *
fluffy cute ones from pixar, i mean the kind that’ll eat * your
data, kick your dog, and love it all. do *not* try *

./drivers/scsi/wd33c93.c

65

there are lots of lurking bugs and “stupid places”. */

./drivers/scsi/qla1280.c

2121

* Now, I would love the magic decoder ring for this one, the *
header file provided by QLogic seems to be bogus or incomplete * at
best.

./drivers/ide/setup-pci.c

574

* fixme: mom, mom, they stole me the helper function

./drivers/scsi/qla1280.c

1573

* I *LOVE* this code!

./drivers/input/touchscreen/mainstone-wm97xx.c

183

/* go you big red fire engine */

./arch/m68k/kernel/head.S

1358

* [A friend and I once noted that Apple hardware engineers
should be * wacked twice each day: once when they show up at work
(as in, Whack!, * “This is for the screwy hardware we know you’re
going to design today.”), * and also at the end of the day (as in,
Whack! “I don’t know what * you designed today, but I’m sure it
wasn’t good.”). — rst]

./arch/m68k/mac/via.c

50

* eight address bits. Why can’t Apple engineers at least be *
_consistently_ lazy? – 1999-05-21 (jmt)

./arch/m68k/mac/macints.c

105

* third layer of indirection. why oh why did the apple
engineers do that?

./arch/alpha/kernel/sys_miata.c

250

case LINUX_REBOOT_CMD_RESTART: /* Who said DEC engineers have
no sense of humor? ;-) */ if (alpha_using_srm) { *(vuip)
PYXIS_RESET = 0x0000dead;

./drivers/atm/horizon.c

1992

// they will always be zero for the SAMBA. Ha! Bloody hardware
// engineers. It’ll never work.

Der Code in »arch/sparc/kernel/smp _64.c« erheitert ebenfalls (siehe Listing 4). In ihm schickt der Programmierer Pinguine ins Gefängnis (Zeile 1118), begnadet sie aber glücklicherweise ein paar Zeilen später wieder (Zeile 1136).

Listing 4: “Gehen sie
nicht über Los” fordert
»smp_64.c«

1118 printk("CPU[%d]: Sending penguins to jail...",
1119    smp_processor_id());
[...]
1136 printk("CPU[%d]: Giving pardon to "
1137    "imprisoned penguinsn",
1138    smp_processor_id());

Verkleidete Teufel

Pinguine spielen bei Linus Torvalds und im Linux-Kernel eine tragende Rolle. Typischerweise repräsentieren sie die Prozessoren beziehungsweise Prozessorkerne, weshalb der Code beim Booten – nach entsprechender Kernelkonfiguration – für jeden Prozessorkern einen Pinguin anzeigt. In der Kernelversion 2.6.29 hatte Linus seinen Tux ins Sabbatical geschickt und an seiner Stelle den tasmanischen Teufel Tuz – verkleidet als Tux – auftreten lassen: der Linux-Kernel, ein Werkzeug der Tierschützer (Abbildung 6).

Abbildung 6: Der tasmanische Teufel Tuz ersetzte im Linux-Kernel 2.6.29 den in Urlaub geschickten Tux.

Abbildung 6: Der tasmanische Teufel Tuz ersetzte im Linux-Kernel 2.6.29 den in Urlaub geschickten Tux.

Damit der Linux-Kern sowohl auf einer Armbanduhr als auch auf einem Supercomputer läuft, bringt er zwei besondere Eigenschaften mit: Skalierbarkeit und Portierbarkeit. Skalierbarkeit bedeutet, dass sich der Kernel unterschiedlichen Anforderungen exakt anpasst. Dazu lässt er sich mit Hilfe von etwa 5000 Optionen passgenau auf einen bestimmten Einsatzzweck vorbereiten. Wer etwa kein Netzwerk benötigt, spart sich die Ressourcen und konfiguriert den Kernel ohne eine solche Unterstützung.

Für eine x86-Architektur bedeutet diese Skalierbarkeit einen Unterschied im Umfang des Kernels zwischen 716 KByte und 29 MByte. Der erste Fall entspricht einem mit »make allnoconfig« erzeugten minimalen Kernel, im zweiten Fall schaltet der Entwickler alle möglichen Optionen mit dem Argument »allyesconfig« ein.

Überall zu Hause

Portierbarkeit wiederum bedeutet, dass der Kernel auf verschiedenen Hardwareplattformen lauffähig ist. Dazu gehören nicht nur unterschiedliche Prozessoren (x86, ARM, PowerPC und so weiter), sondern auch unterschiedliche Architekturen, beispielsweise 32- und 64-Bit-Systeme, Ein- und Mehrprozessorsysteme sowie Numa-Architekturen. Für Linux ist das kein wirkliches Problem. Zurzeit unterstützt der Kernel offiziell 20 Prozessortypen, daneben gibt es aber noch mehrere inoffizielle Portierungen.

Irren ist menschlich

Diese Eigenschaften hatte Linux nicht von Anfang an. Ursprünglich war das System nur für Maschinen gedacht, die mit einem x86-kompatiblen Prozessor bestückt sind. Dies und der Umstand, dass Torvalds auf einen monolithischen Systemkern und nicht auf eine Mikrokernel-Architektur gesetzt hat, brachte ihm 1992 die harsche Kritik des Betriebssystem-Professors Andrew S. Tanenbaum ein, der Linux als überflüssig, als “obsolete” bezeichnete (siehe Abbildung 7). Ein großer Irrtum, wie IT-Experten heute wissen. Die Debatte zwischen Torvalds und Tanenbaum wurde berühmt und gilt heute als Teil der Linux-Folklore [5].

Abbildung 7: Linux ist überflüssig – hier irrte Betriebssystem-Papst und Minix-Erfinder Andrew S. Tanenbaum. 18 Jahre später behauptet das kaum noch jemand.

Abbildung 7: Linux ist überflüssig – hier irrte Betriebssystem-Papst und Minix-Erfinder Andrew S. Tanenbaum. 18 Jahre später behauptet das kaum noch jemand.

Diplom in Kern-Technik

Linus Torvalds hat sich durch solche Angriffe jedoch nie beirren lassen und so läuft auf Mobiltelefonen, Supercomputern, Fernsehern, Netbooks, Flaschenrücknahme-Automaten, Armbanduhren, Navigationsgeräten und auf dem Rechner von Chefredakteur Jan Kleinert der Linux-Kernel. Wer meint, das alles schon gewusst zu haben, darf sich an dem im Kasten “Kernspalterei: Online-Quiz für Linux-Entwickler” beschriebenen Quiz versuchen und selbst prüfen, ob er die wichtigsten Inhalte aus 50 Ausgaben Kern-Technik verinnerlicht hat. (mg)

Kernspalterei:
Online-Quiz

In 50 Folgen Kern-Technik kam so manches auf den Tisch: Von Interrupt-Service-Routinen über Gerätertreiber bis hin zu Firmware-Unterstützung und Assembler-Integration reicht der Kanon der Themen. Wer prüfen will, ob er in der Linux-Kernel-Mailingliste (LKML) auch einem hitzigen Wortgefecht Torvalds, Cox und Hellwig trotzen kann, nimmt am Online-Quiz des Linux-Magazins teil.

Jeder Teilnehmer, der bis zum 28. Februar 2010 die Quizfragen beantwortet, erhält eine Urkunde. Die besten zeichnen die Kern-Technik-Autoren Kunst und Quade mit einem Ehrendiplom aus. Zum Examen geht es unter [http://linux-magazin.de/kernspalterei/]. Die Kern-Technik-Redaktion wertet alle Antworten aus und erläutert nach Einsendeschluss die korrekten Einsendungen.

Infos

[1] Kroah-Hartman, Corbet, McPherson, “Linux Kernel Development”: Linux Foundation, 2009: [http://www.linuxfoundation.org/publications/whowriteslinux.pdf].

[2] Einrückungsstil: [http://de.wikipedia.org/wiki/Einrückungsstil].

[3] Eva-Katharina Kunst, Jürgen Quade, “Kern-Technik”, Folge 3: Linux-Magazin 10/03, S. 81

[4] Vidar Holen, “Linux kernel swear counts”:[http://vidarholen.net/contents/wordcount/]

[5] Andrew S. Tanenbaum, “Linux is obsolete”:[http://www.educ.umu.se/~bjorn/mhonarc-files/obsolete/msg00000.html]

Die Autoren

Eva-Katharina Kunst, Journalistin, und Jürgen Quade, Professor an der Hochschule Niederrhein, sind seit den Anfängen von Linux Fans von Open Source. Unter dem Titel “Linux Treiber entwickeln” haben sie zusammen ein Buch zum Kernel 2.6 veröffentlicht.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben