Loading my GDT causes a triple fault

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
beauhefley
Posts: 13
Joined: Mon Feb 20, 2017 1:01 am
Location: The Moon
Contact:

Loading my GDT causes a triple fault

Post 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?
Developing an OS that is so early in development, it can't do anything because stupid me can't figure out interrupts
Image
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Loading my GDT causes a triple fault

Post 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.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Loading my GDT causes a triple fault

Post 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:
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Loading my GDT causes a triple fault

Post 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.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
beauhefley
Posts: 13
Joined: Mon Feb 20, 2017 1:01 am
Location: The Moon
Contact:

Re: Loading my GDT causes a triple fault

Post 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!
Developing an OS that is so early in development, it can't do anything because stupid me can't figure out interrupts
Image
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Loading my GDT causes a triple fault

Post 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?
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Loading my GDT causes a triple fault

Post 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.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Post Reply