Vorweg

Dies ist nicht notwendig für Einsteiger, es ist Hintergrundwissen über die Inhalte des mysteriösen /dev Verzeichnisbaums. Wer interessiert ist, lese weiter. Wer es nicht ist, mache lieber etwas sinnvolles, wie z.B. mit dem KDE THEME MANAGER rumspielen und das MATRIX Theme ausprobieren...

"Everything is a file."

Dieses UNIX-Paradigma ist schon etliche Jahre alt (so etwa 30) und hat sich immer wieder bewährt. Alles, was du unter einem UNIX-System beschreiben oder lesen kannst, wird über eine mehr oder weniger abstrakte Datei angesprochen. Das fängt an bei ganz normalen Dateien, geht aber über Partitionen, Festplatten, allen anderen Massenspeichern, und ist bei Terminals ("Kommandozeilenfenstern") und Netzwerkgeräten1 noch lange nicht vorbei.

Warum das ganze? Der Einfachheit halber! Beispiel: Wie ändere ich unter DOS mit z.B. einem Pascal oder C-Programm den Bootsektor der zweiten Partition der ersten Festplatte? Es gibt sicher eine API und div. Funktionen dafür, im schlimmsten Fall muß man das via Assembler machen. Unter Linux geht das (Pseudocode) so etwa:

open(HDD, "/dev/hdb2");        # ("hdb2" im Verzeichnis "/dev")
print(HDD, "Dies würde jetzt in den Boosektor der Platte geschrieben");
close(HDD);

und gibt eine Fehlermeldung von wegen "Zugriff verweigert", wenn man keinen Schreibzugriff auf die Partition hat oder nicht ROOT ist (wäre auch dumm wenn nicht). Genauso geht es mit den seriellen Schnittstellen: Man kann /dev/ttyS1 (COM2: unter DOS) einfach wie eine Datei öffnen und davon lesen und darein schreiben.

Die Platte/Partition wird einfach wie eine Datei behandelt. Genauso geht es mit Terminals, d.h. entweder den Textmodus-Kommandozeilen oder halt den X-Terminals. Es gibt dabei BlockDevices (alle Massenspeicher) und CharacterDevices (Terminals, serielle Ports, alle "nicht-speichernden" Geräte). Bei den Block orientierten Geräten2 muss immer ein ganzer Block (z.B. 512 Bytes) auf einmal geschrieben bzw. gelesen werden. Zeichenorientierte Geräte dagegen kann man auch mit einzelnen Bytes füttern. Neben Lesen und Schreiben kann man auf Geräte-Dateien auch so genannte ioctl-Aufrufe ausführen.

Wie werden diese "Spezialdateien" von Linux behandelt, erstellt, und interpretiert? Jede dieser Dateien in /dev (sie müssen übrigens nicht dort liegen, sie können auch an jeder anderen Stelle liegen) hat statt einer Größe zwei Nummern, eine Haupt- und eine Nebenzahl (Major/Minor Number). Diese sieht man, wenn man mit ls -l /dev mal in das entsprechende Verzeichnis reinguckt.

Wie diese Spezialdateien heißen, ist letztendlich egal - was sie tun, hängt vollständig von diesen beiden Zahlen ab. Und die wiederum sind in der Kerneldokumentation beschrieben und zwar in der Datei Documentation/devices.txt. Neu anlegen kann man sie mit dem fast überall in /dev rumliegenden Skript MAKEDEV. Es ist in sich selbst dokumentiert, einfach mit less anschauen.

Wer jemals aus Versehen seinen /dev Verzeichnisbaum gelöscht hat, wird dies zu schätzen wissen -- falls er nicht /dev/MAKEDEV mit gelöscht hat :) . Manchmal benötigt man auch ein Gerät, welches aus Platz- oder Übersichtlichkeitsgründen nicht erzeugt wurde, z.B. wenn man einen zusätzlichen IDE-Adapter einbaut. Mit /dev/MAKEDEV hdi erhält man seine Device Einträge.

Andere Betriebssysteme

Eine Besonderheit an den Dateien unter /dev ist, dass die Namen nicht standardisiert sind (etwa durch POSIX). Das heißt, dass unter anderen UNIX-ähnlichen Systemen die Geräte meist anders heißen. Es gibt sogar unter GNU/Linux noch ein zweites Namensschema -- mit devfs, dem "/dev Filesystem".

Ein abschreckendes Beispiel: Früher (bis Kernel 2.0.x) hieß die erste serielle Schnittstelle /dev/cua0. Seit 2.2 lautet der Name /dev/ttyS0, mit devfs /dev/tts/0. BSD-Systeme benutzen jedoch weiterhin Namen, die mit cu für "Calling Unit" beginnen: FreeBSD hat /dev/cuaa0, OpenBSD /dev/cua00, und das interne Modem heißt unter MacOSX /dev/cu.modem.

Noch ein Beispiel: Die erste IDE-Festplatte heißt unter GNU/Linux /dev/hda, mit devfs /dev/discs/disc0/disc oder /dev/ide/host0/bus0/target0/lun0/disc, unter FreeBSD/NetBSD/OpenBSD /dev/wd0c und unter MacOSX /dev/disk0. Die erste Partition auf dieser Festplatte heißt unter GNU/Linux /dev/hda1, mit devfs /dev/discs/disc0/part1 oder /dev/ide/host0/bus0/target0/lun0/part1, unter FreeBSD/NetBSD/OpenBSD /dev/wd0a und unter MacOSX /dev/disk0s1.

Fazit: Wenn man ein Programm schreibt, das mit Gerätenamen arbeitet, darf man sich niemals darauf verlassen, dass ein bestimmmtes Gerät einen bestimmten Namen hat. cdrecord (CdBrennen/PerKommandozeile) zum Beispiel benutzt eine SCSI-Bibliothek, die auf allen unterstützten Plattformen weiß, wie ein bestimmtes SCSI-Gerät heißt.

JensBenecke et al.

  1. Netzwerk-Interfaces wie eth0 sind aber normalerweise KEINE Datei. <br> was ist es dann? stream, socket,... ? (1)

  2. Neue Rechtschreibung! -- BennySiegert (2)

dev (zuletzt geändert am 2007-12-23 22:47:19 durch localhost)