diff --git a/src/Makefile b/src/Makefile index 2b59deb..d5209df 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ CCPREFIX = i686-elf- AS = $(CCPREFIX)as CC = $(CCPREFIX)gcc -OBJS = boot.s.o main.c.o logger.c.o console.c.o +OBJS = boot.s.o main.c.o logger.c.o console.c.o gdt.c.o gdt.asm.o all: kernel @@ -18,3 +18,6 @@ kernel: $(OBJS) %.s.o: %.s $(AS) $< -o $@ + +%.asm.o: %.asm + nasm -felf -o $@ $< diff --git a/src/gdt.asm b/src/gdt.asm new file mode 100644 index 0000000..04b569f --- /dev/null +++ b/src/gdt.asm @@ -0,0 +1,15 @@ +[GLOBAL gdt_flush] + +gdt_flush: + mov eax, [esp+4] + lgdt [eax] + + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp 0x08:.flush +.flush: + ret diff --git a/src/gdt.c b/src/gdt.c new file mode 100644 index 0000000..725a64a --- /dev/null +++ b/src/gdt.c @@ -0,0 +1,37 @@ +#include "gdt.h" + +static struct GdtPointer gdt_pointer; + +static struct GdtEntry gdt_entries[5]; + +static void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); + +void gdt_flush(uint32_t pointer); + +void gdt_initialize() +{ + gdt_set_gate(0, 0, 0, 0, 0); // Null segment + gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment + gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment + gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment + gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment + + gdt_pointer.limit = sizeof(struct GdtEntry) * 5 - 1; + gdt_pointer.base = (uint32_t)&gdt_entries; + + gdt_flush((uint32_t)&gdt_pointer); +} + +void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) +{ + gdt_entries[num].base_low = (base & 0xFFFF); + gdt_entries[num].base_middle = (base >> 16) & 0xFF; + gdt_entries[num].base_high = (base >> 24) & 0xFF; + + gdt_entries[num].limit_low = (limit & 0xFFFF); + gdt_entries[num].granularity = (limit >> 16) & 0x0F; + + gdt_entries[num].granularity |= gran & 0xF0; + + gdt_entries[num].access = access; +} diff --git a/src/gdt.h b/src/gdt.h new file mode 100644 index 0000000..894d074 --- /dev/null +++ b/src/gdt.h @@ -0,0 +1,24 @@ +#ifndef TAILIX_KERNEL_INCLUDED_GDT +#define TAILIX_KERNEL_INCLUDED_GDT 1 + +#include + +struct GdtPointer { + uint16_t limit; + uint32_t base; +} +__attribute__((packed)); + +struct GdtEntry { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_middle; + uint8_t access; + uint8_t granularity; + uint8_t base_high; +} +__attribute__((packed)); + +void gdt_initialize(); + +#endif diff --git a/src/main.c b/src/main.c index 2c523c0..fb0d6ad 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,15 @@ #include "logger.h" +#include "gdt.h" void main() { logger_initialize(); logger_info("Kernel initialization started."); + + logger_info("GDT initialization started."); + gdt_initialize(); + logger_info("GDT initialization finished."); + logger_warn("Nothing to do."); logger_fail("Halt."); }