...
This commit is contained in:
2
makefile
2
makefile
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
20
src/kernel.c
20
src/kernel.c
@@ -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();
|
||||
}
|
||||
11
src/kernel.h
11
src/kernel.h
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
18
src/util.h
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user