Der Wert dieses Flags gibt die Privilegierungsstufe an, die ein Code-Segment mindestens aufweisen muß, um auf den I/O-Adreßraum zugreifen zu können, d.h. es muß gelten CPL IOPL. Ist der CPL des aktuellen Task größer (niedrigere Privilegierungsstufe), so führen die I/O-Befehle IN, OUT, INS und OUTS zu der bereits hinlänglich bekannten Exception "allgemeiner Protection-Fehler". Vernünftige Anwendungsprogramme unter einem vernünftigen Betriebssystem führen solche Zugriffe ausschließlich über das Betriebssystem aus. Weniger vernünftige Anwendungsprogramme versuchen das direkt, um die Performance zu erhöhen oder andererseits bestimmte Komponenten überhaupt ansprechen zu können. Neben den vier bereits erwähnten I/O-Befehlen sind auch CLI (Clear Interrupt Flag) und STI (Set Interrupt Flag) vom IOPL-Flag abhängig. Diese sechs Befehle werden als IOPL-sensitive Befehle bezeichnet, da der Wert des IOPL-Flag Einfluß auf ihre Ausführung hat.
Sinn und Zweck dieser Einschränkung werden sofort einsichtig, betrachtet man den Fall, daß eine Systemfunktion beispielsweise einen Datensatz von der Festplatte liest, dabei durch einen Task-Switch unterbrochen wird, und der neu aufgerufene Task durch einen unmittelbaren Zugriff auf die Steuerregister im Festplattencontroller "dazwischenfunkt". In welchen Zustand sich die unterbrochene Systemroutine nach einem erneuten Task-Switch befindet, ist völlig unvorhersehbar, der PC verabschiedet sich oder zerstört sogar Daten.
Ein Task kann das IOPL-Flag nur über die Befehle POPF (Pop Flags) und PUSHF (Push Flags) verändern. Zur Änderung des IOPL-Flags steht kein expliziter Befehl zur Verfügung (wie z.B. CLI oder STI für das Interrupt-Flag). Die beiden genannten Befehle sind jedoch privilegiert, d.h. sie können nur von einem Codesegment mit CPL=0 ausgeführt werden. Diese Stufe ist üblicherweise dem Betriebssystem-Kernel vorbehalten - die Anwendungsprogramme können das IOPL-Flag nicht verändern. Bei einem solchen Versuch löst der Prozessor die Exception "allgemeiner Protection-Fehler" aus. Da die Flags jedoch Teil des TSS sind und sich somit von Task zu Task unterscheiden, kann durchaus ein Task Zugriff auf den I/O-Adreßraum besitzen, ein anderer dagegen nicht.
Diese Strategie der globalen Absicherung des I/O-Adreßbereichs über das IOPL-Flag ist bereits im 80286 implementiert. Der i386 kann die Ports zusätzlich individuell schützen. Diese Schutzstrategie für die Ports ist besonders im Hinblick auf den Virtual 8086 Mode implementiert worden. [Wie auch die Paging-Mechanismen, werde ich auf den Virtual 8086 Mode nicht näher eingehen, er sei nur der Vollständigkeit wegen erwähnt.]
|