In English

�bersetzung von Philipp Strebl (viele danke!)

Was ist protected mode?

Die CPU des 8088 im urspr�nglichen IBM PC war nicht besonders erweiterungsf�hig. Vor allem gab es keinen einfachen Weg, auf mehr als ein MB physischen Speicher zuzugreifen. Um dieses Problem zu beseitigen und trotzdem Abw�rtskompatibilit�t zu wahren, entwickelte Intel die 80286 CPU mit zwei Ausf�hrungsmodi: dem real mode, in dem der 80286 sich wie ein schneller 8088 verh�lt, und den protected mode (heute als 16-bit protected mode bezeichnet). Protected mode erlaubt Programmen den Zugriff auf mehr als ein MB physischen Speicher und sch�tzt gleichzeitig vor falscher Verwendung von Speicher (zum Beispiel der Ausf�hrung eines data segment als code, oder dem Schreiben in ein code segment). Eine verbesserte Version, 32-bit protected mode, wurde mit der 80386 CPU pr�sentiert.


Was unterscheidet protected mode von real mode?

Unterschiede zwischen protected mode und real mode:

real mode 16-bit protected mode 32-bit protected mode
Segmentbasisaddresse 20-bit (1 MB range) = 16 * Segmentregister 24-bit (16 MB range), im descriptor 32-bit (4 GB range), im descriptor
Segmentgr��e (h�chstens) 16-bit, 64 KB (fix) 16-bit, 1 B - 64 KB 20-bit, 1 B - 1 MB oder 4 KB - 4 GB
Segmentschutz nein ja ja
Segmentregister segment base adr / 16 selector selector


Ich dachte protected mode kommt ohne segmentierten Speicher aus...

Die Segmente sind immer noch da, aber im 32-bit protected mode ist es m�glich, das segment limit, d.h. die Grenze f�r die Gr��e eines einzelnen Segments, die im real mode fix bei 64 KB liegt, auf 4 GB zu setzen. Das ist das Maximum an physischem Speicher, das von einer CPU mit 32-bit address bus �berhaupt addressiert werden kann. Dadurch "verschwinden" die Segmente, weil es nur ein (sehr gro�es) Segment mehr gibt (oder geben kann). Trotzdem bleiben andere Schutzmechanismen wirkungsvoll. Einzig und allein diese Tatsache machte 32-bit protected mode beliebt.


Was ist ein descriptor?

Im real mode gibt es wenig, was man �ber die Segmente wissen muss. Jedes ist 64 KB gro� und man kann damit machen, was man will: Daten darin speichern, den Stack hineinplatzieren oder code ausf�hren, der im jeweiligen Segment gespeichert ist. Die base address des Segments ist einfach das 16-fache des Werts in einem der Segmentregister. Im protected mode brauchen wir neben der base address eines Segments auch seine maximale Gr��e und einige flags, die seinen Verwendungszweck angeben. Diese Information kommt in einen 8 bytes gro�en record mit dem klingenden Namen descriptor:

Der Aufbau eines code/data segment descriptor:

Niedrigstes byte byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 H�chstes byte
limit 7:0 limit 15:8 base 7:0 base 15:8 base 23:16 access flags, limit 19:16 base 31:24

Das ist ein 32-bit (80386) descriptor. Bei 16-bit (80286) descriptors sind die beiden h�chsten bytes (limit 19:16 und base 31:24) auf 0 gesetzt. Das access-byte gibt die Verwendung des Segments an (data segment, stack segment, code segment etc.).

Der Aufbau eines access byte:

H�chstes bit present present bit: Muss auf 1 gesetzt sein, um den Zugriff auf das Segment zu gestatten
bits 6, 5 privilege privilege bits: 0 ist das h�chste Niveau an privilege (Ring 0), 3 ist das niedrigste (Ring 3)
bit 4 1 f�r code und data/stack segments. Wenn nicht gesetzt, handelt es sich um ein system segment.
bit 3 executable executable bit: Wenn dieses bit als Wert 1 hat, ist dieses Segment code segment, sonst handelt es sich um ein stack/data segment
bit 2 expansion direction/conforming expansion direction (stack/data segment): Wenn dieses bit den Wert 1 hat, w�chst das Segment (den Adressen nach) nach unten und offsets m�ssen gr��er als das limit sein.
conforming (code segment): steht in Verbindung mit privilege
bit 1 writable/readable writable (stack/data segment): Wenn dieses bit den Wert 1 hat, kann in das Segment geschrieben werden
readable (code segment): Wenn dieses bit den Wert 1 hat, kann von diesem Segment gelesen werden (in code segments kann nicht geschrieben werden)
Niedrigstes bit accessed accessed bit: Dieses bit wird gesetzt wann immer aus dem Segment gelesen oder in das Segment geschrieben wird.

Der Wert des 4-bit flag in byte 6 eines descriptor ist nur f�r 32-bit Segmente nicht 0:

Highest bit Bit 6 Bit 5 Bit 4
Granularity Default Size 0 0

Das granularity bit (G) entscheidet, ob das segment limit in Einheiten zu 4 KB Seiten (G=1) oder ob es in Einheiten zu einem byte (G=0) angegeben ist.

Im Falle der Verwendung eines Segments als stack segment wird das default size bit (D) auch als B (Big) bit bezeichnet und legt fest, ob 16- oder 32-bit Werte auf den Stack gelegt werden (mit den Anweisungen push und pop). Wird das Segment als code segment verwendet, gibt das D bit an, ob Anweisungen prinzipiell in 16-bit (D=0) oder 32-bit (D=1) Einheiten verarbeitet werden. Um etwas n�her darauf einzugehen: Ist das D bit gesetzt, dann ist das Segment USE32, benannt nach der Assemblerdirektive mit demselben Namen. Die folgende Sequenz von hexadezimalen bytes:

B8 90 90 90 90

wird von der CPU als eine 32-bit Anweisung betrachtet und w�rde in Assembler folgenderma�en lauten:

mov eax, 90909090h

Ist das D bit nicht gesetzt, ist das Segment USE16, also 16-bit code, und die gleiche Sequenz von bytes w�rde wie folgt interpretiert:

mov ax, 9090h
nop
nop

Zwei spezielle opcode bytes, n�mlich das operand size prefix und das address length prefix kehren die Wirkung des D bit f�r das Ziel beziehungsweise f�r die Quelle der unmittelbar folgenden Anweisung um.

Bit 4 des access byte ist gesetzt, wenn ein code oder data/stack segment vorliegt. Wenn das bit den Wert 0 hat, handelt es sich um ein system segment. Davon gibt es wiederum verschiedene Varianten:

task state segment (TSS) Wird zur Vereinfachung des multitasking verwendet. Die CPU vom 80386 aufw�rts kennt vier Untertypen des TSS.
local descriptor table (LDT) Hier k�nnen tasks anstatt im GDT ihre eigenen privaten descriptors speichern.
gate Kontrolliert �berg�nge der CPU von einem privilege-Niveau zu einem anderen. gate descriptors haben einen anderen Aufbau als die �brigen descriptors.

Aufbau eines gate descriptor:

Niedrigstes byte byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 H�chstes byte
offset 7:0 offset 15:8 selector 7:0 selector 15:8 word count 4:0 access offset 23:16 offset 31:24

Beachten Sie das selector-Feld. gates arbeiten �ber Umwege und ben�tigen einen eigenen code oder ein eigenes TSS, um zu funktionieren.

Der Aufbau des access byte eines system segment descriptor:

H�chstes bit bits 6, 5 bit 4 bits 3, 2, 1, 0
Present Privilege 0 Type

Die unterschiedlichen system segment-Typen:

0 ung�ltig 8 ung�ltig
1 verf�gbares '286 TSS 9 verf�gbares '386 TSS
2 LDT 10 undefiniert, reserviert
3 belegtes '286 TSS 11 belegtes '386 TSS
4 '286 call gate 12 '386 call gate
5 task gate 13 undefiniert, reserviert
6 '286 interrupt gate 14 '386 interrupt gate
7 '286 trap gate 15 '386 trap gate

So. Wenn das Verwirrung stiften sollte: Es reicht vorerst vollauf, wenn Sie sich merken, dass die Haupttypen von system segments TSS (task state segment), LDT (local descriptor table) und gates sind.


Wo befinden sich die descriptors?

Die descriptors sind in einer Tabelle, dem global descriptor table (GDT), dem interrupt descriptor table (IDT) oder in einem der local descriptor tables (LDT) aufgelistet. Die CPU verf�gt �ber 3 Register, n�mlich den GDTR, den IDTR (wenn interrupts benutzt werden) und den LDTR (wenn ein LDT benutzt wird) - das "R" am Ende jeder Bezeichnung steht f�r "Register". Diese Register m�ssen jeweils die Addresse des GDT, des IDT beziehungsweise des LDT beinhalten. Jede descriptor-Tabelle kann bis zu 8192 descriptors enthalten (eine Tabelle ist daher 64 KB gro0).


Was ist ein Selektor?

Im protected mode enthalten die Segmentregister selectors, die auf einen descriptor tables verweisen. Nur die h�chsten 13 bits des selector werden f�r diesen Verweis gebraucht, das n�chstniedrigere bit w�hlt zwischen dem GDT und dem LDT aus. Die beiden niedrigsten bits legen ein privilege-Niveau fest (0-3).


Wie aktiviere ich den protected mode?

Den protected mode zu aktivieren ist eigentlich recht einfach. Man muss:


Wie komme ich zur�ck in den real mode?

Dazu muss man am '386:

Vor dem Zur�ckschalten in den real mode m�ssen CS und SS selectors enthalten, die auf "real mode-geeignete" descriptors verweisen. real mode-geeignet bedeutet, dass sie ein limit von 64 KB haben, byte-granular sind, d.h. das flags nibble=0, das sie nach oben wachsen, beschreibbar (gilt nur f�r data/stack segments) und present sind (access byte=1xx1001xb).

Am '286 kann man nicht einfach das PE bit auf 0 setzen, um den protected mode zu verlassen. Die einzige M�glichkeit ist, die CPU neu zu starten. Das kann geschehen indem man dem keyboard controller die Tastenkombination zum Warmstart �bergibt oder indem man die CPU triple-faulted (siehe die Website von Robert Collins).


Welche Fallen gibt es?


Wenn Sie einfach beginnen wollen, versuchen Sie es mit diesen Ratschl�gen: