Übersicht über dieses Buch

An dieser Stelle betreten wir die Welt der Kernel-Programmierung. Kapitel 2 führt das Thema Modularisierung ein, erklärt die dahinterstehenden Geheimnisse und zeigt den Code zum Starten von Modulen. Kapitel 3 erläutert Zeichen-Treiber und enthält den vollständigen Code eines speicherbasierten Gerätetreibers, der zum Spaß gelesen und geschrieben werden kann. Die Verwendung von Speicher als Hardware-Basis erlaubt es jedem, die Beispielprogramme laufen zu lassen, ohne spezielle Hardware beschaffen zu müssen.

Für jeden Programmierer sind Debugging-Techniken äußerst wichtig; sie werden in Kapitel 4 eingeführt. Mit unseren neu erworbenen Debugging-Fähigkeiten gehen wir dann auf fortgeschrittenere Merkmale von Zeichen-Treibern ein, darunter auf blockierende Operationen, die Verwendung von select und den wichtigen ioctl-Aufruf; diese Themen sind der Inhalt von Kapitel 5.

Bevor wir zur Verwaltung von Hardware kommen, werden wir noch einige weitere Software-Schnittstellen des Kernels auseinandernehmen: Kapitel 6 erklärt, wie Zeit im Kernel verwaltet wird, und Kapitel 7 beschreibt die Anforderung und Vergabe von Speicher.

Anschließend konzentrieren wir uns auf die Hardware: Kapitel 8 beschreibt die Verwaltung von I/O-Ports und Speicher-Puffern, die sich im Gerät befinden; danach gehen wir dann in Kapitel 9 zur Behandlung von Interrupts über. Unglücklicherweise wird nicht jeder in der Lage sein, die Beispielprogramme aus diesen Kapiteln auszuprobieren, weil ein wenig Hardware-Unterstützung notwendig ist, um die Software-Schnittstelle zu den Interrupts zu testen. Wir haben uns bemüht, die benötigte Hardware so gering wie möglich zu halten, aber trotzdem werden Sie zum Lötkolben greifen müssen, um Ihr “Gerät” zu bauen. Das Gerät ist ein einziges Stück Draht, das in den parallelen Port gesteckt wird. Wir hoffen also, daß das kein Problem ist.

Kapitel 10 enthält einige weitere Hinweise zum Schreiben von Kernel-Software und zu Portabilitätsfragen.

Im zweiten Teil dieses Buches werden wir etwas ambitionierter, weswegen Kapitel 11 noch einmal auf die Modularisierung zu sprechen kommt und dabei tiefer in das Thema einsteigt.

Kapitel 12 beschreibt dann, wie Block-Treiber implementiert werden, und erläutert die Punkte, an denen sich diese von Zeichen-Treibern unterscheiden. Anschließend erklärt Kapitel 13, was wir bei unserer bisherigen Behandlung der Speicherverwaltung ausgelassen haben: mmap und DMA. Nach diesen Kapiteln sollten Sie alles über Zeichen- und Block-Treiber wissen.

Als nächstes folgt die dritte große Klasse der Treiber: In Kapitel 14 besprechen wir detailliert, wie Netzwerk-Interfaces aussehen, und zerlegen den Code eines Beispiel-Netzwerktreibers.

Einige wenige Merkmale von Gerätetreibern hängen direkt von dem Bus ab, an dem das Peripherie-Gerät hängt, daher enthält Kapitel 15 einen Überblick über die heutzutage gängigsten Bus-Implementationen, wobei besonders auf die PCI-Unterstützung im Kernel eingegangen wird.

Schließlich ist Kapitel 16 eine Art Rundreise durch die Kernel-Quellen. Dieses Kapitel ist als Ausgangspunkt für Leute gedacht, die das allgemeine Design verstehen wollen, aber die sich vielleicht durch den riesigen Berg an Quellcode, aus dem Linux besteht, abgeschreckt fühlen.