From 01e6022fa7367d2b2b703b6c1afb4f41ffc3727c Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 24 Aug 2025 20:09:11 +0200 Subject: [PATCH] idt --- makefile | 2 +- src/boot.asm | 1 + src/idt.asm | 23 +++++++++++---- src/idt.c | 79 +++++++++++++++++++++++++++------------------------- src/idt.h | 3 +- src/kernel.c | 3 +- src/vga.c | 62 +++++++++++++++++++++++++++++++++++++++-- src/vga.h | 4 +++ 8 files changed, 128 insertions(+), 49 deletions(-) diff --git a/makefile b/makefile index b7f7717..5ad0a62 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 -Wshadow -std=c23 +CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Werror -Wshadow -std=c23 LDFLAGS = all: .build/nub-os.iso diff --git a/src/boot.asm b/src/boot.asm index f5b1488..dc65ba7 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -31,6 +31,7 @@ section .text bits 32 global _start _start: + cli mov esp, stack_top ; Check if CPU supports 64-bit mode diff --git a/src/idt.asm b/src/idt.asm index 8fd15d4..8ada1db 100644 --- a/src/idt.asm +++ b/src/idt.asm @@ -1,16 +1,21 @@ +extern interrput_handler + %macro isr_err_stub 1 isr_stub_%+%1: - call exception_handler + push %1 + call interrput_handler + add rsp, 8 iretq %endmacro %macro isr_no_err_stub 1 isr_stub_%+%1: - call exception_handler + push %1 + call interrput_handler + add rsp, 8 iretq %endmacro -extern exception_handler isr_no_err_stub 0 isr_no_err_stub 1 isr_no_err_stub 2 @@ -49,5 +54,13 @@ isr_stub_table: %assign i 0 %rep 32 dq isr_stub_%+i -%assign i i+1 -%endrep \ No newline at end of file +%assign i i + 1 +%endrep + +.text +global idt_hang +idt_hang: + cli +.loop: + hlt + jmp .loop \ No newline at end of file diff --git a/src/idt.c b/src/idt.c index f23c80e..857eeed 100644 --- a/src/idt.c +++ b/src/idt.c @@ -1,19 +1,19 @@ +#include "idt.h" #include "vga.h" #include +#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; + uint16_t address_low; + uint16_t selector; + uint8_t ist; + uint8_t flags; + uint16_t address_mid; + uint32_t address_high; + uint32_t reserved; +} __attribute__((packed)) interrupt_descriptor; typedef struct { @@ -21,45 +21,48 @@ typedef struct uint64_t base; } __attribute__((packed)) idtr_t; -static idt_entry_t idt[256]; +static interrupt_descriptor 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[]; +extern void idt_hang(); + +void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl) +{ + interrupt_descriptor* entry = &idt[vector]; + + entry->address_low = (uint64_t)handler & 0xFFFF; + entry->address_mid = ((uint64_t)handler >> 16) & 0xFFFF; + entry->address_high = (uint64_t)handler >> 32; + entry->selector = 0x08; + entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7); + entry->ist = 0; + entry->reserved = 0; +} void idt_init(void) { idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1; + idtr.limit = (uint16_t)sizeof(interrupt_descriptor) * 256 - 1; for (uint8_t vector = 0; vector < 32; vector++) { - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = true; + idt_set_descriptor(vector, isr_stub_table[vector], 0); } __asm__ volatile("lidt %0" : : "m"(idtr)); __asm__ volatile("sti"); - - vga_print_success("IDT intialzied"); } + +typedef struct +{ + uint64_t vector_number; + uint64_t error_code; +} cpu_status_t; + +void interrput_handler(uint64_t vector_number) +{ + vga_print("An exception occurred: "); + vga_print_uint(vector_number); + vga_print("\n"); + idt_hang(); +} \ No newline at end of file diff --git a/src/idt.h b/src/idt.h index c403d4c..a1ce9a2 100644 --- a/src/idt.h +++ b/src/idt.h @@ -1,5 +1,6 @@ +#pragma once + #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 a66135f..ba2a83a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -6,8 +6,7 @@ void kernel_main(void) vga_clear(); idt_init(); + vga_print_success("IDT intialzied\n"); 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 f30886e..c2869ce 100644 --- a/src/vga.c +++ b/src/vga.c @@ -116,7 +116,6 @@ void vga_print_success(const char* message) vga_print_colored("success", VGA_GREEN); vga_print(" ] "); vga_print(message); - vga_print("\n"); } void vga_print_error(const char* message) @@ -125,5 +124,64 @@ void vga_print_error(const char* message) vga_print_colored("error", VGA_RED); vga_print(" ] "); vga_print(message); - vga_print("\n"); +} + +static void reverse(char* str, int length) +{ + int start = 0; + int end = length - 1; + while (start < end) + { + char temp = str[start]; + str[start] = str[end]; + str[end] = temp; + start++; + end--; + } +} + +static int uitoa(unsigned int value, char* buffer) +{ + int i = 0; + if (value == 0) + { + buffer[i++] = '0'; + buffer[i] = '\0'; + return i; + } + + while (value > 0) + { + buffer[i++] = (value % 10) + '0'; + value /= 10; + } + + buffer[i] = '\0'; + reverse(buffer, i); + return i; +} + +void vga_print_uint(unsigned int value) +{ + char buffer[11]; + uitoa(value, buffer); + vga_print(buffer); +} + +void vga_print_int(int value) +{ + char buffer[12]; + + if (value < 0) + { + vga_print("-"); + unsigned int abs_val = (unsigned int)(-value); + uitoa(abs_val, buffer); + } + else + { + uitoa((unsigned int)value, buffer); + } + + vga_print(buffer); } \ No newline at end of file diff --git a/src/vga.h b/src/vga.h index 63d66ce..a0fde85 100644 --- a/src/vga.h +++ b/src/vga.h @@ -26,9 +26,13 @@ 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); +void vga_print_uint(unsigned int value); +void vga_print_int(int value); + static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color) { return fg_color | bg_color << 4;