From 29093837a33aa24449e4c398621d667e6bcab9d6 Mon Sep 17 00:00:00 2001 From: Arnau478 Date: Sat, 18 Jun 2022 00:44:37 +0200 Subject: [PATCH] Implemented IDT --- src/kernel/arch/i686/idt.asm | 16 ++++++++++++++ src/kernel/arch/i686/idt.c | 41 ++++++++++++++++++++++++++++++++++++ src/kernel/arch/i686/idt.h | 23 ++++++++++++++++++++ src/kernel/hal/hal.c | 6 ++++++ src/kernel/hal/hal.h | 3 +++ src/kernel/main.c | 5 ++++- src/kernel/util/binary.h | 4 ++++ 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/kernel/arch/i686/idt.asm create mode 100644 src/kernel/arch/i686/idt.c create mode 100644 src/kernel/arch/i686/idt.h create mode 100644 src/kernel/hal/hal.c create mode 100644 src/kernel/hal/hal.h create mode 100644 src/kernel/util/binary.h diff --git a/src/kernel/arch/i686/idt.asm b/src/kernel/arch/i686/idt.asm new file mode 100644 index 0000000..d5c138b --- /dev/null +++ b/src/kernel/arch/i686/idt.asm @@ -0,0 +1,16 @@ +[bits 32] + +global i686_idt_load +i686_idt_load: + ; New call frame + push ebp + mov ebp, esp + + ; Load IDT + mov eax, [ebp + 8] + lidt [eax] + + ; Restore call frame + mov esp, ebp + pop ebp + ret diff --git a/src/kernel/arch/i686/idt.c b/src/kernel/arch/i686/idt.c new file mode 100644 index 0000000..78002a3 --- /dev/null +++ b/src/kernel/arch/i686/idt.c @@ -0,0 +1,41 @@ +#include "idt.h" +#include "../../util/binary.h" + +typedef struct{ + uint16_t base_low; + uint16_t segment_selector; + uint8_t reserved; + uint8_t flags; + uint16_t base_high; +} idt_entry; + +typedef struct{ + uint16_t limit; + idt_entry *ptr; +} idt_descriptor; + +idt_entry g_idt[256]; + +idt_descriptor g_idt_descriptor = {sizeof(g_idt) - 1, g_idt}; + +void __attribute__((cdecl)) i686_idt_load(idt_descriptor *descriptor); + +void i686_idt_set_gate(int interrupt, void *base, uint16_t segment_descriptor, uint8_t flags){ + g_idt[interrupt].base_low = ((uint32_t)base) & 0xFFFF; + g_idt[interrupt].segment_selector = segment_descriptor; + g_idt[interrupt].reserved = 0; + g_idt[interrupt].flags = flags; + g_idt[interrupt].base_high = ((uint32_t)base >> 16) & 0xFFFF; +} + +void i686_idt_enable_gate(int interrupt){ + FLAG_SET(g_idt[interrupt].flags, IDT_FLAG_PRESENT); +} + +void i686_idt_disable_gate(int interrupt){ + FLAG_UNSET(g_idt[interrupt].flags, IDT_FLAG_PRESENT); +} + +void i686_idt_initialize(){ + i686_idt_load(&g_idt_descriptor); +} diff --git a/src/kernel/arch/i686/idt.h b/src/kernel/arch/i686/idt.h new file mode 100644 index 0000000..8d98362 --- /dev/null +++ b/src/kernel/arch/i686/idt.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +typedef enum{ + IDT_FLAG_GATE_TASK = 0x5, + IDT_FLAG_GATE_16BIT_INT = 0x6, + IDT_FLAG_GATE_16BIT_TRAP = 0x7, + IDT_FLAG_GATE_32BIT_INT = 0xE, + IDT_FLAG_GATE_32BIT_TRAP = 0xF, + + IDT_FLAG_RING0 = (0 << 5), + IDT_FLAG_RING1 = (1 << 5), + IDT_FLAG_RING2 = (2 << 5), + IDT_FLAG_RING3 = (3 << 5), + + IDT_FLAG_PRESENT = 0x80, +} idt_flags; + +void i686_idt_initialize(); +void i686_idt_enable_gate(int interrupt); +void i686_idt_disable_gate(int interrupt); +void i686_idt_set_gate(int interrupt, void *base, uint16_t segment_descriptor, uint8_t flags); diff --git a/src/kernel/hal/hal.c b/src/kernel/hal/hal.c new file mode 100644 index 0000000..ab8602c --- /dev/null +++ b/src/kernel/hal/hal.c @@ -0,0 +1,6 @@ +#include "hal.h" +#include "../arch/i686/idt.h" + +void hal_initialize(){ + i686_idt_initialize(); +} diff --git a/src/kernel/hal/hal.h b/src/kernel/hal/hal.h new file mode 100644 index 0000000..4fa1812 --- /dev/null +++ b/src/kernel/hal/hal.h @@ -0,0 +1,3 @@ +#pragma once + +void hal_initialize(); diff --git a/src/kernel/main.c b/src/kernel/main.c index f61db0d..44a9891 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,9 +1,12 @@ #include #include "stdio.h" +#include "hal/hal.h" void __attribute__((cdecl)) kmain(uint64_t magic, uint64_t addr){ + hal_initialize(); + puts("\x1b[33mWARNING\x1b[0m"); printf(": amazing %s ahead!\n", "math"); printf("%i+%i=%i\n", 1, 1, 2); - for(;;); // Halt here + for(;;); // Halt here } diff --git a/src/kernel/util/binary.h b/src/kernel/util/binary.h new file mode 100644 index 0000000..2d0ab9f --- /dev/null +++ b/src/kernel/util/binary.h @@ -0,0 +1,4 @@ +#pragma once + +#define FLAG_SET(x, flag) (x) |= (flag) +#define FLAG_UNSET(x, flag) (x) &= ~(flag)