...
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
|
LDFLAGS = -g
|
||||||
ASFLAGS = -f elf64 -g -F dwarf
|
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
|
SRC_ASM := src/start.asm
|
||||||
|
|
||||||
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define PIC1_COMMAND 0x20
|
#define PIC1_COMMAND 0x20
|
||||||
#define PIC1_DATA 0x21
|
#define PIC1_DATA 0x21
|
||||||
#define PIC2_COMMAND 0xA0
|
#define PIC2_COMMAND 0xA0
|
||||||
#define PIC2_DATA 0xA1
|
#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] = {
|
static const char* exception_messages[32] = {
|
||||||
"divide by zero",
|
"divide by zero",
|
||||||
@@ -44,18 +61,45 @@ static const char* exception_messages[32] = {
|
|||||||
"reserved",
|
"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)
|
void register_irq_handler(u8 irq, irq_handler_t handler)
|
||||||
{
|
{
|
||||||
if (irq >= 16)
|
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)
|
if (irq >= 8)
|
||||||
{
|
{
|
||||||
outb(PIC2_COMMAND, 0x20);
|
outb(PIC2_COMMAND, 0x20);
|
||||||
@@ -64,36 +108,17 @@ static inline void pic_send_eoi(u8 irq)
|
|||||||
outb(PIC1_COMMAND, 0x20);
|
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)
|
if (frame->int_no < 32)
|
||||||
{
|
{
|
||||||
vga_print_error();
|
handle_exception(frame);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (frame->int_no < 48)
|
else if (frame->int_no < 48)
|
||||||
{
|
{
|
||||||
u8 irq = frame->int_no - 32;
|
handle_irq(frame);
|
||||||
|
|
||||||
if (irq_handlers[irq])
|
|
||||||
{
|
|
||||||
irq_handlers[irq](frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
pic_send_eoi(irq);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ typedef struct
|
|||||||
|
|
||||||
typedef void (*irq_handler_t)(const isr_frame_t*);
|
typedef void (*irq_handler_t)(const isr_frame_t*);
|
||||||
|
|
||||||
static inline void outb(u16 port, u8 val)
|
void pic_remap();
|
||||||
{
|
|
||||||
__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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_irq_handler(u8 irq, irq_handler_t handler);
|
void register_irq_handler(u8 irq, irq_handler_t handler);
|
||||||
|
|
||||||
|
static inline void enable_interrupts()
|
||||||
|
{
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void disable_interrupts()
|
||||||
|
{
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
}
|
||||||
20
src/kernel.c
20
src/kernel.c
@@ -1,33 +1,21 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "keyboard.h"
|
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
void kernel_main()
|
void kernel_main()
|
||||||
{
|
{
|
||||||
vga_clear();
|
vga_clear();
|
||||||
vga_print_success();
|
|
||||||
vga_print(" VGA intialzied\n");
|
|
||||||
|
|
||||||
init_keyboard();
|
pic_remap();
|
||||||
vga_print_success();
|
enable_interrupts();
|
||||||
vga_print(" Keyboard intialzied\n");
|
|
||||||
|
|
||||||
vga_print("\nWelcome to nub OS\n");
|
vga_print("\nWelcome to nub OS\n");
|
||||||
|
|
||||||
while (true)
|
kernel_halt();
|
||||||
{
|
|
||||||
__asm__ volatile ("cli");
|
|
||||||
__asm__ volatile ("hlt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel_panic()
|
void kernel_panic()
|
||||||
{
|
{
|
||||||
vga_print("Kernel panic!\n");
|
vga_print("Kernel panic!\n");
|
||||||
while (true)
|
kernel_halt();
|
||||||
{
|
|
||||||
__asm__ volatile ("cli");
|
|
||||||
__asm__ volatile ("hlt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
#pragma once
|
#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 "interrupts.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define SCANCODE_LEFT_SHIFT 42
|
#define SCANCODE_LEFT_SHIFT 42
|
||||||
#define SCANCODE_RIGHT_SHIFT 54
|
#define SCANCODE_RIGHT_SHIFT 54
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ section .text
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
; Set up idt
|
; Fill in the idt table with the stub functions
|
||||||
mov rdi, idt64
|
mov rdi, idt64
|
||||||
mov rsi, isr_stub_table
|
mov rsi, isr_stub_table
|
||||||
mov rcx, 256
|
mov rcx, 256
|
||||||
@@ -193,8 +193,8 @@ section .text
|
|||||||
add rsi, 8
|
add rsi, 8
|
||||||
loop .loop
|
loop .loop
|
||||||
lidt [idt64_descriptor]
|
lidt [idt64_descriptor]
|
||||||
sti
|
|
||||||
|
|
||||||
|
; Finally, we call in to c
|
||||||
call kernel_main
|
call kernel_main
|
||||||
.hang:
|
.hang:
|
||||||
hlt
|
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];
|
return vga_buffer[COLUMNS * row + col];
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_clear(void)
|
void vga_clear()
|
||||||
{
|
{
|
||||||
for (u8 row = 0; row < ROWS; row++)
|
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("[ ");
|
||||||
vga_print_colored("success", VGA_GREEN);
|
vga_print_colored("success", VGA_GREEN);
|
||||||
vga_print(" ]");
|
vga_print(" ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_print_error(void)
|
void vga_print_error()
|
||||||
{
|
{
|
||||||
vga_print("[ ");
|
vga_print("[ ");
|
||||||
vga_print_colored("error", VGA_RED);
|
vga_print_colored("error", VGA_RED);
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
typedef u8 vga_color_t;
|
typedef u8 vga_color_t;
|
||||||
|
|
||||||
void vga_clear(void);
|
void vga_clear();
|
||||||
void vga_set_cursor_position(u8 row, u8 col);
|
void vga_set_cursor_position(u8 row, u8 col);
|
||||||
|
|
||||||
void vga_print_char_colored(char character, vga_color_t color);
|
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_colored(const char* string, vga_color_t color);
|
||||||
|
|
||||||
void vga_print_success(void);
|
void vga_print_success();
|
||||||
void vga_print_error(void);
|
void vga_print_error();
|
||||||
|
|
||||||
void vga_print_uint(u32 value);
|
void vga_print_uint(u32 value);
|
||||||
void vga_print_int(i32 value);
|
void vga_print_int(i32 value);
|
||||||
|
|||||||
Reference in New Issue
Block a user