I'm trying to set up GDT and GDT reload for my kernel written in C. The example code in the osdev wiki is written in NASM i believe, I've been trying to convert it to AT&T but I keep getting triple faults. Any advice would be appreciated.
Relevant section in boot.S
Code: Select all
.section .data
gdtr:
.word 0
.long 0x00000000
.section .text
.global setGDT
setGDT:
movw 8(%esp), %ax
movw %ax, gdtr
movl 12(%esp), %eax
movl %eax, gdtr + 2
lgdt gdtr
ret
.section .text
.global reloadSegments
reloadSegments:
ljmp $0x08, $.reload_CS
.reload_CS:
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ret
Relevant code in kernel.c
Code: Select all
struct GDT {
uint32_t base;
uint32_t limit;
uint8_t access;
uint8_t flags;
};
void encodeGdtEntry(uint8_t *target, struct GDT source)
{
target[0] = source.limit & 0xFF;
target[1] = (source.limit >> 8) & 0xFF;
target[6] = (source.limit >> 16) & 0x0F;
target[2] = source.base & 0xFF;
target[3] = (source.base >> 8) & 0xFF;
target[4] = (source.base >> 16) & 0xFF;
target[7] = (source.base >> 24) & 0xFF;
target[5] = source.access;
target[6] |= (source.flags << 4);
}
extern void setGDT(uint16_t limit, uint32_t base);
extern void reloadSegments(void);
void GdtSetup() {
uint32_t gdt[3 * 8];
struct GDT segmnt_null = {0, 0x00000000, 0x00, 0x0};
struct GDT segmnt_code = {0, 0xFFFFF, 0x9A, 0xC};
struct GDT segmnt_data = {0, 0xFFFFF, 0x92, 0xC};
encodeGdtEntry((uint8_t*)&gdt[0], segmnt_null);
encodeGdtEntry((uint8_t*)&gdt[1], segmnt_code);
encodeGdtEntry((uint8_t*)&gdt[2], segmnt_data);
uint16_t limit = (sizeof(gdt) - 1);
uint32_t base = (uint32_t)&gdt;
setGDT(limit, base);
}