Getting GDT to work on AT&T asm
Posted: Mon Feb 03, 2025 3:43 pm
Hello all. I'm quite new to this so please do bare with me.
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
Relevant code in kernel.c
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);
}