diff --git a/src/interrupts.c b/src/interrupts.c index b7c602e..f0da254 100644 --- a/src/interrupts.c +++ b/src/interrupts.c @@ -63,27 +63,17 @@ static const char* exception_messages[32] = { 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(); + kprintf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code); + kpanic(); } static irq_handler_t irq_handlers[16] = {0}; -void register_irq_handler(u8 irq, irq_handler_t handler) +void register_irq_handler(uint8_t irq, irq_handler_t handler) { if (irq >= 16) { - vga_print_error(); - vga_print("Cannot register irq "); - vga_print_uint(irq); - vga_print(" is out of bounds\n"); + kprintf("Cannot register irq %d is out of bounds\n", irq); } else { @@ -93,7 +83,7 @@ void register_irq_handler(u8 irq, irq_handler_t handler) void handle_irq(const isr_frame_t* frame) { - u8 irq = frame->int_no - 32; + uint8_t irq = frame->int_no - 32; if (irq_handlers[irq]) { @@ -110,7 +100,7 @@ void handle_irq(const isr_frame_t* frame) void handle_isr(const isr_frame_t* frame) { - vga_print("test"); + kprintf("isr"); if (frame->int_no < 32) { @@ -122,10 +112,6 @@ void handle_isr(const isr_frame_t* frame) } else { - vga_print_error(); - vga_print(" interrupt["); - vga_print_uint(frame->int_no); - vga_print("]: "); - vga_print("not implemented\n"); + kprintf("interrupt[%d]: not implemented\n", frame->int_no); } } \ No newline at end of file diff --git a/src/interrupts.h b/src/interrupts.h index 29376e5..7e2ebde 100644 --- a/src/interrupts.h +++ b/src/interrupts.h @@ -1,21 +1,21 @@ #pragma once -#include "typedef.h" +#include typedef struct { - u64 r15, r14, r13, r12, r11, r10, r9, r8; - u64 rbp, rdi, rsi, rdx, rcx, rbx, rax; - u64 int_no; - u64 err_code; - u64 rip, cs, rflags, rsp, ss; + uint64_t r15, r14, r13, r12, r11, r10, r9, r8; + uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax; + uint64_t int_no; + uint64_t err_code; + uint64_t rip, cs, rflags, rsp, ss; } __attribute__((packed)) isr_frame_t; typedef void (*irq_handler_t)(const isr_frame_t*); void pic_remap(); -void register_irq_handler(u8 irq, irq_handler_t handler); +void register_irq_handler(uint8_t irq, irq_handler_t handler); static inline void enable_interrupts() { diff --git a/src/kernel.c b/src/kernel.c index 132b7e0..31ef846 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,21 +1,67 @@ #include "kernel.h" #include "interrupts.h" +#include "string.h" #include "vga.h" +#include +#include -void kernel_main() +void kmain() { vga_clear(); pic_remap(); enable_interrupts(); - vga_print("\nWelcome to nub OS\n"); + kprintf("\nWelcome to nub OS\n"); - kernel_halt(); + khalt(); } -void kernel_panic() +void kpanic() { - vga_print("Kernel panic!\n"); - kernel_halt(); + kprintf("Kernel panic!\n"); + khalt(); +} + +void kprintf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + for (size_t i = 0; fmt[i] != '\0'; i++) + { + if (fmt[i] == '%') + { + i++; + if (fmt[i] == 's') + { + const char* str = va_arg(args, const char*); + for (size_t j = 0; str[j] != '\0'; j++) + { + vga_put_char(str[j], 0x0F); + } + } + else if (fmt[i] == 'd') + { + int val = va_arg(args, int); + char buf[12]; + itoa(val, buf); + for (size_t j = 0; buf[j] != '\0'; j++) + { + vga_put_char(buf[j], 0x0F); + } + } + else + { + vga_put_char('%', 0x0F); + vga_put_char(fmt[i], 0x0F); + } + } + else + { + vga_put_char(fmt[i], 0x0F); + } + } + + va_end(args); } \ No newline at end of file diff --git a/src/kernel.h b/src/kernel.h index c8d2e0e..cf8430f 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -1,12 +1,14 @@ #pragma once -void kernel_panic(); +void kpanic(); -static inline void kernel_halt() +static inline void khalt() { while (true) { __asm__ volatile ("cli"); __asm__ volatile ("hlt"); } -} \ No newline at end of file +} + +void kprintf(const char* fmt, ...); \ No newline at end of file diff --git a/src/keyboard.c b/src/keyboard.c index 7ead15d..d697730 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -33,7 +33,7 @@ bool caps_lock = false; static keyboard_handler_t keyboard_handlers[KEYBOARD_HANDLERS_LENGTH]; static int handler_index = 0; -char scan_code_to_ascii(u8 scan_code) +char scan_code_to_ascii(uint8_t scan_code) { if (scan_code >= 128) { @@ -52,8 +52,8 @@ char scan_code_to_ascii(u8 scan_code) void handle_keyboard(const isr_frame_t* frame) { - u8 code = inb(0x60); - u8 scan_code = code & 0x7F; + uint8_t code = inb(0x60); + uint8_t scan_code = code & 0x7F; bool pressed = (code & 0x80) == 0; switch (scan_code) @@ -82,7 +82,7 @@ void handle_keyboard(const isr_frame_t* frame) .ascii = scan_code_to_ascii(scan_code), }; - for (int i = 0; i < handler_index; i++) + for (size_t i = 0; i < handler_index; i++) { keyboard_handlers[i](&event); } @@ -96,9 +96,8 @@ void register_keypress_handler(const keyboard_handler_t handler) // keyboard_handlers is a dynamic list if (handler_index >= KEYBOARD_HANDLERS_LENGTH) { - vga_print_error(); - vga_print(" Maximum keyboard handlers reached\n"); - kernel_panic(); + kprintf("Maximum keyboard handlers reached\n"); + kpanic(); } keyboard_handlers[handler_index] = handler; diff --git a/src/keyboard.h b/src/keyboard.h index 4573070..c064f2b 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -1,10 +1,10 @@ #pragma once -#include "typedef.h" +#include typedef struct { - u8 scan_code; + uint8_t scan_code; bool pressed; bool shift; bool caps_lock; @@ -15,4 +15,4 @@ typedef void (*keyboard_handler_t)(const keyboard_event_t*); void init_keyboard(); void register_keypress_handler(keyboard_handler_t handler); -char scan_code_to_ascii(u8 scan_code); \ No newline at end of file +char scan_code_to_ascii(uint8_t scan_code); \ No newline at end of file diff --git a/src/multiboot.h b/src/multiboot.h index 73ffb30..dd9044c 100644 --- a/src/multiboot.h +++ b/src/multiboot.h @@ -1,59 +1,59 @@ #pragma once -#include "typedef.h" +#include typedef struct multiboot_info { - u32 flags; // required + uint32_t flags; // required // Available if flags[0] is set - u32 mem_lower; - u32 mem_upper; + uint32_t mem_lower; + uint32_t mem_upper; // Available if flags[1] is set - u32 boot_device; + uint32_t boot_device; // Available if flags[2] is set - u32 cmdline; + uint32_t cmdline; // Available if flags[3] is set - u32 mods_count; - u32 mods_addr; + uint32_t mods_count; + uint32_t mods_addr; // Available if flags[4] or flags[5] is set - u8 syms[16]; // 28 - 40 bytes, exact layout may differ depending on a.out or ELF + uint8_t syms[16]; // 28 - 40 bytes, exact layout may differ depending on a.out or ELF // Available if flags[6] is set - u32 mmap_length; - u32 mmap_addr; + uint32_t mmap_length; + uint32_t mmap_addr; // Available if flags[7] is set - u32 drives_length; - u32 drives_addr; + uint32_t drives_length; + uint32_t drives_addr; // Available if flags[8] is set - u32 config_table; + uint32_t config_table; // Available if flags[9] is set - u32 boot_loader_name; + uint32_t boot_loader_name; // Available if flags[10] is set - u32 apm_table; + uint32_t apm_table; // Available if flags[11] is set - u32 vbe_control_info; - u32 vbe_mode_info; - u16 vbe_mode; - u16 vbe_interface_seg; - u16 vbe_interface_off; - u16 vbe_interface_len; + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; // Available if flags[12] is set - u64 framebuffer_addr; // 64-bit for large memory addresses - u32 framebuffer_pitch; - u32 framebuffer_width; - u32 framebuffer_height; - u8 framebuffer_bpp; - u8 framebuffer_type; - u8 color_info[6]; // 110-115 bytes + uint64_t framebuffer_addr; // 64-bit for large memory addresses + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; + uint8_t color_info[6]; // 110-115 bytes } __attribute__((packed)) multiboot_info_t; \ No newline at end of file diff --git a/src/start.asm b/src/start.asm index 42418c8..f1da24f 100644 --- a/src/start.asm +++ b/src/start.asm @@ -1,5 +1,5 @@ global _start -extern kernel_main +extern kmain extern handle_isr %define FLAGS 0b10 @@ -195,7 +195,7 @@ section .text lidt [idt64_descriptor] ; Finally, we call in to c - call kernel_main + call kmain .hang: hlt jmp .hang diff --git a/src/string.c b/src/string.c index ecf9ea6..01ab9b5 100644 --- a/src/string.c +++ b/src/string.c @@ -25,7 +25,7 @@ void reverse(char* str, size_t length) } } -int uitoa(u64 value, char* buffer) +int uitoa(uint64_t value, char* buffer) { int i = 0; if (value == 0) @@ -46,7 +46,7 @@ int uitoa(u64 value, char* buffer) return i; } -int itoa(i64 value, char* buffer) +int itoa(int64_t value, char* buffer) { int i = 0; @@ -58,16 +58,16 @@ int itoa(i64 value, char* buffer) } bool negative = false; - u64 v; + uint64_t v; if (value < 0) { negative = true; - v = (u64)(-value); + v = (uint64_t)(-value); } else { - v = (u64)value; + v = (uint64_t)value; } while (v > 0) diff --git a/src/string.h b/src/string.h index 853d7fe..49ed2aa 100644 --- a/src/string.h +++ b/src/string.h @@ -1,8 +1,9 @@ #pragma once -#include "typedef.h" +#include +#include int strcmp(const char* a, const char* b); void reverse(char* str, size_t length); -int uitoa(u64 value, char* buffer); -int itoa(i64 value, char* buffer); \ No newline at end of file +int uitoa(uint64_t value, char* buffer); +int itoa(int64_t value, char* buffer); \ No newline at end of file diff --git a/src/typedef.h b/src/typedef.h deleted file mode 100644 index 85573fb..0000000 --- a/src/typedef.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -typedef unsigned char u8; -typedef signed char i8; - -typedef unsigned short u16; -typedef signed short i16; - -typedef unsigned int u32; -typedef signed int i32; - -typedef unsigned long long u64; -typedef signed long long i64; - -typedef u64 size_t; -typedef u64 uintptr_t; diff --git a/src/util.h b/src/util.h index 6df418f..87c7e3b 100644 --- a/src/util.h +++ b/src/util.h @@ -1,13 +1,15 @@ #pragma once -static inline void outb(u16 port, u8 val) +#include + +static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); } -static inline u8 inb(u16 port) +static inline uint8_t inb(uint16_t port) { - u8 ret; + uint8_t ret; __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } diff --git a/src/vga.c b/src/vga.c index cd83a30..73a8d7f 100644 --- a/src/vga.c +++ b/src/vga.c @@ -1,57 +1,20 @@ #include "vga.h" -#include "string.h" +#include #define ROWS 25 #define COLUMNS 80 typedef struct { - u8 character; - u8 color; -} vga_char; + uint8_t character; + uint8_t color; +} vga_char_t; -vga_char* vga_buffer = (vga_char*)0xb8000; -u8 cursor_row = 0; -u8 cursor_col = 0; +static vga_char_t* vga_buffer = (vga_char_t*)0xb8000; +static uint8_t cursor_row = 0; +static uint8_t cursor_col = 0; -void vga_set_char(u8 row, u8 col, vga_char character) -{ - vga_buffer[COLUMNS * row + col] = character; -} - -vga_char vga_char_at(u8 row, u8 col) -{ - return vga_buffer[COLUMNS * row + col]; -} - -void vga_clear() -{ - for (u8 row = 0; row < ROWS; row++) - { - for (u8 col = 0; col < COLUMNS; col++) - { - vga_char character = { - .character = ' ', - .color = vga_default_color(), - }; - vga_set_char(row, col, character); - } - } - - cursor_row = 0; - cursor_col = 0; -} - -void vga_set_cursor_position(u8 row, u8 col) -{ - if (row < ROWS && col < COLUMNS) - { - cursor_row = row; - cursor_col = col; - } -} - -void vga_print_char_colored(char character, vga_color_t color) +void vga_put_char(char character, uint8_t color) { switch (character) { @@ -68,17 +31,16 @@ void vga_print_char_colored(char character, vga_color_t color) } case '\t': { - u8 remainter = cursor_col % 4; + uint8_t remainter = cursor_col % 4; cursor_col += remainter == 0 ? 4 : remainter; break; } default: { - vga_char c = { + vga_buffer[COLUMNS * cursor_row + cursor_col] = (vga_char_t){ .character = character, .color = color, }; - vga_set_char(cursor_row, cursor_col, c); cursor_col += 1; break; } @@ -92,59 +54,39 @@ void vga_print_char_colored(char character, vga_color_t color) if (cursor_row >= ROWS) { - for (u8 row = 1; row < ROWS; row++) + for (size_t row = 1; row < ROWS; row++) { - for (u8 col = 0; col < COLUMNS; col++) + for (size_t col = 0; col < COLUMNS; col++) { - vga_set_char(row - 1, col, vga_char_at(row, col)); + vga_buffer[COLUMNS * row - 1 + col] = vga_buffer[COLUMNS * row + col]; } } - for (u8 col = 0; col < COLUMNS; col++) + for (size_t col = 0; col < COLUMNS; col++) { - vga_char c = { + vga_buffer[ROWS - 1 + col] = (vga_char_t){ .character = ' ', - .color = vga_default_color(), + .color = VGA_LIGHT_GRAY | VGA_BLACK << 4, }; - vga_set_char(ROWS - 1, col, c); }; cursor_row = ROWS - 1; } } -void vga_print_colored(const char* string, vga_color_t color) +void vga_clear() { - for (u8 i = 0; string[i] != '\0'; i++) + for (size_t row = 0; row < ROWS; row++) { - vga_print_char_colored(string[i], color); + for (size_t col = 0; col < COLUMNS; col++) + { + vga_buffer[COLUMNS * row - 1 + col] = (vga_char_t){ + .character = ' ', + .color = VGA_LIGHT_GRAY | VGA_BLACK << 4, + }; + } } -} -void vga_print_success() -{ - vga_print("[ "); - vga_print_colored("success", VGA_GREEN); - vga_print(" ]"); -} - -void vga_print_error() -{ - vga_print("[ "); - vga_print_colored("error", VGA_RED); - vga_print(" ]"); -} - -void vga_print_uint(u32 value) -{ - char buffer[11]; - uitoa(value, buffer); - vga_print(buffer); -} - -void vga_print_int(i32 value) -{ - char buffer[12]; - itoa(value, buffer); - vga_print(buffer); + cursor_row = 0; + cursor_col = 0; } \ No newline at end of file diff --git a/src/vga.h b/src/vga.h index 42ef7c9..0de24de 100644 --- a/src/vga.h +++ b/src/vga.h @@ -1,6 +1,6 @@ #pragma once -#include "typedef.h" +#include #define VGA_BLACK 0 #define VGA_BLUE 1 @@ -19,36 +19,5 @@ #define VGA_YELLOW 14 #define VGA_WHITE 15 -typedef u8 vga_color_t; - +void vga_put_char(char character, uint8_t color); 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 vga_print_error(); - -void vga_print_uint(u32 value); -void vga_print_int(i32 value); - -static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color) -{ - return fg_color | bg_color << 4; -} - -static inline vga_color_t vga_default_color() -{ - return vga_color(VGA_LIGHT_GRAY, VGA_BLACK); -} - -static inline void vga_print_char(char character) -{ - vga_print_char_colored(character, vga_default_color()); -} - -static inline void vga_print(const char* string) -{ - vga_print_colored(string, vga_default_color()); -} \ No newline at end of file