Page 1 of 1

Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 1:09 am
by beauhefley
I am reading some guides on how to write a simple GDT. After reading 50 different guides, I came up with this:

Code: Select all

//In gdtc.h
#include <stdint.h>

typedef struct {
	uint16_t           lLimit;
	uint16_t	        lBase;
	uint8_t		      mBase;
	uint8_t		      access;
	uint8_t		      granularity;
	uint8_t		      hBase;
} gdtEntry_t;

struct {
	uint16_t limit;
	uint32_t base;
} gdtPointer;

extern void loadGdt();
void setupGdt();


//In gdtc.c
#include "gdtc.h"

gdtEntry_t gdt[3];


void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
	uint8_t gran){
	gdt[num].lBase		= (base & 0xFFFF);
	gdt[num].mBase		= (base >> 16) & 0xFF;
	gdt[num].hBase		= (base >> 24) & 0xFF;

	gdt[num].lLimit		= (limit & 0xFFFF);
	gdt[num].granularity	= ((limit >> 16) & 0x0F);

	gdt[num].granularity   |= (gran & 0xF0);
	gdt[num].access		= access;
}

void setupGdt(){
	gdtPointer.limit	= (sizeof(gdtEntry_t) * 3) - 1;
	gdtPointer.base		= &gdt;

	gdtSetGate(0, 0, 0, 0, 0);
	gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
	gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

	loadGdt();
}


//And in gdtaglobal loadGdt
extern gdtPointer

loadGdt:
	lgdt[gdtPointer]
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	jmp 0x08:fload
fload:
	ret.asm
When I compile I get this warning:

Code: Select all

gdtc.c:21:19: warning: assignment makes integer from pointer without a cast
  gdtPointer.base  = &gdt;
I tried to load it in my emulator anyway, but of course it triple faults.
Then I changed that line to:

Code: Select all

gdtPointer.base = (uint32_t*) *gdt;
And got

Code: Select all

gdtc.c:21:2: error: cannot convert to a pointer type
  gdtPointer.base  = (uint32_t*) *gdt;
So what am I doing wrong?

Re: Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 1:47 am
by alexfru
beauhefley wrote:

Code: Select all

struct {
	uint16_t limit;
	uint32_t base;
} gdtPointer;
The structure is not tightly packed, base must be at offset of 2, immediately after limit.
beauhefley wrote:

Code: Select all

void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
	uint8_t gran){
Just a nit: you don't need those uint64_t's. uint32_t is enough.

Re: Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 2:24 am
by Octacone
Oh! Memories :cry:
You reminded me of the moment when the exact same thing happened to me.
After looking for days trying to figure out what was wrong, nothing was wrong with my code except I forgot:
typedef struct gdt_entry_t
{
...
} __attribute__((packed)) gdt_entry_t;

typedef struct gdt_pointer_t
{
...
} __attribute__((packed)) gdt_pointer_t;

Also as alexfru mentioned uint32_t is enough. Before posting "Loading my IDT causes a triple fault", check if your structs are aligned. :wink:

Re: Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 10:58 am
by BrightLight
Maybe this is a little off-topic to this specific problem, but some references indicate that some CPU implementations require that the GDT and IDT be aligned on a uint64_t boundary. Just to be safe, you should probably do this.

Re: Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 12:51 pm
by beauhefley
octacone wrote:Oh! Memories :cry:
You reminded me of the moment when the exact same thing happened to me.
After looking for days trying to figure out what was wrong, nothing was wrong with my code except I forgot:
typedef struct gdt_entry_t
{
...
} __attribute__((packed)) gdt_entry_t;

typedef struct gdt_pointer_t
{
...
} __attribute__((packed)) gdt_pointer_t;

Also as alexfru mentioned uint32_t is enough. Before posting "Loading my IDT causes a triple fault", check if your structs are aligned. :wink:
Ah OK. I'll try both of those when I get home. I'm currently on my phone. Thank you!

Re: Loading my GDT causes a triple fault

Posted: Sun Mar 05, 2017 1:39 pm
by Gigasoft
omarrx024 wrote:Maybe this is a little off-topic to this specific problem, but some references indicate that some CPU implementations require that the GDT and IDT be aligned on a uint64_t boundary. Just to be safe, you should probably do this.
Hold on, what kind of references?

Re: Loading my GDT causes a triple fault

Posted: Mon Mar 06, 2017 11:17 am
by BrightLight
Gigasoft wrote:
omarrx024 wrote:Maybe this is a little off-topic to this specific problem, but some references indicate that some CPU implementations require that the GDT and IDT be aligned on a uint64_t boundary. Just to be safe, you should probably do this.
Hold on, what kind of references?
TBH, I don't remember where I read this. Anyway, it wouldn't hurt doing it.