Im Katalog suchen
Linux-Gerätetreiber, 2.Auflage

Linux-Gerätetreiber, 2. Auflage

Alessandro Rubini & Jonathan Corbet
2. Auflage April 2002
ISBN 3-89721-138-6
608 Seiten, EUR 44,-


Inhalt
Vorwort
Alessandros Einführung
Jons Einführung
Die Zielgruppe dieses Buches
Organisation des Buches
Hintergrundinformationen
Weitere Informationsquellen
Online-Versionen und Lizenz
Konventionen in diesem Buch
Danksagungen
1. Eine Einführung in den Linux-Kernel
Die Rolle des Treiber-Programmierers
Organisation des Kernels
Klassen von Geräten und Modulen
Sicherheitsfragen
Versionsnumerierung
Lizenzbedingungen
Selbst in der Kernel-Entwicklergemeinde tätig werden
Übersicht über dieses Buch
2. Module erstellen und starten
Module versus Applikationen
Kompilieren und Laden
Versionsabhängigkeit
Plattformabhängigkeiten
Die Symboltabelle des Kernels
Initialisierung und Beendigung
Fehlerbehandlung in init_module
Verwendungszähler
Entladen
Explizite Initialisierungs- und Aufräumfunktionen
Ressourcen verwenden
I/O-Ports und I/O-Speicher
Ressourcen-Allokation in Linux 2.4
Automatische und manuelle Konfiguration
Im User-Space arbeiten
Abwärtskompatibilität
Änderungen in der Ressourcen-Verwaltung
Kompilieren auf Multiprozessor-Systemen
Symbole in Linux 2.0 exportieren
Modul-Konfigurationsparameter
Schnellreferenz
3. Zeichen-Treiber
Das Design von scull
Major- und Minor-Nummern
Dynamische Zuweisung von Major-Nummern
Einen Treiber aus dem System entfernen
dev_t und kdev_t
Datei-Operationen
Die Struktur file
open und release
Die Methode open
Die Methode release
Die Verwendung von Speicher in scull
Ein kurze Einführung in Race Conditions
read und write
Die neuen Geräte ausprobieren
Das Device-Dateisystem
devfs in der Praxis
Portabilitätsprobleme mit devfs
Abwärtskompatibilität
Änderungen in der Struktur für die Dateioperationen
Der Verwendungszähler von Modulen
Änderungen in der Unterstützung von Semaphoren
Änderungen im Zugriff auf den User-Space
Schnellreferenz
4. Debugging-Techniken
Debugging mit Ausgaben
printk
Wie Meldungen protokolliert werden
Die Meldungen ein- und ausschalten
Debugging mit Abfragen
Das /proc-Dateisystem verwenden
Die Methode ioctl
Debugging durch Beobachten
Debuggen von Systemfehlern
Oops-Meldungen
Das System bleibt stehen
Debugger und verwandte Werkzeuge
gdb verwenden
Der Kernel-Debugger kdb
Der Integrated Kernel Debugger-Patch
Der kgdb-Patch
Kernel Crash Dump Analyzer
Die User-Modus-Linux-Portierung
Das Linux Trace Toolkit
Dynamic Probes
5. Fortgeschrittene Operationen in Zeichen-Treibern
ioctl
Die ioctl-Befehle auswählen
Der Rückgabewert
Die vordefinierten Befehle
Das Argument von ioctl benutzen
Capabilities und eingeschränkte Operationen
Die Implementation der ioctl-Befehle
Geräte ohne ioctl steuern
Blockierende I/O
Schlafen gehen und wieder aufwachen
Ein genauerer Blick auf Warteschlangen
Reentranten Code schreiben
Blockierende und nicht-blockierende Operationen
Eine Beispiel-Implementation: scullpipe
poll und select
Interaktion mit read und write
Die zugrundeliegende Datenstruktur
Asynchrone Benachrichtigung
Die Sicht des Treibers
Ein Gerät positionieren
Die Implementation von llseek
Zugriffskontrolle auf Gerätedateien
Nur einmal zu öffnende Geräte
Ein weiterer Abstecher zu den Race Conditions
Den Zugriff auf jeweils einen Benutzer gleichzeitig beschränken
Blockieren im open-Aufruf als Alternative zu EBUSY
Kopieren des Gerätes beim Öffnen
Abwärtskompatibilität
Warteschlangen in Linux 2.2 und 2.0
Asynchrone Benachrichtigung
Die Methode fsync
Zugriff auf den User-Space in Linux 2.0
Capabilities in 2.0
Die select-Methode in Linux 2.0
Positionieren in Linux 2.0
2.0 und SMP
Schnellreferenz
6. Der Lauf der Zeit
Zeit-Intervalle im Kernel
Prozessorspezifische Register
Die aktuelle Zeit ermitteln
Die Ausführung verzögern
Lange Verzögerungen
Kurze Verzögerungen
Task-Schlangen
Wie Task-Schlangen aufgebaut sind
Wie Task-Schlangen ausgeführt werden
Vordefinierte Task-Schlangen
Eigene Task-Schlangen anlegen
Tasklets
Kernel-Timer
Abwärtskompatibilität
Schnellreferenz
7. Speicher ergattern
Die ganze Wahrheit über kmalloc
Das Argument flags
Das Argument size
Lookaside-Caches
Ein scull mit Slab-Caches: scullc
get_ free_ page und Freunde
Ein scull, das ganze Seiten verwendet: scullp
vmalloc und Freunde
Ein scull mit virtuellen Adressen: scullv
Allozierung während des Bootens
Einen dedizierten Puffer beim Booten bekommen
Der bigphysarea-Patch
Reservieren von hohen RAM-Adressen
Abwärtskompatibilität
Schnellreferenz
8. Hardware-Verwaltung
I/O-Ports und I/O-Speicher
I/O-Register und konventioneller Speicher
I/O-Ports benutzen
String-Operationen
Wartende I/O
Plattformabhängigkeiten
Digitale I/O-Ports verwenden
Grundlagen des Parallel-Ports
Ein Beispiel-Treiber
I/O-Speicher verwenden
Direkt abgebildeter Speicher
short für I/O-Speicher verwenden
Von der Software abgebildeter I/O-Speicher
ISA-Speicher unter 1 MByte
isa_readb und verwandte Funktionen
Nach ISA-Speicher suchen
Abwärtskompatibilität
Schnellreferenz
9. Interrupt-Handler
Überblick über die Interrupt-Steuerung
Den Parallel-Port vorbereiten
Einen Interrupt-Handler installieren
Die /proc-Schnittstelle
Automatische Erkennung der IRQ-Nummer
Schnelle und langsame Handler
Einen Handler implementieren
Argumente verwenden
Interrupts ein- und ausschalten
Tasklets und untere Hälften
Tasklets
Das Design der unteren Hälften
Eine untere Hälfte (BH) schreiben
Gemeinsames Nutzen von Interrupts
Einen gemeinsam genutzten Handler installieren
Aufrufen des Handlers
Die /proc-Schnittstelle
Interrupt-gesteuerte I/O
Race Conditions
Ring-Puffer verwenden
Spinlocks verwenden
Sperrvariablen verwenden
Schlafen gehen ohne Race Conditions
Abwärtskompatibilität
Unterschiede im 2.2-Kernel
Weitere Unterschiede im 2.0-Kernel
Schnellreferenz
10. Überlegte Verwendung von Datentypen
Verwendung der Standard-C-Typen
Datenelementen eine explizite Größe zuweisen
Schnittstellenspezifische Typen
Andere Portabilitätsfragen
Zeit-Intervalle
Seitengröße
Byte-Reihenfolge
Datenausrichtung
Verkettete Listen
Schnellreferenz
11. kmod und fortgeschrittene Modularisierung
Module bei Bedarf laden
Module im Kernel anfordern
Die Seite des User-Space
Sicherheitsfragen beim Laden von Modulen
Ein Beispiel für das Laden von Modulen
User Mode-Hilfsprogramme ausführen
Kommunikation zwischen Modulen
Versionskontrolle in Modulen
Versionsunterstützung in Modulen verwenden
Exportieren von Symbolen mit Versionsinformationen
Abwärtskompatibilität
Schnellreferenz
12. Das Laden von Block-Treibern
Den Treiber registrieren
Die Header-Datei blk.h
Anfragen bearbeiten: Eine einfache Einführung
Die Anfrage-Warteschlange
Die eigentliche Datenübertragung durchführen
Anfragen bearbeiten: Das Ganze noch einmal genauer
Die I/O-Anfrage-Warteschlange
Cluster-Anfragen
Block-Treiber mit mehreren Warteschlangen
Ohne die Anfrage-Warteschlange arbeiten
Wie das Einhängen und Aushängen funktioniert
Die ioctl-Methode
Herausnehmbare Geräte
check_media_change
Revalidierung
Zusätzliche Vorsichtsmaßnahmen
Partitionierbare Geräte
Die generische Festplatte
Partitionserkennung
Partitionserkennung mit initrd
Die Geräte-Methoden von spull
Interrupt-gesteuerte Block-Treiber
Abwärtskompatibilität
Schnellreferenz
13. mmap und DMA
Speicherverwaltung in Linux
Adreßtypen
Hoher und niedriger Speicher
Die Speichertabelle und struct page
Seitentabellen
Virtuelle Speicherbereiche (Virtual Memory Areas)
Die Geräteoperation mmap
remap_page_range verwenden
Eine einfache Implementation
VMA-Operationen hinzufügen
Speicher mit nopage einblenden
Umblenden bestimmter I/O-Regionen
RAM umblenden
Umblenden virtueller Adressen
Die kiobuf-Schnittstelle
Die kiobuf-Struktur
Einblenden von User-Space-Buffern und rohe I/O
Direct Memory Access und Bus Mastering
Überblick über eine DMA-Datenübertragung
Allozieren der DMA-Puffer
Bus-Adressen
DMA auf dem PCI-Bus
DMA bei ISA-Geräten
Abwärtskompatibilität
Änderungen in der Speicherverwaltung
DMA-Änderungen
Schnellreferenz
14. Netzwerk-Treiber
Das Design von snull
Zuweisen von IP-Nummern
Die physikalische Übertragung der Pakete
Mit dem Kernel verbinden
Module laden
Jedes Gerät initialisieren
Entladen von Modulen
Modularisierte und nicht-modularisierte Treiber
Die Struktur net_device im Detail
Der sichtbare Anfang
Die versteckten Felder
Öffnen und Schließen
Paket-Übertragung
Steuerung der Nebenläufigkeit von Übertragungen
Übertragungs-Timeouts
Paket-Empfang
Der Interrupt-Handler
Änderungen im Verbindungszustand
Die Socket-Buffer
Die wichtigen Felder
Funktionen, die auf Socket-Buffern operieren
MAC-Adreßauflösung
ARP mit Ethernet verwenden
Überschreiben von ARP
Nicht-Ethernet-Header
Eigene ioctl-Befehle
Statistische Informationen
Multicasting
Kernel-Unterstützung für Multicasting
Eine typische Implementierung
Abwärtskompatibilität
Unterschiede in Linux 2.2
Weitere Unterschiede in Linux 2.0
Suchen und HAVE_DEVLIST
Schnellreferenz
15. Ein Überblick über die Peripherie-Busse
Die PCI-Schnittstelle
PCI-Adressierung
Hochfahren des Systems
Konfigurationsregister und Initialisierung
Zugriff auf den Konfigurationsraum
Zugriff auf die I/O- und Speicherräume
PCI-Interrupts
Hot-Pluggable-Geräte
Hardware-Abstraktionen
Ein Blick zurück: ISA
Hardware-Ressourcen
ISA-Programmierung
Die “Plug-and-Play”-Spezifikation
PC/104 und PC/104+
Andere PC-Busse
MCA
EISA
VLB
SBus
NuBus
Externe Bus-Systeme
USB
Einen USB-Treiber schreiben
Abwärtskompatibilität
Schnellreferenz
16. Der physikalische Aufbau der Kernel-Quellen
Booten des Kernels
Vor dem Booten
Der init-Prozeß
Das Verzeichnis kernel
Das Verzeichnis fs
Das Verzeichnis mm
Das Verzeichnis net
ipc und lib
include und arch
Treiber
drivers/char
drivers/block
drivers/ide
drivers/md
drivers/cdrom
drivers/scsi
drivers/net
drivers/sound
drivers/video
drivers/input
drivers/media
Bus-spezifische Verzeichnisse
Plattform-spezifische Verzeichnisse
Andere Unterverzeichnisse
Bibliographie
Bücher zum Linux-Kernel
Unix-Design und Interna
Abbildungsverzeichnis
1-1. Ein Blick auf die Aufgabenblöcke des Kernels
2-1. Ein Modul zum Kernel linken
2-2. Aufeinanderstapeln von Treibermodulen für den Parallel-Port
3-1. Das Layout eines scull-Geräts
3-2. Die Argumente von read
5-1. Warteschlangen in Linux 2.4
5-2. Die Datenstrukturen von poll
6-1. Zeitlicher Ablauf bei der Verwendung von Task-Schlangen
8-1. Die Pinbelegung des Parallel-Ports
10-1. Die Datenstruktur list_head
12-1. Registrieren eines Block-Gerätetreibers
12-2. Puffer in der I/O-Anfrage-Warteschlange
13-1. Adreßtypen in Linux
13-2. Die drei Ebenen der Linux-Seitentabellen
14-1. Wie ein Host seine Schnittstellen sieht
15-1. Layout eines typischen PCI-Systems
15-2. Die standardisierten PCI-Konfigurationsregister
15-3. Für USB-Eingabegeräte verwendete Module