Neben dem globalen Schutz durch das IOPL-Flag kennt der i386 einen weiteren Schutzmechanismus für Zugriffe auf den I/O-Adreßbereich, nämlich die sogenannte I/O-Permission-Bit-Map. Sie ist im TSS des jeweiligen Task abgelegt, verschiedene Tasks können also unterschiedliche I/O-Permission-Bit-Maps besitzen. Der Eintrag I/O-Map-Basis im TSS-Deskriptor gibt den Offset innerhalb des TSS an, bei dem die I/O-Permission-Bit-Map beginnt. Sie erstreckt sich bis zum Ende des TSS, wie es im Limiteintrag des TSS-Deskriptors festgelegt ist. Den Raum zwischen dem Eintrag I/O-Map-Basis und dem Beginn der I/O-Permission-Bit-Map kann das Betriebssystem verwenden, um eigene Informationen abzulegen. Die I/O-Permission-Bit-Map muß also nicht unmittelbar nach den Einträgen für die Register im TSS beginnen. Vielmehr kann ein nahezu beliebig großer Raum zwischen dem Eintrag I/O-Map-Basis und dem Beginn der I/O-Permission-Bit-Map zur Verwendung durch das Betriebssystem vorgesehen werden, das dort eigene Informationen ablegt. Zu beachten ist, daß das höchstwertige Byte der Map, d.h. das Byte unmittelbar vor dem Ende des TSS den Wert 11111111b (=0ffh) besitzen muß. Für die I/O-Permission-Bit-Map kann nur ein i386-TSS verwendet werden, da das 80286-TSS keinen Eintrag I/O-Map-Basis hat.
Eine gültige I/O-Permission-Bit-Map ist immer dann vorhanden, wenn die I/O-Map-Basis im TSS noch innerhalb des TSS liegt. Zeigt der Wert der Basis über das TSS hinaus, so ignoriert der i386 alle Prüfungen im Zusammenhang mit der I/O-Permission-Bit-Map, der Zugriffsschutz für den I/O-Adreßbereich erfolgt allein durch das IOPL-Flag.
Die I/O-Permission-Bit-Map stellt praktisch einen Zugriffsschutz zweiter Ebene dar: Wenn die Werte von CPL und IOPL dem aktiven Task einen Zugriff auf den I/O-Adreßbereich gestatten, so untersucht der i386 anschließend zusätzlich noch die I/O-Permission-Bit-Map, um zu ermitteln, ob der gewünschte Port auch tatsächlich angesprochen werden darf. Das geschieht auf einer eins-zu-eins Zuordnung von I/O-Adressen und dem entsprechenden Bit in der Map. Dem Port mit der Adresse 0 ist das Bit mit dem Offset 0 innerhalb der Map zugeordnet, dem Port 1 das Bit 1 usw. Ist das einem Port entsprechende Bit in der Map gesetzt, also gleich 1, so löst der i386 beim Zugriff auf den zugehörigen Port die Exception "allgemeiner Protection-Fehler" aus. Ist das Bit gelöscht, so fährt der Prozessor mit der I/O-Operation fort.
Die Länge der Map bestimmt die Zahl der so zusätzlich geschützten Ports. Es ist also nicht erforderlich, daß die I/O-Permission-Bit-Map alle I/O-Adressen abdeckt. Allen von der Map nicht erfaßten I/O-Ports wird automatisch ein gesetztes Bit zugeordnet, d.h. ein Zugriff auf die außerhalb der Map liegenden Ports führt automatisch zu einer Exception. In einem ISA-PC reicht es z.B. aus, die 3ffh niederwertigsten Ports durch eine Map abzudecken. Ein Zugriff auf Ports mit höheren Adressen löst eine Exception aus. Das ermöglicht neben der Schutzwirkung von Programmen und dem System eine wesentlich genauere Lokalisierung von Bugs.
Zu beachten ist, daß 16-Bit-Ports zwei und 32-Bit-Ports vier aufeinanderfolgende Bits zugeordnet sind. Nur wenn beide bzw. alle vier zugeordneten Bits gleichzeitig gelöscht sind, kann der i386 die I/O-Operation fortsetzen. Ist auch nur eines der Bits gleich 1, so löst der Prozessor eine Exception aus.
Beispiel:
Die Bit-Map lautet: {11111111} [11001101 00110000 11010100]
{Ende der Map} [I/O-Permission-Bit-Map]
Fall: 8-Bit-Ports
Geschützt sind die Ports 2, 4, 6, 7, 12, 13, 16, 18, 19, 22, 23
Ungeschützt sind die Ports 0, 1, 3, 5, 8, 9, 10, 11, 14, 15, 17, 20, 21
Fall: 16-Bit-Ports
Geschützt sind die Ports 2, 4, 6, 12, 16, 18, 22
Ungeschützt sind die Ports 0, 8, 10, 14, 20
Fall: 32-Bit-Ports
Geschützt sind die Ports 0, 4, 12, 16, 20
Ungeschützt ist der Port 8
|