This commit is contained in:
nub31
2025-08-24 20:09:11 +02:00
parent 57ef424e00
commit 01e6022fa7
8 changed files with 128 additions and 49 deletions

View File

@@ -1,7 +1,7 @@
CC = x86_64-elf-gcc CC = x86_64-elf-gcc
LD = x86_64-elf-ld 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 = LDFLAGS =
all: .build/nub-os.iso all: .build/nub-os.iso

View File

@@ -31,6 +31,7 @@ section .text
bits 32 bits 32
global _start global _start
_start: _start:
cli
mov esp, stack_top mov esp, stack_top
; Check if CPU supports 64-bit mode ; Check if CPU supports 64-bit mode

View File

@@ -1,16 +1,21 @@
extern interrput_handler
%macro isr_err_stub 1 %macro isr_err_stub 1
isr_stub_%+%1: isr_stub_%+%1:
call exception_handler push %1
call interrput_handler
add rsp, 8
iretq iretq
%endmacro %endmacro
%macro isr_no_err_stub 1 %macro isr_no_err_stub 1
isr_stub_%+%1: isr_stub_%+%1:
call exception_handler push %1
call interrput_handler
add rsp, 8
iretq iretq
%endmacro %endmacro
extern exception_handler
isr_no_err_stub 0 isr_no_err_stub 0
isr_no_err_stub 1 isr_no_err_stub 1
isr_no_err_stub 2 isr_no_err_stub 2
@@ -51,3 +56,11 @@ isr_stub_table:
dq isr_stub_%+i dq isr_stub_%+i
%assign i i + 1 %assign i i + 1
%endrep %endrep
.text
global idt_hang
idt_hang:
cli
.loop:
hlt
jmp .loop

View File

@@ -1,19 +1,19 @@
#include "idt.h"
#include "vga.h" #include "vga.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define IDT_MAX_DESCRIPTORS 255
typedef struct typedef struct
{ {
uint16_t isr_low; // The lower 16 bits of the ISR's address uint16_t address_low;
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR uint16_t selector;
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now uint8_t ist;
uint8_t attributes; // Type and attributes; see the IDT page uint8_t flags;
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address uint16_t address_mid;
uint32_t isr_high; // The higher 32 bits of the ISR's address uint32_t address_high;
uint32_t reserved; // Set to zero uint32_t reserved;
} __attribute__((packed)) idt_entry_t; } __attribute__((packed)) interrupt_descriptor;
typedef struct typedef struct
{ {
@@ -21,45 +21,48 @@ typedef struct
uint64_t base; uint64_t base;
} __attribute__((packed)) idtr_t; } __attribute__((packed)) idtr_t;
static idt_entry_t idt[256]; static interrupt_descriptor idt[256];
static idtr_t idtr; 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* 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) void idt_init(void)
{ {
idtr.base = (uintptr_t)&idt[0]; 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++) for (uint8_t vector = 0; vector < 32; vector++)
{ {
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); idt_set_descriptor(vector, isr_stub_table[vector], 0);
vectors[vector] = true;
} }
__asm__ volatile("lidt %0" : : "m"(idtr)); __asm__ volatile("lidt %0" : : "m"(idtr));
__asm__ volatile("sti"); __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();
} }

View File

@@ -1,5 +1,6 @@
#pragma once
#include <stdint.h> #include <stdint.h>
void idt_init(void); void idt_init(void);
void exception_handler(void);
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);

View File

@@ -6,8 +6,7 @@ void kernel_main(void)
vga_clear(); vga_clear();
idt_init(); idt_init();
vga_print_success("IDT intialzied\n");
vga_print("Welcome to nub OS\n"); vga_print("Welcome to nub OS\n");
int x = 1 / 0;
} }

View File

@@ -116,7 +116,6 @@ void vga_print_success(const char* message)
vga_print_colored("success", VGA_GREEN); vga_print_colored("success", VGA_GREEN);
vga_print(" ] "); vga_print(" ] ");
vga_print(message); vga_print(message);
vga_print("\n");
} }
void vga_print_error(const char* message) 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_colored("error", VGA_RED);
vga_print(" ] "); vga_print(" ] ");
vga_print(message); 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);
} }

View File

@@ -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_colored(const char* string, vga_color_t color);
void vga_print(const char* string); void vga_print(const char* string);
void vga_print_success(const char* message); void vga_print_success(const char* message);
void vga_print_error(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) static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
{ {
return fg_color | bg_color << 4; return fg_color | bg_color << 4;