This commit is contained in:
nub31
2025-09-01 19:18:38 +02:00
parent 385c0d432c
commit 1bc122e29a
10 changed files with 106 additions and 65 deletions

View File

@@ -6,7 +6,7 @@ CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -g
LDFLAGS = -g
ASFLAGS = -f elf64 -g -F dwarf
SRC_C := src/kernel.c src/string.c src/vga.c src/interrupts.c src/keyboard.c
SRC_C := src/kernel.c src/string.c src/vga.c src/interrupts.c
SRC_ASM := src/start.asm
OBJ_C := $(SRC_C:src/%.c=.build/%.o)

View File

@@ -1,13 +1,30 @@
#include "interrupts.h"
#include "vga.h"
#include "kernel.h"
#include "util.h"
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
static irq_handler_t irq_handlers[16] = {0};
void pic_remap()
{
outb(PIC1_COMMAND, 0x11);
outb(PIC2_COMMAND, 0x11);
outb(PIC1_DATA, 32);
outb(PIC2_DATA, 40);
outb(PIC1_DATA, 4);
outb(PIC2_DATA, 2);
outb(PIC1_DATA, 1);
outb(PIC2_DATA, 1);
outb(PIC1_DATA, 0);
outb(PIC2_DATA, 0);
}
static const char* exception_messages[32] = {
"divide by zero",
@@ -44,18 +61,45 @@ static const char* exception_messages[32] = {
"reserved",
};
void handle_exception(const isr_frame_t* frame)
{
vga_print_error();
vga_print(" exception[");
vga_print_uint(frame->int_no);
vga_print("]: ");
vga_print(exception_messages[frame->int_no]);
vga_print(", error code: ");
vga_print_uint(frame->err_code);
vga_print("\n");
kernel_panic();
}
static irq_handler_t irq_handlers[16] = {0};
void register_irq_handler(u8 irq, irq_handler_t handler)
{
if (irq >= 16)
{
kernel_panic();
vga_print_error();
vga_print("Cannot register irq ");
vga_print_uint(irq);
vga_print(" is out of bounds\n");
}
else
{
irq_handlers[irq] = handler;
}
irq_handlers[irq] = handler;
}
static inline void pic_send_eoi(u8 irq)
void handle_irq(const isr_frame_t* frame)
{
u8 irq = frame->int_no - 32;
if (irq_handlers[irq])
{
irq_handlers[irq](frame);
}
if (irq >= 8)
{
outb(PIC2_COMMAND, 0x20);
@@ -64,36 +108,17 @@ static inline void pic_send_eoi(u8 irq)
outb(PIC1_COMMAND, 0x20);
}
void handle_isr(isr_frame_t* frame)
void handle_isr(const isr_frame_t* frame)
{
vga_print("test");
if (frame->int_no < 32)
{
vga_print_error();
vga_print(" exception[");
vga_print_uint(frame->int_no);
vga_print("]: ");
vga_print(exception_messages[frame->int_no]);
vga_print(", error code: ");
vga_print_uint(frame->err_code);
vga_print("\n");
while (true)
{
__asm__ volatile ("cli");
__asm__ volatile ("hlt");
}
handle_exception(frame);
}
else if (frame->int_no < 48)
{
u8 irq = frame->int_no - 32;
if (irq_handlers[irq])
{
irq_handlers[irq](frame);
}
pic_send_eoi(irq);
handle_irq(frame);
}
else
{
@@ -103,4 +128,4 @@ void handle_isr(isr_frame_t* frame)
vga_print("]: ");
vga_print("not implemented\n");
}
}
}

View File

@@ -13,16 +13,16 @@ typedef struct
typedef void (*irq_handler_t)(const isr_frame_t*);
static inline void outb(u16 port, u8 val)
void pic_remap();
void register_irq_handler(u8 irq, irq_handler_t handler);
static inline void enable_interrupts()
{
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
__asm__ volatile("sti");
}
static inline u8 inb(u16 port)
static inline void disable_interrupts()
{
u8 ret;
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
void register_irq_handler(u8 irq, irq_handler_t handler);
__asm__ volatile("cli");
}

View File

@@ -1,33 +1,21 @@
#include "kernel.h"
#include "interrupts.h"
#include "keyboard.h"
#include "vga.h"
void kernel_main()
{
vga_clear();
vga_print_success();
vga_print(" VGA intialzied\n");
init_keyboard();
vga_print_success();
vga_print(" Keyboard intialzied\n");
pic_remap();
enable_interrupts();
vga_print("\nWelcome to nub OS\n");
while (true)
{
__asm__ volatile ("cli");
__asm__ volatile ("hlt");
}
kernel_halt();
}
void kernel_panic()
{
vga_print("Kernel panic!\n");
while (true)
{
__asm__ volatile ("cli");
__asm__ volatile ("hlt");
}
kernel_halt();
}

View File

@@ -1,3 +1,12 @@
#pragma once
void kernel_panic();
void kernel_panic();
static inline void kernel_halt()
{
while (true)
{
__asm__ volatile ("cli");
__asm__ volatile ("hlt");
}
}

View File

@@ -2,6 +2,7 @@
#include "interrupts.h"
#include "kernel.h"
#include "vga.h"
#include "util.h"
#define SCANCODE_LEFT_SHIFT 42
#define SCANCODE_RIGHT_SHIFT 54

View File

@@ -175,7 +175,7 @@ section .text
mov gs, ax
mov ss, ax
; Set up idt
; Fill in the idt table with the stub functions
mov rdi, idt64
mov rsi, isr_stub_table
mov rcx, 256
@@ -193,8 +193,8 @@ section .text
add rsi, 8
loop .loop
lidt [idt64_descriptor]
sti
; Finally, we call in to c
call kernel_main
.hang:
hlt

18
src/util.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
static inline void outb(u16 port, u8 val)
{
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline u8 inb(u16 port)
{
u8 ret;
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void io_wait()
{
outb(0x80, 0);
}

View File

@@ -24,7 +24,7 @@ vga_char vga_char_at(u8 row, u8 col)
return vga_buffer[COLUMNS * row + col];
}
void vga_clear(void)
void vga_clear()
{
for (u8 row = 0; row < ROWS; row++)
{
@@ -121,14 +121,14 @@ void vga_print_colored(const char* string, vga_color_t color)
}
}
void vga_print_success(void)
void vga_print_success()
{
vga_print("[ ");
vga_print_colored("success", VGA_GREEN);
vga_print(" ]");
}
void vga_print_error(void)
void vga_print_error()
{
vga_print("[ ");
vga_print_colored("error", VGA_RED);

View File

@@ -21,14 +21,14 @@
typedef u8 vga_color_t;
void vga_clear(void);
void vga_clear();
void vga_set_cursor_position(u8 row, u8 col);
void vga_print_char_colored(char character, vga_color_t color);
void vga_print_colored(const char* string, vga_color_t color);
void vga_print_success(void);
void vga_print_error(void);
void vga_print_success();
void vga_print_error();
void vga_print_uint(u32 value);
void vga_print_int(i32 value);