Global Descriptor Table — Änderungen 4359 → 4360

Zeile 93: Zeile 93:
 
| 0    || 0x1 || Available Bit      || Dieses Bit steht dem Programmierer zur freien Verfügung.
 
| 0    || 0x1 || Available Bit      || Dieses Bit steht dem Programmierer zur freien Verfügung.
 
|}
 
|}
 +
 +
== Laden der GDT ==
 +
Nachdem der Kernel eine GDT im Speicher liegen hat, die er für seine Segmente verwenden möchte, muss er das Register GDTR ändern. Dieses Register enthält die Adresse und Länge der GDT und wird über den Befehl '''lgdt''' geladen. Da das Register 6 Bytes breit ist, kann dieser Befehl den neuen Wert nicht direkt als Operand entgegennehmen, sondern erwartet einen Pointer auf eine Speicherstelle, die diese 6 Bytes enthält:
 +
 +
<c>static long long unsigned int gdt[GDT_ENTRIES];
 +
 +
// ...
 +
 +
struct {
 +
    unsigned short int length;
 +
    void* pointer;
 +
} __attribute__((packed)) gdtp = {
 +
    .length = GDT_ENTRIES * 8,
 +
    .pointer = gdt,
 +
};
 +
asm volatile("lgdt %0" : : "m" (gdtp));</c>
 +
 +
Dadurch wird allerdings nur der Verweis auf die Tabelle geändert, tatsächliche Auswirkungen hat die Änderung noch nicht. Auf die Tabelle wird nur zugegriffen, wenn ein Segmentregister neu geladen wird. Daher müssen jetzt noch alle Segmentregister neu geladen werden:
 +
 +
<asm>
 +
mov $0x10, %eax
 +
mov %eax, %ds
 +
mov %eax, %es
 +
mov %eax, %ss
 +
ljmp $0x8, $.1
 +
.1:
 +
</asm>