Kapitel 2   Architektur

Bestimmte Aufgaben müssen alle Betriebssysteme erfüllen. Ein Betriebssystem muss Speicherressourcen zuweisen, den Zugriff auf Treiber kontrollieren und den Wechsel zwischen Programmen behandeln, die momentan aktiv sind oder warten. Windows 2000 ist da keine Ausnahme. Der Prozess funktioniert bei der gesamten Windows 2000 Serverfamilie gleich. Deshalb bietet dieses Kapitel einen allgemeinen Überblick über die Funktionsweise des Betriebssystems - unabhängig von den Diensten und zum größten Teil unabhängig von der zugrunde liegenden Hardwareplattform. Um die Analyse zu erleichtern, wird das Betriebssystem dabei in kleinere Einheiten unterteilt:

Werfen wir zunächst einen Blick auf die Architektur der Teilsysteme und des Kernels, dem Herzen von Windows 2000.

2.1 Die Architektur der Teilsysteme und des Kernels

Als das Betriebssystem noch in den Kinderschuhen steckte und »Windows NT 3.5« hieß, kämpften verschiedene Betriebssysteme um die Vorherrschaft. Windows NT war der Newcomer unter den Rivalen OS/2 und UNIX. Microsoft wusste auch, dass der Markt für 32-Bit-Windows-Anwendungen zunächst nur langsam wachsen würde. Deshalb war Windows NT ursprünglich auf den Betrieb verschiedener Teilsysteme oder Subsysteme ausgelegt, die die Ausführung von Programmen von verschiedenen Betriebssystemen aus ermöglichten. Windows NT erlaubt Programmen, die diese Teilsysteme verwenden, die gleichzeitige Ausführung und den gemeinsamen Zugriff auf Ressourcen wie die CPU-Zeit, Festplattenlaufwerke und Bildschirme, wobei dafür gesorgt wird, dass das fehlerhafte Verhalten eines Programms die anderen Programme nicht negativ beeinflusst.

Die Teilsysteme wurden so programmiert, dass sie, wenn ein Programm Gefahr lief, Amok zu laufen und die Integrität des Teilsystems des Hosts zu zerstören drohte, nicht das gesamte Betriebssystem zum Absturz bringen und die anderen Teilsysteme nicht beeinflussen sollten.

Damit die Teilsysteme unabhängig voneinander arbeiten können, muss es einen zentralen Zuweisungsmechanismus (oder Kernel) und zahlreiche andere Systeme geben, die zusammenarbeiten, um die grundlegenden Dienste bereitzustellen. Der Prozessor muss in der Lage sein zu verhindern, dass Anwendungen Speicher überschreiben, der vom Kernel und anderen Diensten genutzt wird. Dies wurde durch Implementierung eines Benutzer- und eines Kernelmodus erreicht. Um zu verhindern, dass der Kernel und die Ausführungsschicht Probleme bei der Hardware verursachen und um den Wechsel zwischen verschiedenen Prozessorarchitekturen zu erleichtern, muss die gesamte Interaktion mit der Hardware über die Hardwareabstraktionsschicht (HAL = Hardware Abstraction Layer) erfolgen. Außerdem muss der Kernel in der Lage sein, die Zeitplanung für Prozesse durchzuführen, Speicher zu verwalten und die Steuerelemente für die Sicherheit zu verstärken. Schließlich haben die Teilsysteme auch noch die Dienste, die sie Anwendungen bereitstellen müssen und die Anwendungsprogrammierungsschnittstellen (API = Application Programming Interface), die sie benötigen, um mit dem Benutzer zu interagieren. Die Abbildung 2.1 bietet Ihnen einen Überblick über das, was in den nächsten Abschnitten behandelt wird.

Abbildung 2.1:  Die grundlegende Architektur von Windows 2000. Alle Schichten unterhalb der Anwendungsschicht werden in den nachfolgenden Abschnitten ausführlich beschrieben.

2.1.1 Benutzermodus und Kernelmodus

Windows 2000 benutzt zwei verschiedene Prozessormodi. Ein Modus namens Kernelmodus führt die Dienste der Ausführungsschicht aus und der andere Modus namens Benutzermodus führt die Anwendungsprogramme aus.

Die Dienste des Kernelmodus werden vom Prozessor geschützt. Die Dienste des Benutzermodus werden vom Betriebssystem geschützt. Dabei wird verhindert, dass Programme, die im Benutzermodus ausgeführt werden, Speicher überschreiben, der von Programmen benutzt wird, die im Kernelmodus ausgeführt werden. Der Prozessor verhindert, dass Programme, die im Kernelmodus ausgeführt werden, Daten in den Adressraum schreiben, in dem Programme gespeichert sind. Außerdem ruft der Prozessor eine Kernelmodus-Ausnahme hervor, die Windows 2000 in einen »blauen Bildschirm« (BSOD = Blue Screen of Death) umsetzt. Der blaue Bildschirm enthält Text, anhand dessen der Support von Microsoft herausfinden kann, was mit dem Computer los ist. Normalerweise wird ein blauer Bildschirm durch einen fehlerhaften Treiber verursacht, der versucht, Daten an eine unzulässige Stelle zu schreiben.

Wenn der Kernelmodus um so viel zuverlässiger ist, warum wird dann nicht alles im Kernelmodus ausgeführt? Die Antwort darauf ist einfach und einleuchtend zugleich: Die Programmierung von Komponenten, die im Kernelmodus ausgeführt werden, ist erheblich aufwändiger. Neue Releases würden dann noch später erscheinen als bisher. Ein Komödiant fragte einmal, »Warum besteht nicht das gesamte Flugzeug aus demselben Material wie der Flugschreiber?«. Wenn das Flugzeug aus diesem Material bestünde, wäre es zu schwer, um überhaupt fliegen zu können. Andere Frage, gleiche Antwort: Wenn alles im Kernelmodus ausgeführt würde, müssten Programme so umfangreich sein, um alle möglichen Ausnahmen zu behandeln, dass sie niemals erscheinen würden. Deshalb müssen wir uns damit abfinden, dass Programme eventuell abstürzen können.

Bei Windows 2000 wird so viel wie möglich im Benutzermodus ausgeführt. Dadurch reduziert sich die Menge des höchst kritischen Codes, der im Kernelmodus ausgeführt wird, und der Code wird leichter handhabbar. Der Unterschied zwischen einem Absturz eines Programms im Benutzermodus und einem im Kernelmodus ist, dass ein Benutzermodusprogramm ein Ereignis in das Ereignisprotokoll einträgt und die restlichen Programme davon unberührt bleiben. Wenn ein Kernelmodusprogramm ein Problem hat, bricht der Server mit einem blauen Bildschirm ab. Werfen Sie einen Blick auf Abbildung 2.1. Die Komponenten unterhalb der Linie werden im Benutzermodus ausgeführt.

Beginnend mit Windows NT 4.0 werden Teile des Win32-Teilsystems, insbesondere die Benutzer- und GDI-Teile, im Kernelmodus ausgeführt. Dies war eine etwas kontroverse Entscheidung, die im Abschnitt zum Win32-Teilsystem ausführlicher beschrieben wird.

Benutzermodusprogramme kommunizieren mit dem Kernel über spezifische Anwendungsprogrammierungsschnittstellen (APIs = Application Programming Interfaces). Diese APIs dienen dazu, einen stabilen Kommunikationsmodus zwischen den verschiedenen Programmen, die ausgeführt werden, und dem Betriebssystem zu definieren.

Der Rest des Kernelmodus ist in drei Teile aufgeteilt. Die Hardwareabstraktionsschicht (HAL = Hardware Abstraction Layer) bietet eine konsistente Schnittstelle zur Hardware, der Kernel ist der Motor des Ganzen und die Dienste der Ausführungsschicht (Executive Services) verwalten die grundlegenden Operationen wie die Sicherheit, die Zeitplanung für Tasks und den Speicher.

2.1.2 Die Hardwareabstraktionsschicht

Windows 2000 ist portierbar, was bedeutet, dass es auf verschiedenen Hardwareplattformen laufen kann. Windows NT war für Alpha-Systeme, MIPS und den PowerPC verfügbar. Die Nachfrage war jedoch nicht groß genug, um den Produktionsaufwand zu rechtfertigen.

Windows 2000 ist portierbar, weil es fast komplett in C++ geschrieben ist und C++-Compiler zu den ersten Compilern gehört, die für neue Prozessoren geschrieben werden. Die Teile von Windows 2000, die nicht in C++ geschrieben sind, sind in der Assemblersprache der Hardwareplattform geschrieben, auf die Windows 2000 portiert wurde. Diese Teile sind in der so genannten Hardwareabstraktionsschicht (HAL) enthalten.

Dabei handelt es sich um den einzigen Bestandteil des Betriebssystems, der direkt mit der Hardware interagiert. Die Interaktion erfolgt über eine feste Schnittstelle zum darüber liegenden Kernel und eine Maskierung der Unregelmäßigkeiten der darunter liegenden Hardware. Deshalb muss der Kernel nichts über die Besonderheiten der Hardware wissen und auch nicht so stark geändert werden, wenn eine Portierung auf eine andere Hardwareplattform erfolgt.

Die Hardwareabstraktionsschicht präsentiert dem Kernel eine abstrakte Sicht der Hardware, sodass der Kernel nicht neu geschrieben werden muss, um einen anderen Prozessor nutzen zu können. Der Kernel muss nur wissen, wie er auf einen bestimmten Prozessortyp zugreift. Dies ist der Typ, den die Hardwareabstraktionsschicht bereitstellt. Die Hardwareabstraktionsschicht behandelt die Anforderungen des Kernels und wandelt diese in Anweisungen um, die der Prozessor verarbeiten kann.

Die Hardwareabstraktionsschicht bietet die Grundlage für die Unterstützung des symmetrischen Multiprocessing (SMP). Es weiß, wie der Prozessor benutzt wird und präsentiert dem Kernel einfach - falls vorhanden - mehrere Prozessoren. Wenn ein Computer mit mehreren Prozessoren ausgestattet wird, muss die Hardwareabstraktionsschicht ersetzt werden. Bei den meisten Systemen, insbesondere Serversystemen, ist eine Programmdiskette vorhanden, die eine vom Hardwarehersteller bereitgestellte Hardwareabstraktionsschicht installiert, um die Unterstützung von SMP zu aktivieren.

Noch ein wichtiger Hinweis: 
Die Hardwareabstraktionsschicht ist der einzige Bestandteil des Systems, der direkt mit der Hardware kommunizieren kann, und der Kernel ist der einzige Teil des Systems, der direkt mit der Hardwareabstraktionsschicht kommuniziert. Dies reduziert die Probleme mit der Hardware und erhöht die Sicherheit, weil zerstörerische Anwendungen den Kernel und die Hardwareabstraktionsschicht umgehen müssen, um Probleme bei der Hardware zu verursachen.

2.1.3 Der Kernel

Der Kernel ist unter architektonischen Gesichtspunkten der zentrale Bestandteil des Betriebssystems. Bei Windows 2000 wird ein Mikrokernel-Design eingesetzt, was bedeutet, dass der Kernel nur ein Minimum der Funktionalität bereitstellt und darauf baut, dass andere Dienste zusätzliche Funktionalität liefern. Der Kernel ist hauptsächlich dafür verantwortlich festzulegen, was der Prozessor als Nächstes ausführt.

Wenn ein Programm ausgeführt wird, ist dies mit einem Prozess verknüpft und ein Prozess besitzt mindestens einen Thread. Ein Prozess besteht aus Speicherplatz und mindestens einem Thread. Der Thread ist das, was tatsächlich ausgeführt wird. Er ist der »Programm«-Teil der Anwendung und der Prozess setzt sich aus dem Programm und den Daten zusammen, mit denen das Programm arbeitet. Der Unterschied zwischen einem Prozess und einem Thread ist, dass nicht dem Prozess vom Betriebssystem Prozessorzeit zugeteilt wird, sondern dem Thread. Vereinfacht ausgedrückt bedeutet dies: Nicht Prozessen, sondern Threads wird vom Betriebssystem Ausführungszeit zugeteilt.

Der Kernel kennt drei Arten von Aufgaben. Erstens legt er die Zeitplanung für die Ausführung von Threads fest. Jedem Thread wird eine Priorität im Bereich zwischen 0 und 31 zugeordnet. Der Kernel nimmt den Thread mit der höchsten Priorität, der unbedingt ausgeführt werden muss, und gestattet, dass dieser Thread für eine bestimmte Zeitdauer auf einem Prozessor ausgeführt wird. Am Ende dieser Zeitdauer betrachtet der Kernel wieder die Threadliste und wählt den Thread mit der höchsten Priorität zur Ausführung aus. Enthält das System mehrere Prozessoren, wird für jeden Prozessor, basierend auf der Priorität, ein Thread ausgewählt.

Eine weitere Aufgabe des Kernels ist das Interrupt Handling. Wenn ein Gerät, wie z.B. eine Festplatte, aufgefordert wird, Daten zu lesen, wird die Anforderung an die Festplatte gesendet. Die Festplatte ruft die Daten ab und benachrichtigt dann den Kernel, indem sie veranlasst, dass ein Interruptsignal an einen Prozessor gesendet wird. Wenn ein Interrupt auftritt, unterbricht der Kernel automatisch den Prozess, der auf einem Prozessor ausgeführt wird, behandelt den Interrupt und liefert dann die Kontrolle wieder an den Prozess zurück, der unterbrochen (preempted) wurde.

Die dritte Art von Aufgaben, die das System behandeln muss, ist die Behandlung von Kernelausnahmen. Wenn etwas passiert und ein Programm, das im Kernelmodus ausgeführt wird, eine Schutzverletzung oder eine andere Art von Fehler verursacht, versucht der Kernel, den Fehler zu behandeln. In einigen Fällen kann der Kernel den Fehler problemlos beheben. Manchmal ist das aber auch nicht möglich, dann ist mal wieder BSOD-Zeit, d.h. der blaue Bildschirm mit dem Speicherabbild wird angezeigt.

2.1.4 Die Windows 2000-Ausführungsschicht

Ein Betriebssystem hat zahlreiche unterschiedliche Pflichten zu erfüllen, um Anwendungen eine entsprechende Ausführungsumgebung zu bieten. Das Mikrokernel-Design von Windows 2000 legt fest, dass der Kernel nur grundlegende Dienste wie den Taskwechsel behandelt. Die restlichen Dienste werden natürlich auch ausgeführt, nur nicht vom Kernel. Die meisten wurden in die Windows 2000-Ausführungsschicht (Executive) ausgelagert. Diese enthält entsprechend zahlreiche Dienste für die unterschiedlichsten Aufgaben.

Die Windows 2000-Ausführungsschicht wird im Kernelmodus ausgeführt. Sie hat uneingeschränkten Zugriff auf den Kernel und die E/A-Geräte. Die meisten Benutzeranwendungen greifen nicht direkt auf die Ausführungsschicht zu, sondern benutzen ein Teilsystem, wie z.B. das Win32-Teilsystem, das die Dienste der Ausführungsschicht aufruft. Die Abbildung 2.2 zeigt die verschiedenen Komponenten der Windows 2000-Ausführungsschicht.

Abbildung 2.2:  Diese Teile der Windows 2000-Ausführungsschicht stellen in ihrer Kombination die grundlegenden Betriebssystemdienste bereit

Die Ausführungsschicht behandelt die folgenden Dienste:

Die folgenden Abschnitte veranschaulichen die genaue Funktionsweise jedes dieser Dienste.

Der Objekt-Manager

Der Objekt-Manager ist sehr wichtig. Er dient dazu, Objekte zu erstellen, zu verwalten und zu löschen, die vom System benutzt werden. Der Objekt-Manager empfängt eine Anforderung für eine Ressource, wie z.B. ein serieller Anschluss (Port), und liefert ein Handle (Zugriffsnummer) für den seriellen Anschluss zurück. Das Handle beinhaltet eine Zugriffsmethode auf ein Objekt und Sicherheitsinformationen, die festlegen, wie der Zugriff auf das Objekt erfolgt.

Der Objekt-Manager liefert auch andere Arten von Handles zurück, wie z.B. Gerätehandles (für die seriellen und parallelen Anschlüsse), um Konflikte beim Zugriff auf die Geräte zu vermeiden.

Der Objekt-Manager kommuniziert extensiv mit dem Sicherheitsreferenz-Manager (SRM), der später besprochen wird. Der SRM erzeugt die Sicherheitsinformationen, die mit einem Handle verknüpft werden, bevor es an das aufrufende Programm zurückgeliefert wird.

Außerdem achtet der Objekt-Manager auf verwaiste Objekte. Wenn ein Programm auf einen seriellen Port zugreift und dann abstürzt, ist der Objekt-Manager dafür verantwortlich, das Handle zu finden, es zu schließen und die benutzten Ressourcen freizugeben.

Der Prozess-Manager

Der Prozess-Manager ist ein Vermittler zwischen dem Benutzer und dem Objekt-Manager. Seine Aufgabe besteht in erster Linie darin, Prozesse zu erzeugen und zu verwalten. Der Prozess-Manager nimmt Anforderungen für die Erzeugung von Prozessen entgegen, ruft den Objekt-Manager auf, um die Prozesse und ihre Threads zu erzeugen, und hält dann die Liste der Prozesse verfügbar.

Die Speicherverwaltung für den virtuellen Arbeitsspeicher

Wenn ein Prozess erzeugt wird, wird ihm ein 4-Gbyte-Adressraum zugewiesen. Dieser Adressraum beginnt bei 0 und endet bei 4 Gbyte. Bei Windows 2000 Professional und Windows 2000 Server werden 2 Gbyte Speicher für den Benutzeradressraum zugewiesen und 2 Gbyte für das System. Windows 2000 Advanced Server weist 3 Gbyte Benutzeradressraum und 1 Gbyte für das System zu.

Windows 2000 unterstützt den Speicherschutz wie folgt: Ein Programm kann keinen Speicher außerhalb des eigenen Adressraums adressieren. Wenn eine Anwendung einen Lesevorgang aus dem Speicher anfordert, behandelt die Speicherverwaltung (VMM = Virtual Memory Manager) den Mechanismus für den Abruf der Daten. Die virtuelle Speicherverwaltung unterhält eine Tabelle, um zu verfolgen, welche Teile des Adressraums eines Prozesses sich im physischen Arbeitsspeicher befinden und welche ausgelagert sind. Wenn ein Prozess Daten aus dem Speicher lesen muss, prüft die virtuelle Speicherverwaltung, ob sich die Daten tatsächlich im physischen Speicher befinden. Ist das nicht der Fall, behandelt die virtuelle Speicherverwaltung den Abruf der Daten von der Festplatte. Der Abschnitt »Das Speichermodell und die Speicherverwaltung« weiter unten in diesem Kapitel geht näher auf die virtuelle Speicherverwaltung ein.

Der Sicherheitsreferenz-Manager

Der Sicherheitsreferenz-Manager (SRM) bildet die Grundlage für die Sicherheit in Windows 2000. Wenn sich ein Benutzer anmeldet, erzeugt der Anmeldeprozess ein Sicherheitstoken für den Benutzer. Immer dann, wenn der Benutzer den Zugriff auf ein Objekt anfordert, weist der Objekt-Manager den SRM an, das Token zu prüfen und festzustellen, welche Zugriffsberechtigungen der Benutzer erhalten soll. Der Objekt-Manager liefert das Handle auf das Objekt zurück, wobei die Zugriffsberechtigung Bestandteil des Handles ist.

Der E/A-Manager

Der E/A-Manager behandelt die Geräteein- und -ausgabe (E/A) für das System. Der E/A-Manager stellt seine Dienste Gerätetreibern und Anwendungen zur Verfügung, sodass die Gerätetreiber nicht wissen müssen, wie die Anwendungen sie benutzen werden. Und auch die Anwendungen müssen nicht wissen, wie die Geräte verwendet werden.

Der E/A-Manager behandelt beispielsweise alle Festplatten und Medien mit hoher Speicherkapazität als SCSI-Geräte. Wenn ein Hardwarehersteller dafür sorgen will, dass ein bestimmtes Gerät unter Windows 2000 läuft, muss er einen Treiber schreiben, den der E/A-Manager wie ein SCSI-Gerät behandeln kann, das eine stark standardisierte Schnittstelle bietet. Der Hersteller muss alle Aufrufe so übersetzen, dass die Hardware sie verstehen kann. Eine Anwendung muss nur wissen, wie das Teilsystem für einen Lesevorgang von der Festplatte aufgerufen wird. Das Teilsystem fordert dann den E/A-Manager auf, von der Festplatte zu lesen. Die Anwendung und das Teilsystem müssen nicht wissen, wie Daten von der Festplatte gelesen werden. Sie müssen nur wissen, was von der Festplatte gelesen werden soll.

Die Funktionen für lokale Prozeduraufrufe

Windows 2000 ist ein Client/Server-System. Was geschieht, wenn der Client und Serverprozesse auf demselben Computer ausgeführt werden? Eine Methode besteht in der Benutzung von entfernten Prozeduraufrufen (RPC = Remote Procedure Call), was einen ziemlich großen Overhead beinhaltet. Windows 2000 ist jedoch mit der Funktion der lokalen Prozeduraufrufe (LPC = Local Procedure Call) ausgestattet, was die Benutzung derselben Schnittstellen wie bei den RPCs gestattet, jedoch mit einem wesentlich geringeren Overhead. Dadurch kann das System schneller Antworten bieten, ohne die Schnittstelle ändern zu müssen.

2.1.5 Teilsysteme

Ein Teilsystem (auch Subsystem genannt) kann als Umgebung betrachtet werden, das zwischen dem Kernel und den Anwendungen sitzt und Programmen die Dienste und APIs zur Verfügung stellt, die diese erwarten. Dadurch können die Programme ausgeführt werden. Das Teilsystem benutzt die APIs gleichzeitig, um die benötigten Ressourcen beim Kernel anzufordern. Ein Teilsystem ist also im Wesentlichen ein Übersetzungsprogramm, das zwischen einer Gruppe von Anwendungen und dem Kernel sitzt.

Was ist ein API?
Ein API ist eine Anwendungsprogrammierungsschnittstelle (Application Programming Interface). Hilft Ihnen das noch immer nicht weiter? Ein API gestattet einem Programm die Kommunikation mit der Außenwelt. Ein Programm, das eine Verschlüsselung vornehmen muss, kann z.B. das CryptoAPI von Microsoft aufrufen, das Standardfunktionen für die Verschlüsselung enthält. Das Programm selbst muss nicht wissen, wie die Verschlüsselung durchgeführt wird. Diese wird vom API erledigt.
Ein API besteht aus einem Satz von Funktionen, die von Programmierern benutzt werden, um festzulegen, wie Programme interagieren. Der Einsatz eines API erlaubt es dem Hersteller der Schnittstelle (in diesem Fall Microsoft), deren Arbeitsweise zu ändern, ohne dass die Programme, die darauf zugreifen, geändert werden müssen. Wenn Microsoft z.B. eine tolle neue Verschlüsselungsfunktion entwickelt, kann diese problemlos in das CryptoAPI integriert werden. Solange sich die Schnittstelle nicht ändert, können die Programme unverändert auf das CryptoAPI zugreifen.
Wichtig ist hier die Schnittstellenkonsistenz. Toaster haben z.B. eine konsistente Schnittstelle. Jeder Toaster verfügt über einen oder mehrere Schlitze, in die die Brotscheiben eingelegt werden, einen Aktivierungshebel und einen Schalter, um die Bräunungsstufe einzustellen. Einige Toaster sind vielleicht etwas aufwändiger und enthalten Sensoren, die feststellen, wann der Toast perfekt ist. Das Grundprinzip ist jedoch bei allen Toastern gleich und die Benutzer müssen nicht rätseln, wie ein Toaster benutzt wird.
Ein API funktioniert auf dieselbe Weise. Ein Programmierer kann eine bestimmte Version des API schreiben. Wenn jedoch ein neueres API erscheint, das mit zusätzlichen Funktionen ausgestattet ist, kann der Programmierer trotzdem weiterhin die gleichen Eingaben (Brot) verwenden und erhält das gleiche Ergebnis (Toast). Gibt es eine neuere Version eines APIs, kann ein neues Programm dieselbe Schnittstelle benutzen, um eine neue Art von Eingaben (Vollkornbrot) machen und eine neue Art von Ausgabe (getoastetes Vollkornbrot) zu erhalten.
Nun sind Sie sicherlich hungrig. Gönnen Sie sich doch einen Toast. Das Buch ist noch da, wenn Sie zurückkommen.

Ein Teilsystem führt eine ganze Gruppe von Programmen aus und behandelt deren Zugriff auf den Kernel. Dies bedeutet, dass alle Hardwarezugriffe eines Programms über das Teilsystem laufen. Deshalb muss ein Programm, um Sound abspielen zu können, dies dem Teilsystem mitteilen. Das Teilsystem leitet diese Anforderung dann an den Kernel weiter und dieser an die Hardwareabstraktionsschicht. Die Hardwareabstraktionsschicht manipuliert die Hardware so, dass Sound abgespielt werden kann, woraufhin Sound abgespielt wird.

Es gibt zwei Arten von Teilsystemen. Das Win32-Teilsystem ist eine Klasse für sich. Alle anderen Teilsysteme sind im Wesentlichen Übersetzungsprogramme zwischen dem Teilsystem, das sie emulieren, und Win32. Das POSIX-Teilsystem ordnet die Funktionen des POSIX-API denen des Win32-API zu.

Wie sieht ein Teilsystem aus? Jedes Windows 2000-System ist mit ausführbaren Dateien ausgestattet, die Teilsysteme sind. Eines davon heißt Csrss.exe (Client/Server Resources Subsystem), das besser unter der Bezeichnung Win32-Teilsystem bekannt ist.

2.1.6 Das Win32-Teilsystem

Das Win32-Teilsystem wird am häufigsten benutzt und ist das einzige kritische Teilsystem. Ursprünglich war das Win32-Teilsystem eines unter vielen. Weil alle Benutzerfunktionen des Betriebssystems Win32 verwenden, werden Teile des Win32-Teilsystems im Kernelmodus als Teil der Windows 2000-Ausführungsschicht ausgeführt. Dies sind die Teile, die die grafische Benutzeroberfläche und die Grafikausgabe steuern. Deshalb stürzt das gesamte Betriebssystem ab, wenn das Win32-Teilsystem abstürzt.

Wenn das Win32-Teilsystem unter Windows NT 3.51 abstürzte, resultierte dies selbstverständlich in einem blauen Bildschirm, obwohl die User- und GDI-Teile nicht Bestandteil des Kernels waren. Das Betriebssystem war so eingerichtet, dass ein blauer Bildschirm erzeugt wurde, wenn der Kernel keine Benutzeroberfläche hatte. Weil die gesamte Benutzeroberfläche auf der User und der GDI basiert, stürzt das Betriebssystem ab, wenn eine dieser Komponenten abstürzt. Diese Teile in die Ausführungsschicht zu verschieben, ist nicht so schlimm, wie es aussieht. Die Verlagerung erfolgte, weil sich jeder Wechsel zwischen dem Benutzer- und dem Kernelmodus negativ auf die Performance auswirkt. Durch die Reduktion dieser Kontextwechsel verbesserte sich die Performance von Win32-Anwendungen beträchtlich.

Das bedeutet natürlich nicht, dass Anwendungen im Kernelmodus ausgeführt werden, sondern nur Teile des Teilsystems. Deshalb sind das Teilsystem und das Betriebssystem vor schädlichen Anwendungen sicher. Das Betriebssystem entdeckt Schutzverletzungen und stoppt die schädliche Anwendung, bevor sie Schaden verursachen kann.

Das Win32-API deckt alle Operationen ab, die eine Windows-Anwendung bei der Ausführung benötigt. Dies reicht von Lese- und Schreibvorgängen in Dateien bis zu DirectX. Das Win32-API ist ein sehr komplexes API und enthält zahlreiche Funktionalitäten. Die Windows-Programmierung erfolgt heutzutage unter Zugriff auf das Win32-API. Abbildung 2.3 bietet einen Überblick über diese Teilsystemschicht.

Abbildung 2.3:  Die Teilsystemschicht der Windows 2000-Architektur zeigt, wie die Teilsysteme mit dem Win32-Teilsystem interagieren, das als Einziges direkt mit der Ausführungsschicht interagiert.

Das Win32-Teilsystem enthält auch das MS-DOS- und das 16-Bit-Windows-Teilsystem (Windows 3.1 und Windows 3.11). Weil Windows 3.1 eigentlich kein echtes Betriebssystem ist, sondern vielmehr

eine grafische Benutzeroberfläche, die auf MS-DOS aufsetzt, musste das System in erster Linie in der Lage sein, MS-DOS-Anwendungen auszuführen.

MS-DOS-Anwendungen werden in einem Programm namens NT Virtual DOS Machine (NTVDM) ausgeführt. Obwohl das Betriebssystem inzwischen Windows 2000 heißt, gibt es noch eine NTVDM. Die NTVDM führt alle DOS-Anwendungen aus, indem die MS-DOS-5.0-Umgebung emuliert wird. Jede DOS-Anwendung läuft in ihrer eigenen NTVDM und in ihrem eigenen Adressraum. Diese NTVDMs lassen sich so lange starten und benutzen, bis kein Systemspeicher mehr verfügbar ist. Die NTVDM stellt einen vollständigen Netzwerk-Redirector sowie eine Unterstützung der Maus und von CD-ROM-Laufwerken bereit und bietet immer noch genügend freien Speicher (620 Kbyte), um MS-DOS-Anwendungen passabel auszuführen.

Nachdem es eine Möglichkeit gibt, DOS-Anwendungen auszuführen, muss nur noch ein Weg gefunden werden, um Windows 3.1-Anwendungen auszuführen. Dazu dient ein System namens Windows on Windows (WOW). WOW bietet eine Schnittstelle zwischen der 16-Bit-Architektur von Windows 3.1 und der 32-Bit-Architektur des Win32-Teilsystems, indem Aufrufe von Diensten mit einem Prozess namens Thunking umgewandelt werden. Thunking ist eine Methode, um 32-Bit-Datenwerte ohne Datenverlust in 16-Bit-Datenwerte umzuwandeln (und umgekehrt). Der eigentliche Mechanismus des Thunking hängt von den Daten ab, die übergeben werden. Alle Aufrufe an die User-, GDI- und Kernelbibliotheken im Win32-API werden in die entsprechenden Aufrufe im Win32-API umgewandelt. Die Abbildung 2.4 veranschaulicht dies.

Abbildung 2.4:  Die Bestandteile des Windows on Windows-Systems (WOW) und deren Interaktion mit dem Win32-Teilsystem

Programme, die im WOW ausgeführt werden, laufen alle in derselben Instanz von Wowexec (dem Programm, das die Systemaufrufe von Win16 zu Win32 behandelt). Dies geschieht, um den Overhead zu reduzieren (jede der Wowexec-Instanzen benutzt Speicher) und um OLE- und Ausschneiden- und -Einfügen-Operationen bei Win16-Programmen zu ermöglichen.

Windows 3.1 implementiert Multitasking mit einer Technik namens »kooperatives Multitasking«. Das Betriebssystem nimmt an, dass sich jedes Programm »gesittet« verhält und den Prozessor gelegentlich frei gibt, damit das nächste Programm ausgeführt werden kann. Selbstverständlich glauben alle Programmierer, dass ihr Programm das Wichtigste auf der Welt ist und niemals den Prozessor freigeben sollte. Deshalb gibt es unter Windows 3.1 viele Performanceprobleme. Windows 2000 nutzt ein »präemptives Multitasking«.

Bei diesem weist das Betriebssystem CPU-Zeit zu und unterbricht jedes laufende Programm, wenn die zugewiesene CPU-Zeit vorüber ist.

Der Threadplaner von Windows 2000 macht einige einzigartige Dinge, damit Win32-Anwendungen korrekt ausgeführt werden. Denken Sie daran, dass alle Threads im präemptiven Multitasking ausgeführt werden. Bei Wowexec kann immer nur der Thread ausgeführt werden, der auch beim letzten Mal ausgeführt wurde. Das heißt, bei jeder Instanz von Wowexec kann immer nur ein Thread aktiv sein und dieser Thread muss den Prozessor freiwillig freigeben, bevor ein anderes 16-Bit-Windows-Programm ausgeführt werden kann. Das heißt, eine 16-Bit-Windows-Anwendung, die den Prozessor nicht freigibt, verhindert, dass andere 16-Bit-Anwendungen ausgeführt werden. Diese Richtlinie wurde implementiert, weil viele Win16-Anwendungen falsche Annahmen darüber treffen, wie sie in Relation zum Rest des Betriebssystems und anderen Windows 3.1-Anwendungen ausgeführt werden, um Daten zurückzuliefern. Wenn das Betriebssystem für die Anwendungen einen anderen Zeitplan entwickelt als echte Windows 3.1-Anwendungen, geht die Kompatibilität zu den Anwendungen verloren.

2.1.7 Das POSIX-Teilsystem

Laut Microsoft wurde das POSIX-Teilsystem entwickelt, damit Benutzer UNIX-Anwendungen unter Windows NT ausführen konnten. POSIX ist ein Standard, der verschiedene Betriebssystemdienste und API-Aufrufe spezifiziert, die Anwendungen zur Verfügung stehen müssen. POSIX steht für Portable Operating System Interface for UNIX.

Es gibt drei Ebenen von POSIX-Kompatibilität. Windows 2000 unterstützt nur die unterste Ebene namens POSIX.1. Diese Ebene spezifiziert einen minimalen Satz an Diensten und erfordert die Unterstützung der Unterscheidung von Groß-/Kleinschreibung bei Dateinamen, die Unterstützung harter Links und die Möglichkeit, Benutzer daran zu hindern, auf Dateien zuzugreifen, wenn sie keine Berechtigung zum Zugriff auf alle übergeordneten Verzeichnisse der Datei haben (Traverse Checking). Damit der Benutzer also die Datei D:\Daten\Dokumente\Foo.doc lesen kann, benötigt er Lesezugriff auf das Stammverzeichnis auf Laufwerk D:, auf das Verzeichnis Daten, auf das Verzeichnis Dokumente und auf die Datei Foo.doc.

Lange Zeit, insbesondere während der Entwurfsphase von Windows NT, war die POSIX-Kompatibilität eine Anforderung an jedes Betriebssystem, das von der Bundesregierung der USA gekauft wurde. Einige Zyniker behaupten sogar, dass Microsoft die POSIX-Kompatibilität nur aus diesem Grund in Windows NT aufgenommen habe. Diese Zyniker liegen vermutlich richtig.

POSIX.1 ist eine so geringe Kompatibilitätsebene, dass sie fast nutzlos ist. POSIX.1-kompatible Systeme müssen kein bestimmtes binäres Dateiformat nutzen. Deshalb können sie nicht notwendigerweise dieselben Programme ausführen. Das System ist auf der Ebene des POSIX.1-Standard so »schwammig«, dass die Portierung von Anwendungen auf ein anderes Betriebssystem mit sehr viel Mühe verbunden ist. Der POSIX.1-Standard spezifiziert keine Netzwerkschnittstelle. Deshalb haben Programme, die für das POSIX-Teilsystem entwickelt werden, keinen Netzwerkzugriff.

Das POSIX-Teilsystem funktioniert, indem die C-Aufrufe in Aufrufe des Win32-Teilsystems umgewandelt werden. Deshalb ist das POSIX-Teilsystem vom Win32-Teilsystem abhängig und kann nichts, was das Win32-Teilsystem nicht ebenfalls könnte. Außerdem führt der Overhead für die Übersetzung dieser Aufrufe dazu, dass POSIX-Anwendungen langsamer sind als entsprechende reine Win32-Programme. Auch hier könnten Zyniker sagen, dass dies ein weiterer Grund ist, Programme nur auf Win32 zu portieren und UNIX und POSIX ganz zu ignorieren.

2.1.8 Das OS/2-Teilsystem

Als Windows NT entwickelt wurde, war es von Microsoft als Ersatz für OS/2 gedacht. Microsoft fand heraus, dass die Windows-Oberfläche wesentlich beliebter war als der Presentation Manager von OS/2. Deshalb beschloss Microsoft, das neue Betriebssystem mit einer Windows-Oberfläche zu erstellen und das Produkt in Windows New Technology (oder Windows NT) umzubenennen.

Das OS/2-Teilsystem ist ein sehr beschränktes Teilsystem, das ursprünglich entwickelt wurde, um OS/2 1.x-Zeichenmodusanwendungen auszuführen. Es kann keine grafischen Anwendungen ausführen und auch keine OS/2 2.x-Programme oder höher. Das OS/2-Teilsystem basiert wie das POSIX-Teilsystem auf der Win32-API. Es konvertiert im Wesentlichen OS/2-API-Aufrufe in Win32-Aufrufe, enthält aber nur das Kern-API von OS/2 1.x und einige grundlegende LAN Manager-Netzwerkaufrufe, um Programmen Netzwerkzugriff zu bieten. Dadurch ist das System dem POSIX-Teilsystem einen Schritt voraus, das keine Netzwerkunterstützung bietet.

2.2 Das Speichermodell und die Speicherverwaltung

Eine der wichtigsten Aufgaben von Betriebssystemen besteht darin, den Speicher zuzuweisen und zu überwachen. Die Festlegung, wie der Speicher für verschiedene Prozesse zugewiesen wird und wie die Prozesse auf den Speicher zugreifen, ist Bestandteil des Speichermodells des Betriebssystems. Bestandteil der Speicherverwaltung ist die Behandlung des physischen Speichers und der Auslagerung von Seiten auf die Festplatte.

2.2.1 Das Speichermodell

Windows 2000 benutzt ein Prozess- und ein Taskmodell, um die Verarbeitung zu beschreiben. Ein Prozess ist ein Objekt, das eine Speicherreservierung und mehrere Tasks besitzt. Ein Task ist eine Ausführungseinheit (d.h. das, was der Kernel ausführt).

In Windows 2000 erhält jeder Prozess einen Speicherraum von 0x00000000 bis 0xFFFFFFFF, den er adressieren kann und der 4 Gbyte Speicher in einem flachen Adressraum entspricht. Auf diese Weise erzeugt Windows 2000 den Speicherschutz.

Was hat es nun mit dem geschützten Speicher auf sich? Stellen Sie sich ein Betriebssystem, wie z.B. Windows 3.1, mit einem gemeinsam genutzten Speicherraum vor. Dies bedeutet, dass alle Programme im selben Adressraum ausgeführt werden. Stellen Sie sich weiterhin vor, dass ein Programmierer ein Programm erzeugt, das Dateien im Arbeitsspeicher ablegt und später aus diesem abruft und anzeigt. Dieses Programm ist eine Textverarbeitung, die immer eine gesamte Datei in den Arbeitsspeicher einliest und sie dann anzeigt (dies ist vermutlich die ungünstigste Vorgehensweise, aber auf diese Weise arbeitet der Editor, Notepad.exe von Windows). Wenn ein Programm Speicher benötigt, bittet es das Betriebssystem darum. Das Betriebssystem liefert entweder einen Zeiger auf den Speicher zurück oder die Meldung »Ich kann Dir nicht mehr Speicher zur Verfügung stellen«. Wenn der Programmierer also 2 Kbyte Speicher anfordert und die Datei tatsächlich 3 Kbyte groß ist, wird die Datei in den Arbeitsspeicher eingelesen. Wenn die 2 Kbyte überschritten sind, wird die Datei trotzdem weiter eingelesen. Das ist etwa so, als würden 15 kg Kunstdünger in einen 10-kg-Sack gestopft. Die restlichen 5 kg müssen irgendwo hin gelangen. Beim Kunstdünger werden sie auf dem ganzen Boden verstreut. Beim Speicher wird das 1 Kbyte mit Daten einfach in den weiteren Speicheradressraum geschrieben.

Bei einem solchen Speicherüberfluss gibt es nur zwei Optionen. Die Daten werden entweder in den Speicher geschrieben, den das Betriebssystem bisher noch nicht zugewiesen hat, oder sie werden in den Speicher geschrieben, den ein anderes Programm nutzt. Weil es keinen Speicherschutz gibt, merkt das Betriebssystem von diesem Problem nichts. In der Zwischenzeit wurden die Programmdaten des Programms, das im Adressraum neben der Textverarbeitung ausgeführt wird, einfach von den Daten aus der Textdatei überschrieben. Wenn das Programm nun ausgeführt werden soll, stürzt es ab. Wie es Murphys Gesetz voraussagt, wird im schlimmsten Fall das Betriebssystem überschrieben. Und das passiert normalerweise auch.

Dies ist nun allgemein bekannt, aber früher (Ende der achtziger und Anfang der neunziger Jahre) war dies bei PC-basierten Betriebssystemen ein großes Problem. Das einzige PC-orientierte Betriebssystem, das einen Speicherschutz bot, war OS/2, aber dieses Betriebssystem war nicht sehr beliebt.

Wenn eine Anwendung versucht, in einen fremden Speicherraum zu schreiben, resultiert dies in einer Schutzverletzung. Eine solche Schutzverletzung ist die Allgemeine Schutzverletzung, die bei den meisten Windows-Betriebssystemen üblich ist. Sie tritt auf, wenn eine Anwendung mit einem Lese- oder Schreibzugriff unberechtigt auf einen Speicherbereich zugreift.

Warum führen Schutzverletzungen zum Abbruch von Programmen? Eine weitere Möglichkeit wäre es, den Speicher vor dem Schreibzugriff zu schützen und das Programm weiterhin auszuführen. Angenommen, ein Benutzer verwendet dieses alternative Betriebssystem und erstellt in einer Textverarbeitung ein Dokument. Dann beginnt die Textverarbeitung, in einen unerlaubten Speicherbereich zu schreiben. Das Betriebssystem ignoriert den Schreibvorgang, weil dieser unzulässig ist, und der Benutzer versucht, den Text in eine Datei zu speichern. Aber die Datei befindet sich nicht im Speicher. In diesem Fall hat der Benutzer dann nicht nur eine kleine Datenmenge verloren, sondern vermutlich die Arbeit eines ganzen Nachmittags.

Warum kann das Betriebssystem das Programm nicht einfach darüber in Kenntnis setzen, dass es etwas falsch macht? So funktionieren Programme eben nicht, und selbst, wenn sie es täten, muss ein Programm ernsthafte Probleme haben, um eine Schutzverletzung zu verursachen. Und dies ist normalerweise schlechte Programmierung. Wenn ein Programm so schlecht programmiert ist, dass es eine Schutzverletzung verursacht, wird es dann mit einer Meldung des Betriebssystems etwas anfangen können, die besagt, dass es seine Vorgehensweise ändern soll? Es wird diese Meldung sehr wahrscheinlich einfach ignorieren und entweder abstürzen, weil das Betriebssystem seine Ausführung unterbricht, oder die Schutzverletzung komplett übergehen, was in einem Datenverlust resultiert. Auch diese Lösung ist sicherlich nicht wünschenswert. Deshalb bricht Windows 2000 ein Programm eher ab, als einen fortwährenden Datenverlust zu riskieren.

Eine Möglichkeit sicherzustellen, dass Programme nicht mehr Speicher benutzen als sie benötigen und damit ihre Speicherabbilder beschädigen, besteht darin, zu verhindern, dass sie auf die Adressräume anderer Programme zugreifen können. Wenn das Programm nur Adressen zwischen 0 und 4 Gbyte kennt, und dieser Raum zum Programm gehört, kann das Programm möglicherweise keine anderen Daten überschreiben. Auf diese Weise wird Speicher unter Windows 2000 verwaltet. Jeder Prozess erhält seinen eigenen virtuellen 4-Gbyte-Adressraum, und kann damit machen, was er möchte. In Abbildung 2.5 finden Sie ein Programm, das diese Funktionsweise veranschaulicht.

Abbildung 2.5:  Das Speichermodell für den virtuellen Arbeitsspeicher. Jede Anwendung hat ihren eigenen Adressraum und weiß nichts von den Adressräumen anderer Anwendungen.

Prozesse müssen noch immer Speicher vom Betriebssystem anfordern, bevor sie diesen nutzen können, obwohl ihnen ein 4-Gbyte-Adressraum zur Verfügung steht. Dies hat einen einfachen Grund: Die Speicherverwaltung muss wissen, wie viel Speicher ein Prozess benötigt, um feststellen zu können, ob genügend Systemspeicher für die Ausführung des Programms vorhanden ist und damit die virtuelle Speicherverwaltung (VMM) weiß, wie der Speicher adressiert werden soll.

Für Prozesse gibt es eine weitere Beschränkung. Der 4-Gbyte-Adressraum ist nicht vollständig nutzbar. Ein Teil des Adressraums ist für das System reserviert. In Windows 2000 Professional und Windows 2000 Server liegt die Grenze bei 2 Gbyte für das System und die Anwendung. Bei Windows 2000 Advanced Server und Windows 2000 Datacenter liegt die Trennungslinie bei 3 Gbyte für die Anwendung und 1 Gbyte für das System. Diese Änderung wird über einen Schalter in der Datei Boot.ini ermöglicht. Werfen Sie einen Blick auf die nachfolgende Boot.ini-Datei. Die Einträge im Bereich [operating systems] zeigen, wie der /3GB-Schalter zum Start von Windows 2000 hinzugefügt wurde:

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINNT
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINNT=
     "Windows 2000 Advanced Server" /3GB
multi(0)disk(0)rdisk(0)partition(2)\WINNT=
     "Windows 2000 Advanced Server [VGA mode]" /basevideo /sos

Bei einer echten Boot.ini-Datei gibt es beim Gleichheitszeichen keinen Zeilenumbruch. Der Zeilenumbruch ist hier durch die geringe Seitenbreite des Buchs bedingt.

Damit eine Anwendung das neue Speichermodell nutzen kann, muss das Betriebssystem wissen, dass das Programm dazu in der Lage ist. Im Header der .exe-Datei wird ein Attribut namens IMAGE_FILE_LARGE_ADDRESS_AWARE aktiviert, d.h. auf den Wert 1 gesetzt. Im Ordner Support der Windows 2000 Advanced Server-CD finden Sie ein Programm namens Imagecfg.exe, das das Attribut bei ausführbaren Dateien setzt. Um z.B. dafür zu sorgen, dass die Datei Accrecv.exe das neue Speichermodell nutzt, dient folgender Befehl.

Imagecfg -1 ACCRECV.EXE

Der Befehl kann mit dem Befehl imagecfg -0 wieder rückgängig gemacht werden.

2.2.2 Die Speicherverwaltung

Die virtuelle Speicherverwaltung (VMM = Virtual Memory Manager) behandelt die Speicherzuweisung, die Auslagerung und die Übersetzung der Anforderungen von Anwendungen eines bestimmten Speicherblocks in eine Leseanweisung für einen bestimmten Block des physischen Speichers.

Bevor die Speicherverwaltung beschrieben wird, müssen noch ein paar wesentliche Punkte genannt werden. Windows 2000 versucht, jedes Bit des Systemspeichers auszunutzen. Für den Programmstart bleibt nur eine geringe Speichermenge verfügbar. Wenn dieser Speicher von keiner Anwendung genutzt wird, wird er vom Betriebssystem als Zwischenspeicher für die Festplatte genutzt. Wenn ein Computer als Dateiserver läuft, gibt es keine Möglichkeit, Windows 2000 mitzuteilen, dass Speicher als Zwischenspeicher genutzt werden soll - dies geschieht bereits.

Außerdem gibt es noch den physischen Arbeitsspeicher, d.h. die Chips im Computer und den virtuellen Arbeitsspeicher (der sich eigentlich auf der Festplatte befindet.). Der Arbeitsspeicher ist in Einheiten aufgeteilt, die Seiten genannt werden. Eine Seite besteht aus 4 Kbyte Arbeitsspeicher. In dieser Größe verschiebt die virtuelle Speicherverwaltung auch Arbeitsspeicher. Eine Seite existiert an mindestens einem von drei Orten: dem physischen Speicher, der Auslagerungsdatei oder in einer Liste der Seiten, die ausgelagert werden sollen (die sog. Warteliste).

Die virtuelle Speicherverwaltung muss einen Überblick über den gesamten virtuellen Arbeitsspeicher haben, der für einen Prozess reserviert ist, und auch den Status des Arbeitsspeichers prüfen und sehen, ob sich der Prozess tatsächlich im Arbeitsspeicher befindet oder auf die Festplatte ausgelagert wurde. Die virtuelle Speicherverwaltung zeichnet auch auf, ob eine einzelne Seite Code oder Daten enthält. Die virtuelle Speicherverwaltung kennt den Unterschied zwischen Code (ausführbare Programme, die in den Speicher geladen werden) und Daten (Informationen, die von Code benutzt werden). Code ist schreibgeschützt, auf Daten besteht ein Lese-/Schreibzugriff. Dies hilft der virtuellen Speicherverwaltung festzustellen, wenn ein Programm »verrückt spielt« und versucht, in einem unerlaubten Speicherbereich zu schreiben. Die virtuelle Speicherverwaltung behandelt alle Lese- und Schreibanforderungen an den Arbeitsspeicher und weiß somit, wenn ein Programm versucht, in schreibgeschützte Daten zu schreiben. Derartige Situationen lassen sich leicht verhindern.

Die virtuelle Speicherverwaltung führt auch Buch über den physischen Speicher im Computer: er zeichnet auf, welche Seiten zugewiesen wurden, zu welchen Prozessen diese Seiten gehören und wann die Seiten zuletzt benutzt wurden (d.h. gelesen oder beschrieben wurden).

Wenn die virtuelle Speicherverwaltung eine Anforderung erhält, Daten für ein Programm aus einem bestimmten Speicherbereich zu lesen, konsultiert die virtuelle Speicherverwaltung eine Tabelle, die eine Liste aller Seiten enthält, die zu dem Programm gehören, und ein Statusbit, das angibt, ob sich die Seite im physischen Speicher befindet. Ist dies der Fall, liefert die virtuelle Speicherverwaltung die angeforderten Daten direkt an das Teilsystem zurück. Befinden sich die Informationen nicht im physischen Speicher, prüft die virtuelle Speicherverwaltung seine Warteliste um festzustellen, ob die Seite dort verfügbar ist. Ist dies der Fall, wird versucht, die Seite von der Festplatte zu laden.

Wenn die virtuelle Speicherverwaltung die Seite nicht findet, resultiert daraus ein Seitenfehler. Es gibt zwei Arten von Seitenfehlern. Ein harter Seitenfehler tritt auf, wenn die virtuelle Speicherverwaltung die gesuchte Seite weder im physischen Speicher noch in der Warteliste findet. Ein weicher Seitenfehler tritt auf, wenn die virtuelle Speicherverwaltung die Seite zwar nicht im physischen Speicher findet, wohl aber in der Warteliste. Die virtuelle Speicherverwaltung ruft die Seite dann wieder in den physischen Speicher, ohne sie von der Festplatte lesen zu müssen.

Wenn die virtuelle Speicherverwaltung entweder Speicher als neuen Speicher für ein Programm zuweisen oder eine Seite von der Festplatte lesen muss, wird eine Tabelle überprüft, die eine Liste der freien Seiten enthält. Die Speicherverwaltung weist dann die benötigte Anzahl von Seiten im Speicher zu. Wenn der freie Arbeitsspeicher einen bestimmten Wert unterschreitet, startet die virtuelle Speicherverwaltung einen Prozess um festzustellen, welche Seiten ausgelagert werden können. Erinnern Sie sich daran, wie die virtuelle Speicherverwaltung feststellt, ob Seiten im physischen Speicher benutzt werden? Diese Informationen dienen auch dazu festzulegen, welche Seiten im physischen Speicher bleiben müssen und welche auf die Festplatte ausgelagert werden können.

Die virtuelle Speicherverwaltung bestimmt auf der Basis des Zeitpunkts der letzten Nutzung, welche Seiten auf die Warteliste gesetzt werden. Sie benutzt einen LRU-Algorithmus (LRU = Least Recently Used) um festzulegen, welche Seiten auf die Festplatte ausgelagert werden. Seiten, die schon eine Weile nicht benutzt wurden, werden ausgelagert, wohingegen häufig benutzte Seiten im Arbeitsspeicher bleiben.

Um diese Aktivität zu überwachen, stehen im Systemmonitor zahlreiche Attribute zur Verfügung. Eine ausführliche Beschreibung des Systemmonitors finden Sie in Kapitel 24.


© Copyright Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH
Elektronische Fassung des Titels: Windows 2000 Server Kompendium, ISBN: 3-8272-5611-9 Kapitel: Architektur