GDT in C
Posted: Thu Jan 29, 2004 8:59 am
Hi.
I'm trying to setup GDT in my C kernel, but there's something wrong.
The bootloader sets up a GDT for me to use, but I want to set one up in my kernel.
Someone said I can get the address of the GDT with LGDT, how?
And, when will I have to access the GDT in my kernel, do I have to access it when I create a process?
I'm trying to setup GDT in my C kernel, but there's something wrong.
The bootloader sets up a GDT for me to use, but I want to set one up in my kernel.
Someone said I can get the address of the GDT with LGDT, how?
And, when will I have to access the GDT in my kernel, do I have to access it when I create a process?
Code: Select all
//////////////////////////////////////////////////////////////////////////
// GDT
typedef struct {
uint16 low_limit;
uint16 low_base;
uint8 middle_base;
uint8 settings;
uint8 high_limit:4;
uint8 attributes:3;
uint8 granularity:1;
uint8 high_base;
} x86_gdt;
//////////////////////////////////////////////////////////////////////////
// GDT Descriptor
typedef struct {
uint16 limit;
x86_gdt* base;
} __attribute__ ((packed)) gdtr;
gdtr GDTR;
x86_gdt GDT[20] = {0};
int InitializeMemManager() {
// Null segment
GDT[0].low_limit = 0x0;
GDT[0].low_base = 0x0;
GDT[0].middle_base = 0x0;
GDT[0].settings = 0x0;
GDT[0].high_limit = 0x0;
GDT[0].attributes = 0x0;
GDT[0].granularity = 0x0;
GDT[0].high_base = 0x0;
// Code segment
GDT[1].low_limit = 0xFFFF;
GDT[1].low_base = 0x0;
GDT[1].middle_base = 0x0;
GDT[1].settings = 0x9A; // Non-conforming, PL0
GDT[1].high_limit = 0xF;
GDT[1].attributes = 0x4;
GDT[1].granularity = 0x0;
GDT[1].high_base = 0x0;
// Data segment
GDT[2].low_limit = 0xFFFF;
GDT[2].low_base = 0x0;
GDT[2].middle_base = 0x0;
GDT[2].settings = 0x92; // Write access, expand down
GDT[2].high_limit = 0xF;
GDT[2].attributes = 0x4;
GDT[2].granularity = 0x0;
GDT[2].high_base = 0x0;
GDTR.limit = 256 * (sizeof(x86_gdt) - 1);
GDTR.base = GDT;
gdtr* GDTRPtr = &GDTR;
kprintf("GDT @ 0x%X\n", GDTRPtr);
outb(0x70, inb(0x70) | 0x80); // Disable NMI
asm volatile("xor %%ax, %%ax \n\t" \
"mov %%ax, %%ds \n\t" \
"lgdt (%0) ": :"p" (GDTRPtr));
WriteCR0(ReadCR0() | 0x80000000);
outb(0x70, inb(0x70) & 0x7F); // Enable NMI
return 0;
}