Aus Linux-Magazin 10/2016

Kernel- und Treiberprogrammierung mit dem Linux-Kernel – Folge 88

© psdesign1, Fotolia

Mit Kernel 4.8 stellt Linus Torvalds die Kerneldokumentation auf die leichtgewichtige Markup-Sprache Restructuredtext um. Das Ganze ist kein fauler Kompromiss, sondern soll bei gleichem oder gar geringerem Dokumentationsaufwand im Quelltext bessere Ergebnisse liefern.

Wer Gedanken aller Art zu Papier bringen will, darf dies natürlich mit Libre Office oder einer Notiz-Software tun. Die Deklaration einer Datenstruktur aus einer Headerdatei auf die gleiche Weise dynamisch zu einer Entwickler-Dokumentation zu verfassen, wäre naheliegend ein holpriger Weg. Ungleich schneller führen wenige Zeilen Skriptcode zum Ziel, die klassische Ascii-Textdateien analysieren, Texte extrahieren und in möglichst geeigneter Weise interpretieren.

Um die Vorteile der Textverarbeitung mit den Vorteilen der Textdateien zu verbinden, sind die Markup-Sprachen (ML) wie HTML oder Docbook aufgekommen. Um explizit eine Dokumentation zu verfassen, schreibt der Entwickler zumeist mit einem Ascii-Editor in ein neues Ausgangsdokument, das er dann mit Hilfe eines Formatierprogramms in ein ansehnliches Ausgabeformat wie HTML oder PDF bringt (Abbildung 1) – und dieser Vorgang lässt sich leicht mit einem Skript automatisieren.

Abbildung 1: Das Prinzip ist einfach: Textbasierte Ausgangsdokumente lassen sich über Formatiersoftware in beliebige Ausgabeformate übersetzen.

Abbildung 1: Das Prinzip ist einfach: Textbasierte Ausgangsdokumente lassen sich über Formatiersoftware in beliebige Ausgabeformate übersetzen.

So ist zu erklären, dass im Linux-Quellcode ein Informationsschatz von rund 5500 Dateien entweder als Plaintext-Dateien oder im Docbook-Format schlummert. Hinzu kommt ein Satz von Skripten – allen voran das Skript »kernel-doc« –, die in der Theorie aus einem Teil dieser Dateien in Kombination mit den C- und H-Dateien des Kernel-Quellcods eine HTML- oder PDF-Doku erzeugen.

In der Praxis funktioniert das allerdings nicht wie erhofft. Wer im Linux-Quellcode-Verzeichnis die Kommandos »make htmldocs« oder »make pdfdocs« tippt, produziert statt informativer Dokumente Fehlermeldungen. Denn zum Erzeugen der Dokumente bedarf es eines größeren Sets von Werkzeugen, die installiert sein wollen und die selten sofort zueinander passen. Hinzu kommt, dass sowohl die Einarbeitung in das Docbook-Format als auch das Interpretieren von Syntaxfehler-Meldungen als aufwändig gelten.

Up and down

Die Misere ist den Entwicklern natürlich nicht verborgen geblieben, weshalb für den Linux-Kernel seit Anfang des Jahres der Vorschlag konkret im Raum steht, leichtgewichtiges Markup, Markdown genannt, als Dokumentationsformat einzuführen [1]. Markdown-Sprachen sollen das Anfertigen einer Dokumentation signifikant erleichtern.

Dazu ist innerhalb des Ascii-Textes keine extra Auszeichnung mit Tags wie »<Section>« notwendig. Vielmehr erkennt die Analysesoftware an einem vorangestelltem »#« eine Überschrift und formatiert diese bei der Umsetzung in HTML oder PDF ansehnlich. Wer in der Vergangenheit also seine Doku mit normalem Ascii geschrieben hat, kann mit geringem Aufwand ein professionelles HTML, PDF, Epub oder auch eine Präsentation generieren.

In guter Open-Source-Manier hatten Entwickler für den Linux-Kernel nicht nur die Variante Asciidoc vorgeschlagen, sondern gleich erste Versionen geeigneter Formatiersoftware geliefert. Andere Entwickler brachten wiederum eine Umstellung auf ein in der Python-Welt produktiv eingesetztes Format namens Restructuredtext und das zugehörige Formatierungswerkzeug Sphinx ins Spiel.

Kind der Schlange

Auch Restructuredtext [2] ist eine leichtgewichtige, vereinfachte Auszeichnungssprache. Ihr gelingt durch Vermeiden langer Tags ein so genanntes Pretty-Printing unter Beibehaltung der Lesbarkeit des Ausgangsdokuments. Listing 1 zeigt beispielhaft ein solches Ausgangsdokument, Abbildung 2 die Umsetzung mit Hilfe von »rst2pdf« in ein PDF.

Listing 1

linuxmag.rst – Restructuredtext im Beispiel

01 ================
02  Linux Magazin
03 ================
04 ----------------
05  Kern-Technik 88
06 ----------------
07
08 .. |date| date::
09
10 Absätze werden durch Leerzeilen voneinander
11 getrennt. Einzelne Worte lassen sich leicht
12 **fett** oder *kursiv* auszeichnen.
13
14 Kapitel 1 Historie
15 ==================
16
17 Kapitel 1.1 Früher war alles ...
18 -----------------------------------
19
20 Aufzählungen werden durch "``-``" eingeleitet,
21 automatisch mummerierte Aufzählungen durch "``#.``".
22
23 - Gestern
24 - Datum heute: |date|
25
26 Jetzt die nummierte Liste:
27
28 #. Reine Ascii-Dokumentation
29 #. Markup
30 #. Markdown
31
32 Direktiven werden durch "``..``" eingeleitet.
33 Der zugehörige Text wird eingerückt.
34
35 .. code:: C
36
37   int main()
38   {
39         printf("Hello World\n");
40         return 0;
41   }
42
43 Durch die Direktive ``image::`` werden Bilder eingebunden.
44 Weitere Direktiven sind unter
45 http://docutils.sourceforge.net/docs/ref/rst/directives.html
46 beschrieben.
47
48 .. image:: picture.jpg
49    :scale: 15 %
50    :align: center
Abbildung 2: Pretty-Printing mit dem im Kernel eingesetzten Tool »rst2pdf«.

Abbildung 2: Pretty-Printing mit dem im Kernel eingesetzten Tool »rst2pdf«.

Restructuredtext erkennt einen Dokumenttitel daran, dass dieser mit Gleichheitszeichen über- und unterstrichen ist. Kapitelüberschriften sind demgegenüber nur unterstrichen, für die erste Indirektion mit Gleichheitszeichen, für die zweite mit Bindestrichen. Die Elemente einzelner Listen leiten Bindestriche (Minuszeichen) ein. Nummerierte Aufzählungen entstehen per ».#« . Innerhalb eines Textes lässt sich Kursivdruck durch vor- und nachgestellte »*« erreichen, bei Fettdruck verwendet der Programmierer zwei Sterne (»**« ).

Neben diesen statischen Auszeichnungen kennt Restructuredtext so genannte Direktiven, um Texte dynamisch und automatisiert umzusetzen beziehungsweise für komplexere Auszeichnungen. Direktiven werden grundsätzlich durch zwei Punkte (»..« ) eingeleitet. Danach kommt der Direktiventyp, den Doppelpunkte (»: :« ) einrahmen. Einige Direktiven lassen sich per Option parametrieren (Unterdirektive). Optionen sind mit Doppelpunkten umschlossen, sie folgen – eingerückt – direkt nach der Direktivenzeile.

Sphinx

Mit Sphinx [3] lassen sich im Restructuredtext-Format vorliegende Dokumente in diverse Ausgabeformate umwandeln. Wer als Ausgabeformat HTML wählt, dem erzeugt Sphinx in der Defaulteinstellung eine komplette dynamische Website mit Stylesheet- und Javascript-Dateien. Diese besitzt nicht nur ein Inhaltsverzeichnis, sondern auch eine Suchfunktion. Damit Sphinx das kann, benötigt es eine Konfiguration, die es in einer Datei namens »conf.py« erwartet.

Sinnvoll ist es, für die Dokumentation ein eigenes Verzeichnis anzulegen und innerhalb dieses Verzeichnisses das Python-Skript »sphinx-quickstart« aufzurufen. Dabei sind Fragen wie die nach dem Projektnamen und einer Versionsnummer zu beantworten. Sphinx schreibt auf Basis der Angaben sowohl die Datei »conf.py« als auch ein Makefile. Ein »make html« erzeugt dann die HTML-Version der Dokumentation. Andere Generierungs-Targets bekommt zu sehen, wer »make« ohne Argumente aufruft.

Asciidoc vs. Sphinx

Jonathan Corbet – der Maintainer der Linux-Dokumentation und Betreiber der unter Kernelentwicklern sehr beliebten Webseite Lwn.net – kündigte an, die für den Kernel vorhandene Asciidoc-Lösung [4] einer potenziell besseren, aber eben noch nicht existenten Sphinx-Lösung vorzuziehen. Dies motivierte offenbar die Sphinx-Entwickler, denn innerhalb kürzester Zeit präsentierten sie eine gleichwertige Lösung, die Corbet nach einer Diskussion akzeptierte und die zur Übernahme in Kernel 4.8 eingereicht wurde. Linus Torvalds übernahm das Sphinx-basierte Dokumentationssystem bereits für die nächste Kernelversion.

Wer also in der kommenden Kernelversion 4.8 (unter Ubuntu beispielsweise per »apt-get install python-sphinx rst2pdf« ) die Pakete »python-sphinx« und »rst2pdf« installiert und danach im Quellcodeverzeichnis des Linux-Kernels »make htmldocs« aufruft, setzt Sphinx in Marsch, das seinerseits bei den bisher noch nicht umgestellten Docbook-Dokumenten die alte Werkzeugkette bemüht.

Sphinx legt die generierten Dokumente in dem Verzeichnis »Documentations/output/« ab. Das Tool erstellt eine komplette Website inklusive Crossreferenz und Suchfunktion, deren Aussehen der Entwickler über Stylesheets anpassen kann (Abbildung 3).

Abbildung 3: Kernel-doc und Sphinx erzeugen eine komplette Kerneldokumentations-Website.

Abbildung 3: Kernel-doc und Sphinx erzeugen eine komplette Kerneldokumentations-Website.

Trügerische Ähnlichkeit

Für die Crossreferenz und fürs Erkennen der Dokumentation im Linux-Quellcode müssen die Programmierer Funktionen und Datenstrukturen über spezielle Kommentare nach einem vorgegebenen Standard [5] beschreiben. Diese Technik ist den meisten Entwicklern durch Doxygen bereits bekannt, wobei das Linux-Format nur eine – wie es offiziell heißt – trügerische Ähnlichkeit zu Doxygen besitzt. Das Kommentierungsformat ist deutlich älter als Restructuredtext. Bisher hatte das über 3000 Zeilen lange Perl-Skript »kernel-doc« die Kommentare in ein Docbook-XML-File umgesetzt. Mit Kernel 4.8 tritt ein Python-Pendant an dessen Stelle beziehungsweise ergänzt das Perl-Skript zunächst einmal.

Listing 2

lib/vsprintf.c – Kommentierung der Funktion vsprintf()

01 /**
02  * vsprintf - Format a string and place it in a buffer
03  * @buf: The buffer to place the result into
04  * @fmt: The format string to use
05  * @args: Arguments for the format string
06  *
07  * The function returns the number of characters written
08  * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
09  * buffer overflows.
10  *
11  * If you're not already dealing with a va_list consider using sprintf().
12  *
13  * See the vsnprintf() documentation for format string extensions over C99.
14  */
15 int vsprintf(char *buf, const char *fmt, va_list args)
16 {
17         return vsnprintf(buf, INT_MAX, fmt, args);
18 }
19 EXPORT_SYMBOL(vsprintf);

Damit »kernel-doc« und später das Python-Pendant die Kommentare berücksichtigt, müssen diese mit »/**« beginnen. Kernel-doc wertet die Kommentare bis zum schließenden »*/« aus. Dazwischenliegende Kommentarzeilen beginnen wie üblich mit » *« . Es sind zwei Arten von derartigen Kommentaren zu unterscheiden: Die freien Kommentare und die Beschreibung von Funktionen, Datentypen oder Aufzählungstypen (Enum). Bei Letzteren erfolgt die Kernel-doc-Kommentierung im Quellcode direkt oberhalb der Funktions- oder Typbeschreibung. Freie Kommentare dürfen dagegen irgendwo in einer Quellcodedatei auftauchen (Listing 2). Die Schlüsselzeichen, auf die »kernel-doc« reagiert, sind in Tabelle 1 gelistet.

Tabelle 1

Kernel-doc-Schlüsselwörter

Schlüsselzeichen Bedeutung
/ Beginn eines Kernel-doc-Kommentars
*/ Ende eines Kernel-doc-Kommentars
@ Name und Beschreibung eines Funktionsparameters
% Name und Beschreibung einer Konstanten
$ Name und Beschreibung einer Umgebungsvariablen
& Name und Beschreibung einer Datenstruktur, eines Datenstrukturelementes, einer Aufzählung oder eines Typedef

Kernel-doc-Kommentare sollen einer vorgegebenen Struktur entsprechen, die aus den Sektionen Elementname, Parameter- sowie Aufgabenbeschreibung, Return und Beispiel besteht. Eine Sektion leitet eine leere Kommentarzeile » *« oder ein Schlüsselwort ein. Die einzelnen Abschnitte sind optional, nur der Elementname nicht (Abbildung 4).

Abbildung 4: Die Struktur eines Kernel-doc-Kommentars, die sich durch mit Doppelpunkt endende Schlüsselwörter ergibt.

Abbildung 4: Die Struktur eines Kernel-doc-Kommentars, die sich durch mit Doppelpunkt endende Schlüsselwörter ergibt.

Entwickler, die mit Hilfe von Kernel-doc eine Datenstruktur, ein Union, eine Aufzählung oder ein Typedef beschreiben, müssen dem Elementnamen das Schlüsselwort »struct« , »union« , »enum« beziehungsweise »typedef« voranstellen. Ineinandergeschachtelte Deklarationen unterstützt Kernel-doc nicht. Bei sehr umfangreichen Datenstrukturen lassen sich einzelne Elemente auch innerhalb der Datenstruktur beschreiben, wie in Listing 3 zu sehen.

Listing 3

Beispiel für die Beschreibung von Datenstrukturen

01 /**
02  * struct my_little_struct - short description
03  * @a: member named a
04  * @b: member named b
05  *
06  * Longer description
07  */
08 struct my_struct {
09     int a;
10     int b;
11 /* private: */
12     int c;
13 };
14
15 /**
16  * struct my_big_struct - short description
17  * @a: first member
18  * @b: second member
19  *
20  * Longer description
21  */
22 struct my_struct {
23     int first;
24     int second;
25     /**
26      * @third: This is a longer description of third
27      *
28      * You can use paragraphs to describe arguments
29      * using this method.
30      */
31     int third;
32 };

Neue Direktive

Um in die eigene Dokumentation Ausschnitte aus H- und C-Dateien des Linux-Kernel-Quellcods zu übernehmen, haben die Entwickler dem Restructuredtext-Format die Kernel-spezifische neue Direktive »kernel-doc« beigebracht (Listing 4). Der Parameter, welcher der Direktive folgt, referenziert mit einem regulären Ausdruck eine oder auch mehrere Quellcodedateien.

Listing 4

Die neue kernel-doc-Direktive wählt Kommentare aus

01 The following describes the exported functions of
02 file ``bitmap.c``.
03
04 .. kernel-doc:: lib/bitmap.c
05    :export:
06
07 You can use the following functions only inside
08 the module.
09
10 .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
11    :internal:
12
13 Just one specific description ...
14
15 .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
16    :doc: High Definition Audio over HDMI and Display Port

Die Unterdirektive »:option:« legt den Ausschnitt innerhalb der Dateien fest. »:option:« kann dabei die Werte »export« , »:internal:« , »:doc:« oder »:functions:« annehmen. Bei »:export:« nimmt »kernel-doc« die Kommentierungen der globalen Funktionen auf, also die über das Makro »EXPORT_SYMBOL« beziehungsweise »EXPORT_SYMBOL_GPL« exportierten Funktionen. Demgegenüber fügt »:internal:« die Beschreibung der Funktionen ein, die nicht global beziehungsweise nicht über die beiden Makros exportiert werden.

Die Unterdirektive »:doc:« fügt schließlich die in den Kommentaren befindlichen Beschreibungen der Funktionen ein, die »kernel-doc« nicht über den angegebenen Titel gefunden hat. Der Titel darf nicht in Anführungszeichen stehen, aber Leerzeichen enthalten. Er muss exakt so geschrieben sein wie in der Quellcodedatei. »:functions:« schließlich wertet den Kommentar zur angegebenen Funktion aus und baut ihn in den Text ein.

Die neue Direktive findet sich in der Vorabversion zum Kernel 4.8 vor allem in der Dokumentation der Grafiksubsysteme wie »v4l« , »gpu« oder »dvb« . Die Einstiegsseite in die aktuelle HTML-Version zeigt Abbildung 5.

Abbildung 5: So sieht die Einstiegsseite in die neue Linux-Dokumentation aus.

Abbildung 5: So sieht die Einstiegsseite in die neue Linux-Dokumentation aus.

Insgesamt verwenden rund acht Prozent der aktuell vorhandenen Dokumentation bereits Restructuredtext, erkennbar an der Datei-Erweiterung »rst« . Geduld wird also nötig sein, bis die letzte Docbook-Datei verschwunden und die Umstellung somit abgeschlossen sein wird.

Für alle

Die Umstellung der Kernel-Dokumentation auf einen Markdown-Dialekt gibt dem Thema Software-Dokumentation neuen Schwung. Weil von der Linux-Entwicklung eine gewisse Vorbildwirkung ausgeht, steht zu erwarten, dass auch andere Projekte den Einsatz von Restructuredtext und Sphinx prüfen werden. Grundsätzlich könnte jede Software-Entwicklung – Open wie Closed Source – von einer vereinfachten Dokumentationserstellung auf Basis eines Markdown-Dialekts profitieren.

Für reine Kernel- und Treiberprogrammierer ändert sich dabei nichts. Sie kommentieren wie eh und je den Quellcode gemäß der Torvalds’schen »kernel-doc« -Richtlinie – nur die entstehende Dokumentation schaut besser aus. (jk)

88

Infos

  1. Jani Nikula, “Kernel documentation with Sphinx, part 1”: http://lwn.net/Articles/692704/
  2. Restructuredtext: http://docutils.sourceforge.net/rst.html
  3. Sphinx: http://www.sphinx-doc.org/en/stable/
  4. Asciidoc: https://de.wikipedia.org/wiki/AsciiDoc
  5. Jani Nikula, “Kernel documentation with Sphinx, part 2”: http://lwn.net/Articles/692705/

Der Autor

Eva-Katharina Kunst ist seit den Anfängen von Linux Fan von Open Source. Jürgen Quade, Professor an der Hochschule Niederrhein, hat mit “Embedded Linux lernen mit dem Raspberry Pi” letztes Jahr sein drittes Linux-Buch veröffentlicht. Das gemeinsame Buch “Linux-Treiber entwickeln” ist jüngst in vierter Auflage erschienen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
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