[SOLVED] Triple-fault on loading a GDT
Posted: Wed Apr 19, 2017 3:10 pm
I am trying to load a GDT. I have an array of entries, with each entry created like so:
I then load the GDT and switch to the new code and data segment like so:
It triple faults, but not where I thought it would (the far jump). Instead, it seems to start executing some random code after `mov ds, ax` (which is weird because I haven't changed the CS yet??). I usually try to be fairly self-sufficient with debugging, but I can't find the relevant part of the Intel manual and the wiki seems to have slightly conflicting methods. I would appreciate some pointers in what I've done wrong; thanks in advance!
Code: Select all
static uint64_t gdtEntries[NUM_GDT_ENTRIES];
static struct gdt_pointer
{
uint16_t limit;
uint32_t firstEntryAddr;
} gdtPtr;
static uint64_t CreateGDTEntry(uint32_t base, uint32_t limit, uint16_t type)
{
uint64_t entry = 0u;
entry = limit & 0x000F0000;
entry |= (type << 8u) & 0x00F0FF00;
entry |= (base >> 16u) & 0x000000FF;
entry |= base & 0xFF000000;
entry <<= 32u;
entry |= base << 16u;
entry |= limit & 0x0000FFFF;
return entry;
}
extern void FlushGDT(uint32_t);
void InitGDT()
{
gdtPtr.limit = sizeof(uint64_t) * NUM_GDT_ENTRIES;
gdtPtr.firstEntryAddr = (uint32_t)&gdtEntries;
gdtEntries[0u] = CreateGDTEntry(0u, 0u, 0u); // Null segment
gdtEntries[1u] = CreateGDTEntry(0u, 0xFFFFFFFF, 0x9A); // Kernel code segment
gdtEntries[2u] = CreateGDTEntry(0u, 0xFFFFFFFF, 0x92); // Kernel data segment
FlushGDT((uint32_t)&gdtPtr);
}
Code: Select all
; Inputs: Physical address of GDT to be loaded
FlushGDT:
mov eax, [esp+4]
lgdt [eax]
; We can now switch to the new data selectors (0x10 is the selector for the new kernel data segment)
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; We now do a far jump to the new kernel code segment (0x08 is the selector for the new code segment)
jmp 0x08:.flush
.flush:
ret