Axel Rogat
Betriebssysteme und betriebssystemnahes Programmieren
 
2.5: MS-DOS Kapitel 2 2.7: UNIX 
 
  2.6 Windows  
 

Das Windows der Versionen bis 3.11 ist keine Betriebssystem, sondern ein Aufsatz auf MS-DOS. Es stellt eine grafische Bedieneroberfläche zur Verfügung, was aber nicht als Teil eines Betriebssystems angesehen werden kann und von uns hier nicht betrachtet wird.

Durch die DOS-Engpässe erhielt es aber mehr und mehr Betriebssystem-Elemente. Beispielsweise erlaubt es das Halten mehrerer DOS- bzw. spezieller Windows-Programme im Speicher, zwischen denen umgeschaltet werden kann.

Zu seinem Start wird von DOS aus das Kommando WIN abgesetzt (aus WIN.COM), das andere Teile (s.u.) lädt und initialisiert.

Der Hauptbeitrag, den MS-DOS danach leistet, ist allerdings nur das Dateisystem. Da es für Prozessoren entworfen wurde, die maximal 1MB Hauptspeicher ansprechen konnten, ist es für die Speicherverwaltung nicht geeignet, die deshalb von Windows übernommen wird. I/O-Geräte werden teils über DOS, teils über Windows-eigene Treiber, teils über das BIOS angesprochen.

Windows NT und Windows 95 sind dagegen (unter anderem) "echte" Betriebssysteme.

2.6.1 Windows und die 80x86-Modi

Wir schauen uns zunächst die Eignung der Prozessor-Modi für wichtige Betriebssystem-Konzepte an:
Real Mode:
Dieser Modus ist nicht für Multitasking-Systeme geeignet, da jedes Programm alle Befehle ausführen und auf den gesamten Speicher frei zugreifen kann. Außerdem ist hardwaremäßig einfach nicht mehr als 1 MB Speicher ansprechbar, in den nun DOS, Windows und wenn möglich schließlich noch Anwenderprogramme passen müssen.

Die ersten Windows-Versionen hatten nur diesen Modus zur Verfügung. Bis inklusive Version 3.0 wird er auch noch unterstützt, macht auf neueren Prozessoren aber nur für veraltete Anwendungen Sinn. Windows belegt dann selbst 384 KB der belegbaren 640 kB, läßt also wenig Raum für Anwendungen und verkümmert zu einem umfangreichen Dateimanager.

Virtueller 8086-Modus:
Dieser Modus ist wegen der Unterstützung virtueller 8086-Maschinen gut für das Nebeneinander mehrerer DOS-Programme geeignet. Unter Windows können mehrere DOS-Sitzungen unabhängig voneinander laufen (genug Speicher vorausgesetzt). Die DOS-Umgebung vor dem Windows-Start wird komplett geerbt, inklusive Interrupt-Tabelle, speicherresidenten Programmen, etc. Die DOS-Programme multitasken (in 16-Bit-Windows) untereinander nicht. Man kann zwischen echten Windows-Programmen und den DOS-Anwendungen per Maus oder Tastatur umschalten.

Protected Mode:
Auf Prozessoren ab 80386 mit mindestens 2 MB Speicher läuft Windows ab 3.0 automatisch im erweiterten Modus (Enhanced Mode), der als Prozessor-Modus den Protected Mode benutzt.

16-Bit-Versionen von Windows nutzen die Prozessorfähigkeiten aber fast nur zur Verwirklichung von virtuellem Speicher und zur Erweiterung des Adreßraums von 1 MB auf 16 MB bzw. 4 GB. Für DOS-Anwendungen wird weiterhin der virtuelle 8086-Modus verwendet. Die Windows-Schnittstellenbleiben 16-Bit-Schnittstellen. Wirkliches Multitasking wäre hardwaremäßig möglich, wird aber von Windows nicht unterstützt. Der Betriebssystemkern ist aber ein 32-Bit-Programm.

32-Bit-Versionen (NT und 95+) nutzen den Modus dagegen gut aus. Es gibt echtes Multitasking, und die Windows-Schnittstelle wird auf 32 Bit ausgebaut.

2.6.2 Entwicklungsstufen von Windows

Windows 3.x
ist ein System für 16-Bit-Programme.

Das Multitasking ist nicht präemptiv, d.h. es arbeitet nicht mit Zeitscheiben oder I/O-orientierten Mechanismen, um zwischen Prozessen hin- und herzuschalten. Zwischen verschiedenen DOS-Anwendungen und dem normalen Windows-Betrieb muß der Benutzer (z.B. mit ALT TAB) wechseln. Windows-Programme müssen explizit die CPU-Kontrolle abgeben (mit dem System-Aufruf yield oder durch das Warten auf eine Nachricht). Wenn sie dies nicht tun, reißen sie also die komplette Systemkontrolle an sich.

Das Dateisystem wird immer noch von MS-DOS verwaltet. Für jeden Zugriff muß also in den virtuellen 8086-Modus geschaltet werden, und dort bestehen die üblichen Speicherbeschränkungen. Datei- und Gerätezugriffe werden unnötig verlangsamt. Wenn der virtuelle Speicher über normale Dateien abläuft, ist auch er hiervon betroffen.

Windows NT
ist bei seiner Einführung weniger für den einfachen Anwender als für den Einsatz in Netzwerken und insbesondere als Server gedacht gewesen. Entsprechend umfangreich ist der Anteil von Sicherheitsvorkehrungen (Zugriff auf fremde Dateien, Ressourcen, Prozesse) am gesamten System.

Windows NT ist außerdem nicht nur für Intel-Systeme erhältlich, sondern auf andere Prozessor-Architekturen portiert worden. Immer ist es aber (mindestens) ein eigenständiges 32-Bit-Betriebssystem. Es ist nicht auf MS-DOS angewiesen, sondern bringt ein eigenes schnelles Dateisystem mit.

Es wird mit präemptivem Multitasking (mit Zeitscheiben) gearbeitet. Voneinander abgeschottete Prozesse und zusammengehörige Unterprozesse (Threads) sind möglich. Die Programmierschnittstelle ist eine echte 32-Bit-Schnittstelle namens Win32 geworden, die sehr umfangreiche Dienste bietet.

Windows 95
setzt ebenfalls nicht mehr auf MS-DOS auf, hat aber einige DOS-Strukturen mitgenommen und verwendet sie immer noch. Dennoch stellt es fast die komplette Win32-Schnittstelle zur Verfügung.

Das präemptive Multitasking stimmt bei 32-Bit-Anwendungen mit dem von NT überein. Bei der Abwicklung von DOS-Programmen ist Windows 95 kompatibler als NT. Das normale Dateisystem entspricht dem DOS-System, wird aber über eigene 32-Bit-Treiber geregelt.

Als kleine Bonbons wurden damit auch endlich die überall sonst selbstverständlichen "langen" Dateinamen erlaubt. Die automatische Hardware-Erkennung soll auch dem Normalbenutzer den Einbau neuer Hardware erlauben, kämpft aber bis heute mit heftigen Schwierigkeiten.

2.6.3 Struktur der Windows-Systeme

Die Kommunikation von Anwenderprogrammen mit dem Fenstersystem erfolgt in jedem Fall über ein
API (Application Programmer's Interface), eine Sammlung von einigen hundert Funktionen (gesammelt in Bibliotheken), die normal wie Unterprogramme aufgerufen werden. Die 16- und 32-Bit-APIs sind streng voneinander getrennt.

Einige typische API-Aufrufe sind zum Beispiel:

CreateWindow neues Fenster anlegen
SetMenu Menü für ein Fenster festlegen
GlobalAlloc Speicher reservieren (Win32)
CreateFile Datei anlegen (Win32)
EnterCriticalSection kritische Sektion eines Threads signalisieren (Win32)

Mit MS-DOS und dem BIOS kann weiterhin über Interrupts gearbeitet werden. DOS-Interrupts sind dabei der Normalfall (sie werden vom Windows-Kernel abgefangen!). Unter älteren Versionen konnten BIOS-Interrupts dagegen die interne Verwaltung durcheinanderbringen. Durch die Interrupt-Virtualisierung bei 32-Bit-Systemen sind auch sie inzwischen wieder ungefährlich.

Die drei Kernbestandteile von Windows sind folgende drei Module:

16 Bit 32 Bit  
KERNEL.EXE KERNEL32.DLL Laden/Starten von Programmen, Prozeß- und Speicherverwaltung
GDI.EXE GDI32.DLL Graphics Device Interface, grafische Grundoperationen
USER.EXE USER32.DLL verschiedenes, "der Rest"

16-Bit-Systemstruktur:
Unten ist eine 16-Bit-Version von Windows dargestellt, die also auf MS-DOS aufsetzt.

Für I/O-Geräte gibt es Gerätetreiber *.DRV, die von USER und GDI (oder auch direkt vom Anwenderprogramm) aus aufgerufen werden. Datei-orientierte Treiber (für Platten und Drucker) rufen dazu die passenden BIOS-Routinen auf. Treiber für Bildschirm, Maus, Sound, etc. sprechen die Hardware direkt an.

Im Bild ist eine Installation gezeigt, bei der jedem Gerät ein eigener *.DRV-Treiber zugeordnet ist, der leicht einzeln ausgetauscht werden kann. Es gibt auch eine Sammelinstallation, wo die meisten Treiber in zwei Dateien zusammengefaßt sind ( WINxxx.BIN und WINxxx.OVL), die beim Booten schneller geladen werden können. Dann muß allerdings bei jedem Gerätewechsel Windows neu installiert werden!

Real-Mode-Probleme:
Die Aufgaben der meisten *.DRV-Treiber hätten durchaus durch bestehende DOS- oder BIOS-Routinen übernommen werden können. Ihre konsequente Einführung hatte einen speziellen Grund.

Interrupts im Protected Mode werden intern anders beantwortet als Interrupts im Real Mode. Die im Bild angegebenen DOS-Aufrufe mit INT 21h landen deshalb immer im Windows-Kernel, der dann entweder selbst die Verarbeitung übernimmt oder einen DOS- oder BIOS-Aufruf tätigt. Dann muß jedesmal in den Real Mode geschaltet und ein Real-Mode-Interrupt abgesetzt werden.

Es gibt nun aber zwar einen Maschinenbefehl, um vom Real in den Protected Mode zu gelangen -- aber nicht umgekehrt, das geht nur mit einem Prozessor-Reset. Deshalb muß jedesmal ein absurder Umweg gegangen werden -- beispielsweise muß dem System vorgegaukelt werden, der Benutzer hätte CTRL-ALT-DEL gedrückt, und der entsprechende Vektor mußte vorher kurzfristig verbogen werden. Bei jedem Aufruf ging daher viel Zeit für dieses technische Detail verloren. Wenn mehrere Prozesse irgendeinen Real-Mode-Dienst benötigten, wurden die Anfragen in ein und dieselbe Warteschleife gelegt, was zusätzlich verlangsamte.

Die *.DRV-Treiber sind deshalb so ausgelegt, so weit wie möglich ohne BIOS-Zugriff und Real Mode auszukommen. Das ist nicht immer möglich, und dann kommt es dennoch zu den beschriebenen Zeiteffekten.

32-Bit-Systeme:
An der Grundstruktur des Systems ändert sich nichts Wesentliches. Die MS-DOS-Bestandteile sind aber eher in Windows integriert zu sehen, und es gibt eine neue Art von Treibern. Virtuelle Gerätetreiber *.VxD (virtual x device) dienen dazu, Geräte und Systemdienste zu virtualisieren, so daß Anwenderprogramme davon ausgehen können, den Rechner allein zu besitzen.

Die Aufgabe der *VxDs ist also die Verteilung der physischen Ressourcen auf all die Programme, die diese anfordern - und zwar geräteweise getrennt und damit intelligenter als die einfache Warteschlange von weiter oben. Außerdem sind Bestandteile des Kernels in virtuelle Treiber ausgelagert worden, beispielsweise VMM32.VXD für die virtuelle Speicherverwaltung.

Es gibt beispielsweise VFD.VXD für die Floppy, SERIAL.VXD für die serielle Schnittstelle, MSMOUSE.VXD für die Maus, PCI.VXD für den PCI-Bus, etc.

Aus Kompatibilitätsgründen gibt es nun meist Treiber in zwei Stufen: ein *.DRV-Treiber, der aber oft nichts weiter tut, als die passenden Funktionen des *VxD-Treibers aufzurufen, also eine Schnittstellenanpassung von 16 nach 32 Bit vorzunehmen.

Der Kernel benutzt natürlich direkt die *VxDs, und auch echte 32-Bit-Programme können über die Win32-Funktion DeviceIOControl direkt auf ihre Dienste zugreifen.

Virtuelle Interrupts:
Wichtig für die Virtualisierung der Hardware (inklusive der Interrupts!) ist die Möglichkeit vom 80386 aufwärts, die I/O-Maschinenbefehle IN und OUT für bestimmte Ports zu beschränken. Es wird dann durch eine solche Instruktion ein Protected-Mode-Interrupt ausgelöst, der von den *VxD-Treibern behandelt wird.

Für mehrere parallel laufende MS-DOS-Anwendungen (in eigenen virtuellen Maschinen) sieht unser Beispiel für Tastaturdrücke von oben schematisch wie folgt aus:

 
2.5: MS-DOS Startseite 2.7: UNIX