summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-26 15:32:32 +0200
committerCarlos Maiolino <[email protected]>2025-08-01 13:07:38 +0200
commit57d8e2b236c7a185bdd941c247ef0dcc5961a24e (patch)
tree1d1f496510c77422647f1513c3ca6f85e0110689
parent80ac430366d65ef89a078832380a021308bbbfdf (diff)
Implement interrupt descriptor table
Signed-off-by: Carlos Maiolino <[email protected]>
-rw-r--r--Makefile14
-rw-r--r--src/idt/idt.asm13
-rw-r--r--src/idt/idt.c42
-rw-r--r--src/include/toxic/idt.h27
-rw-r--r--src/kernel.c2
5 files changed, 97 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index dfdcae5..51493cd 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,10 @@ KOBJ_LIBS = ./build/string.o
KOBJ_FILES = $(KERNEL_ASM_OBJ) \
$(KERNEL_OBJ) \
- ./build/vga.o
+ ./build/vga.o \
+ ./build/idt/idt.asm.o \
+ ./build/idt/idt.o
+
BOOT_TGT =./bin/boot.bin
KERNEL_TGT = ./bin/kernel.bin
@@ -48,6 +51,13 @@ $(BUILD_DIR)/kernel.o: ./src/kernel.c ./build/vga.o $(KOBJ_LIBS)
$(BUILD_DIR)/vga.o: ./src/vga.c $(KOBJ_LIBS)
i686-elf-gcc $(INCLUDES) $(FLAGS) -std=gnu99 -c ./src/vga.c -o $(BUILD_DIR)/vga.o
+$(BUILD_DIR)/idt/idt.asm.o: ./src/idt/idt.asm
+ nasm -f elf -g ./src/idt/idt.asm -o $(BUILD_DIR)/idt/idt.asm.o
+
+$(BUILD_DIR)/idt/idt.o: ./src/idt/idt.c ./build/vga.o $(KOBJ_LIBS)
+ i686-elf-gcc $(INCLUDES) $(FLAGS) -std=gnu99 -c ./src/idt/idt.c -o $(BUILD_DIR)/idt/idt.o
+
+
$(KOBJ_LIBS):
i686-elf-gcc $(INCLUDES) $(FLAGS) -std=gnu99 -c ./src/lib/string.c -o $(BUILD_DIR)/string.o
clean:
@@ -58,4 +68,6 @@ clean:
rm -f build/kernel.o
rm -f build/vga.o
rm -f build/string.o
+ rm -f build/idt/idt.asm.o
+ rm -f build/idt/idt.o
rm -f bin/os.bin
diff --git a/src/idt/idt.asm b/src/idt/idt.asm
new file mode 100644
index 0000000..998a242
--- /dev/null
+++ b/src/idt/idt.asm
@@ -0,0 +1,13 @@
+section .asm
+
+global idt_load:
+
+idt_load:
+ push ebp
+ mov ebp, esp
+
+ mov ebx, [ebp + 8]
+ lidt [ebx]
+
+ pop ebp
+ ret
diff --git a/src/idt/idt.c b/src/idt/idt.c
new file mode 100644
index 0000000..d7a6743
--- /dev/null
+++ b/src/idt/idt.c
@@ -0,0 +1,42 @@
+#include <stdint.h>
+#include <toxic/config.h>
+#include <toxic/string.h>
+#include <toxic/vga.h>
+#include <toxic/idt.h>
+
+struct int_descriptor int_table[TOTAL_INTERRUPTS];
+struct int_reg_descriptor idtr_descriptor;
+
+extern void idt_load(struct int_reg_descriptor *desc);
+
+static void
+idt_zero()
+{
+ vprintl("Illegal operation: Divide by zero\n");
+}
+
+static void
+idt_set(int int_num, void *addr)
+{
+ struct int_descriptor *desc = &int_table[int_num];
+
+ desc->offset_low = (uint32_t) addr & 0x0000FFFF;
+ desc->selector = KERNEL_CODE_SELECTOR;
+ desc->reserved = 0x00;
+ desc->type_attr = TOXIC_INT_ATTR;
+ desc->offset_high = (uint32_t) addr >> 16;
+}
+
+void
+interrupts_init(void)
+{
+ memset(int_table, 0, sizeof(int_table));
+
+ idtr_descriptor.limit = sizeof(int_table) - 1;
+ idtr_descriptor.base = (uint32_t) int_table;
+
+ idt_set(0, idt_zero);
+
+ idt_load(&idtr_descriptor);
+}
+
diff --git a/src/include/toxic/idt.h b/src/include/toxic/idt.h
new file mode 100644
index 0000000..f54f7f7
--- /dev/null
+++ b/src/include/toxic/idt.h
@@ -0,0 +1,27 @@
+#ifndef IDT_H
+#define IDT_H
+#include <stdint.h>
+
+/* ATTR byte field values */
+#define INT_GATE_32 0x0E
+#define TRAP_GATE_32 0x0F
+#define DPL_RING3 0x60
+#define PRESENT_BIT (1 << 7)
+
+#define TOXIC_INT_ATTR (PRESENT_BIT | DPL_RING3 | INT_GATE_32)
+
+struct int_descriptor {
+ uint16_t offset_low; /* bits 0..15 */
+ uint16_t selector; /* Code segment selector */
+ uint8_t reserved; /* Unused, must be 0 */
+ uint8_t type_attr; /* gate type, DPL, presence */
+ uint16_t offset_high; /* bits 16..31 */
+} __attribute__((packed));
+
+struct int_reg_descriptor {
+ uint16_t limit; /* Int descriptor table size (bytes) -1 */
+ uint32_t base; /* Table starting offset (linear address) */
+} __attribute__((packed));
+
+void interrupts_init(void);
+#endif /* IDT_H */
diff --git a/src/kernel.c b/src/kernel.c
index 0aa8eef..c2a0150 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -3,10 +3,12 @@
#include <toxic/vga.h>
#include <toxic/string.h>
#include <toxic/kernel.h>
+#include <toxic/idt.h>
void start_kernel()
{
init_display(2);
vprintl("Hello World!!!\n");
+ interrupts_init();
}