From 57ef424e00bedbd9a891c012d7b6aae523f1287f Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 24 Aug 2025 18:52:51 +0200 Subject: [PATCH] interrupts --- grub.cfg | 4 ++++ makefile | 12 +++++++--- src/idt.asm | 53 ++++++++++++++++++++++++++++++++++++++++++ src/idt.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/idt.h | 5 ++++ src/kernel.c | 6 +++++ src/vga.c | 18 +++++++++++++++ src/vga.h | 2 ++ 8 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 src/idt.asm create mode 100644 src/idt.c create mode 100644 src/idt.h diff --git a/grub.cfg b/grub.cfg index 8e64ec9..a771cd1 100644 --- a/grub.cfg +++ b/grub.cfg @@ -1,3 +1,7 @@ menuentry "nub-os" { multiboot2 /boot/kernel + boot } + +set default="nub-os" +set timeout=0 diff --git a/makefile b/makefile index cd91884..b7f7717 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ CC = x86_64-elf-gcc LD = x86_64-elf-ld -CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Werror -Wshadow -std=c23 +CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 LDFLAGS = all: .build/nub-os.iso @@ -18,8 +18,8 @@ build-dir: cp .build/kernel .build/iso/boot/ grub-mkrescue -o .build/nub-os.iso .build/iso/ -.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o - $(LD) $(LDFLAGS) -T src/boot.ld -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o +.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt2.o + $(LD) $(LDFLAGS) -T src/boot.ld -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt2.o .build/kernel.o: build-dir src/kernel.c $(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c @@ -27,5 +27,11 @@ build-dir: .build/vga.o: build-dir src/vga.c $(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c +.build/idt.o: build-dir src/idt.c + $(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c + +.build/idt2.o: build-dir src/idt.asm + nasm -f elf64 -o .build/idt2.o src/idt.asm + .build/boot.o: build-dir src/boot.asm nasm -f elf64 -o .build/boot.o src/boot.asm \ No newline at end of file diff --git a/src/idt.asm b/src/idt.asm new file mode 100644 index 0000000..8fd15d4 --- /dev/null +++ b/src/idt.asm @@ -0,0 +1,53 @@ +%macro isr_err_stub 1 +isr_stub_%+%1: + call exception_handler + iretq +%endmacro + +%macro isr_no_err_stub 1 +isr_stub_%+%1: + call exception_handler + iretq +%endmacro + +extern exception_handler +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dq isr_stub_%+i +%assign i i+1 +%endrep \ No newline at end of file diff --git a/src/idt.c b/src/idt.c new file mode 100644 index 0000000..f23c80e --- /dev/null +++ b/src/idt.c @@ -0,0 +1,65 @@ +#include "vga.h" +#include +#include + +#define IDT_MAX_DESCRIPTORS 255 + +typedef struct +{ + uint16_t isr_low; // The lower 16 bits of the ISR's address + uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR + uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now + uint8_t attributes; // Type and attributes; see the IDT page + uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address + uint32_t isr_high; // The higher 32 bits of the ISR's address + uint32_t reserved; // Set to zero +} __attribute__((packed)) idt_entry_t; + +typedef struct +{ + uint16_t limit; + uint64_t base; +} __attribute__((packed)) idtr_t; + +static idt_entry_t idt[256]; +static idtr_t idtr; + +void exception_handler(void) +{ + vga_print_error("An unhandled exception occurred"); + __asm__ volatile("cli; hlt"); +} + +void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) +{ + idt_entry_t* descriptor = &idt[vector]; + + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x08; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; +} + +static bool vectors[IDT_MAX_DESCRIPTORS]; + +extern void* isr_stub_table[]; + +void idt_init(void) +{ + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1; + + for (uint8_t vector = 0; vector < 32; vector++) + { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = true; + } + + __asm__ volatile("lidt %0" : : "m"(idtr)); + __asm__ volatile("sti"); + + vga_print_success("IDT intialzied"); +} diff --git a/src/idt.h b/src/idt.h new file mode 100644 index 0000000..c403d4c --- /dev/null +++ b/src/idt.h @@ -0,0 +1,5 @@ +#include + +void idt_init(void); +void exception_handler(void); +void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); diff --git a/src/kernel.c b/src/kernel.c index 1e4f7f7..a66135f 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,7 +1,13 @@ +#include "idt.h" #include "vga.h" void kernel_main(void) { vga_clear(); + + idt_init(); + vga_print("Welcome to nub OS\n"); + + int x = 1 / 0; } \ No newline at end of file diff --git a/src/vga.c b/src/vga.c index 5329925..f30886e 100644 --- a/src/vga.c +++ b/src/vga.c @@ -108,4 +108,22 @@ void vga_print_colored(const char* string, vga_color_t color) void vga_print(const char* string) { vga_print_colored(string, vga_default_color()); +} + +void vga_print_success(const char* message) +{ + vga_print("[ "); + vga_print_colored("success", VGA_GREEN); + vga_print(" ] "); + vga_print(message); + vga_print("\n"); +} + +void vga_print_error(const char* message) +{ + vga_print("[ "); + vga_print_colored("error", VGA_RED); + vga_print(" ] "); + vga_print(message); + vga_print("\n"); } \ No newline at end of file diff --git a/src/vga.h b/src/vga.h index 43c6804..63d66ce 100644 --- a/src/vga.h +++ b/src/vga.h @@ -26,6 +26,8 @@ void vga_set_cursor_position(uint8_t row, uint8_t col); void vga_print_colored(const char* string, vga_color_t color); void vga_print(const char* string); +void vga_print_success(const char* message); +void vga_print_error(const char* message); static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color) {