Das Betriebssystem abstrahiert die Schnittstelle zur wirklich vorhandenen Hardware in einem Computersystem und stellt eine virtuelle Maschine mit definierten Eigenschaften zur Verfügung. Ein Beispiel für eine Schnittstellendefinition ist der POSIX Standard.
Die Aufgaben, welche das Betriebssystem zu lösen hat sind vielfältig:
Im Kontext der Gerätetreiber-Portierung sind insbesondere die Punkte 2) und 5) interessant. Es ist also zu klären, wie das Betriebssystem mit den Hardware-Ressourcen umgeht und welche Mechanismen die Ein/Ausgabe unterstützen. Außer diesen Punkten darf man auch den Einfluß der Ablaufsteuerung auf Gerätetreiber nicht vernachlässigen.
Auf diese Themen gehe ich in den nächsten Abschnitten näher ein, beginne nun aber mit einer genaueren Beschreibung von Gerätetreiber-Software.
Das ,,Taschenbuch der Informatik`` definiert Treiber-Software so ([W$^+$95] S. 295):
Die Gerätebedienroutinen (Gerätetreiber) übernehmen die Eingabe bzw. Ausgabe einer gerätespezifischen Dateneinheit, z.B. eines Zeichens oder eines Blockes. Dabei beachten sie das von der Gerätesteuerung festgelegte Protokoll (z.B. Ausgabe von Kommandos, Abfrage und Auswertung des Gerätestatus, Behandlung von Fertigmeldungen, Übergabe bzw. Übernahme von Nutzdaten).
Das bedeutet also, daß Gerätetreiber eine Softwareschicht zwischen Applikationen bzw. Kernkomponenten (z.B. Netzwerkprotokoll-Stack) und dem wirklichen Gerät darstellen. Als integraler Bestandteil des Betriebssystems sind sie eng mit diesem verbunden und werden normalerweise speziell auf eine bestimmte Systemumgebung zugeschnitten.
Eine nicht geringe Eigenschaft der Gerätetreiber ist die Schutzfunktion, die diese darstellen. Es soll also nicht möglich sein, ein über einen Treiber angesteuertes Gerät durch falsche Benutzung zu beschädigen oder sogar zu zerstören.
Der Gerätetreiber behandelt Anfragen von Nutzerprogrammen (system calls) und Hardwareereignisse (interrupts). Aus diesem Grund kann man die Treiberfunktionalität grob in zwei Schichten -- Prozeß- und Interrupt-Ebene -- unterteilen (Abb. 2.5). Da die beiden Schichten einen gemeinsamen Status teilen und nicht zwingend sequentiell ausgeführt werden, müssen Zugriffe auf den shared Bereich synchronisiert werden.
Wie die Synchronisation durchgesetzt wird, ist systemabhängig. Häufig basieren Lösungen auf Warteschlangen, Locks und Unterbrechungszulassung bzw. -verbot. Das Sperren von Interrupts ist in Uniprozessor-Systemen die einfachste Möglichkeit zu synchronisieren.
In Multiprozessor-Betriebssystemen dagegen muß man andere Lösungen finden. Die Serialisierung von Systemrufen, so daß nur einer aktiv zu einem Zeitpunkt (Linux 2.0) ist, ist eine Möglichkeit, Aktivitäten auf Prozeßebene zu synchronisieren. Eine andere ist, den Kern multi-threaded (Solaris, Linux 2.4) zu entwerfen. Intelligente Sperren sind hier sehr wichtig, da mehrere Aktivitäten der Prozeß- und Interruptebenen auf unterschiedlichen Prozessoren ablaufen können.
Soll nun derselbe Treiber in verschiedenen Umgebungen genutzt werden, ist es wahrscheinlich, daß die erwarteten Kernfunktionalitäten nicht zur Verfügung stehen bzw. ein anderes Verhalten aufweisen.