diff --git a/makefile b/makefile index 67d847b..a01d9fe 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ LD = x86_64-elf-ld CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 LDFLAGS = -SRC_C := src/kernel.c src/vga.c src/idt.c src/string.c +SRC_C := src/kernel.c src/vga.c src/idt.c src/string.c src/keyboard.c SRC_ASM := src/boot.asm src/idt_stub.asm OBJ_C := $(SRC_C:src/%.c=.build/%.o) diff --git a/src/boot.asm b/src/boot.asm index dc65ba7..a538bfb 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -195,8 +195,8 @@ long_mode_start: mov fs, ax mov gs, ax - extern kernel_main - call kernel_main + extern kmain + call kmain cli .hang: diff --git a/src/idt.c b/src/idt.c index e4ed5da..83cc5c2 100644 --- a/src/idt.c +++ b/src/idt.c @@ -66,18 +66,6 @@ static const char* exception_messages[32] = { "divide by zero", static interrupt_descriptor idt[IDT_SIZE]; -static inline void outb(uint16_t port, uint8_t val) -{ - __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline uint8_t inb(uint16_t port) -{ - uint8_t ret; - __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - static void pic_remap(int offset1, int offset2) { uint8_t a1, a2; @@ -129,7 +117,7 @@ static inline void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl entry->reserved = 0; } -void idt_init(void) +void init_idt(void) { pic_remap(0x20, 0x28); @@ -144,11 +132,6 @@ void idt_init(void) __asm__ volatile("sti"); } -void idt_enable(void) -{ - __asm__ volatile("sti"); -} - void handle_isr(isr_frame_t* frame) { if (frame->int_no < 32) diff --git a/src/idt.h b/src/idt.h index 1459cf7..cb8ce6e 100644 --- a/src/idt.h +++ b/src/idt.h @@ -13,6 +13,18 @@ typedef struct typedef void (*irq_handler_t)(isr_frame_t*); -void idt_init(void); -void idt_enable(void); +void init_idt(void); + +static inline void outb(uint16_t port, uint8_t val) +{ + __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} + +static inline uint8_t inb(uint16_t port) +{ + uint8_t ret; + __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + void register_irq_handler(uint8_t irq, irq_handler_t handler); \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index a80db5e..1d4a452 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,21 +1,43 @@ +#include "kernel.h" #include "idt.h" +#include "keyboard.h" #include "vga.h" #include -void kernel_main(void) +void keyboard_handler(keyboard_event_t* event) +{ + if (event->pressed) + { + vga_print_int(event->scan_code); + vga_print("\n"); + } +} + +void kmain(void) { vga_clear(); vga_print_success(); vga_print(" VGA intialzied\n"); - idt_init(); - idt_enable(); + init_idt(); vga_print_success(); vga_print(" IDT intialzied\n"); + init_keyboard(); + vga_print_success(); + vga_print(" Keyboard driver intialzied\n"); + vga_print("\nWelcome to nub OS\n"); + register_keypress_handler(keyboard_handler); + while (true) { } +} + +void kpanic() +{ + vga_print("Kernel panic!\n"); + __asm__ volatile("cli; hlt"); } \ No newline at end of file diff --git a/src/kernel.h b/src/kernel.h new file mode 100644 index 0000000..6467faa --- /dev/null +++ b/src/kernel.h @@ -0,0 +1,3 @@ +#pragma once + +void kpanic(); diff --git a/src/keyboard.c b/src/keyboard.c new file mode 100644 index 0000000..55b6241 --- /dev/null +++ b/src/keyboard.c @@ -0,0 +1,72 @@ +#include "keyboard.h" +#include "idt.h" +#include "kernel.h" +#include "vga.h" +#include +#include + +#define SCANCODE_LEFT_SHIFT 42 +#define SCANCODE_RIGHT_SHIFT 54 +#define SCANCODE_CAPS_LOCK 58 + +#define KEYBOARD_HANDLERS_LENGTH 32 + +bool shift = false; +bool caps_lock = false; + +// todo(nub): make dynamic when a memory allocator is implemented +static keyboard_handler_t keyboard_handlers[KEYBOARD_HANDLERS_LENGTH]; +static int handler_index = 0; + +void handle_keyboard(isr_frame_t* frame) +{ + uint8_t code = inb(0x60); + uint8_t scan_code = code & 0x7F; + bool pressed = (code & 0x80) == 0; + + switch (scan_code) + { + case SCANCODE_LEFT_SHIFT: + case SCANCODE_RIGHT_SHIFT: + { + shift = pressed; + break; + } + case SCANCODE_CAPS_LOCK: + { + if (pressed) + { + caps_lock = !caps_lock; + } + break; + } + default: + { + keyboard_event_t event = { .scan_code = scan_code, .pressed = pressed, .caps_lock = caps_lock, .shift = shift }; + + for (int i = 0; i < handler_index; i++) + { + keyboard_handlers[i](&event); + } + } + } +} + +void register_keypress_handler(keyboard_handler_t handler) +{ + // todo(nub31): remove when a memory allocator is implemented and keyboard_handlers is a dynamic list + if (handler_index >= KEYBOARD_HANDLERS_LENGTH) + { + vga_print_error(); + vga_print(" Maximum keyboard handlers reached\n"); + kpanic(); + } + + keyboard_handlers[handler_index] = handler; + handler_index += 1; +} + +void init_keyboard() +{ + register_irq_handler(1, handle_keyboard); +} \ No newline at end of file diff --git a/src/keyboard.h b/src/keyboard.h new file mode 100644 index 0000000..7f92ff4 --- /dev/null +++ b/src/keyboard.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +typedef struct +{ + uint8_t scan_code; + bool pressed; + bool shift; + bool caps_lock; +} keyboard_event_t; + +typedef void (*keyboard_handler_t)(keyboard_event_t*); + +void init_keyboard(); +void register_keypress_handler(keyboard_handler_t handler); \ No newline at end of file diff --git a/src/vga.c b/src/vga.c index 201c44d..8dec3a2 100644 --- a/src/vga.c +++ b/src/vga.c @@ -51,7 +51,7 @@ void vga_set_cursor_position(uint8_t row, uint8_t col) } } -void vga_print_char(char character, vga_color_t color) +void vga_print_char_colored(char character, vga_color_t color) { switch (character) { @@ -101,11 +101,16 @@ void vga_print_char(char character, vga_color_t color) } } +void vga_print_char(char character) +{ + vga_print_char_colored(character, vga_default_color()); +} + void vga_print_colored(const char* string, vga_color_t color) { for (uint8_t i = 0; string[i] != '\0'; i++) { - vga_print_char(string[i], color); + vga_print_char_colored(string[i], color); } } diff --git a/src/vga.h b/src/vga.h index b3b17c1..dacec3b 100644 --- a/src/vga.h +++ b/src/vga.h @@ -24,6 +24,7 @@ typedef uint8_t vga_color_t; void vga_clear(void); void vga_set_cursor_position(uint8_t row, uint8_t col); +void vga_print_char(char character); void vga_print_colored(const char* string, vga_color_t color); void vga_print(const char* string);