From 87d1a291f7fce4714c356ff510746e26d0c953d7 Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 3 Sep 2025 13:13:16 +0200 Subject: [PATCH] ... --- .clangd | 10 ++ makefile | 6 +- src/arch/arch.h | 4 + src/arch/mmap.h | 17 ++++ src/arch/x86_64/interrupts.c | 8 +- src/arch/x86_64/interrupts.h | 3 - src/arch/x86_64/keyboard.c | 189 +++++++++++++++++------------------ src/arch/x86_64/keyboard.h | 30 +++--- src/arch/x86_64/mmap.c | 44 ++++++++ src/arch/x86_64/mmap.h | 6 ++ src/arch/x86_64/pmm.h | 10 -- src/arch/x86_64/start.asm | 4 +- src/{ => arch/x86_64}/util.h | 8 ++ src/{ => arch/x86_64}/vga.c | 0 src/{ => arch/x86_64}/vga.h | 0 src/arch/x86_64/x86_64.c | 37 +++++++ src/kernel.c | 104 +------------------ src/kernel.h | 14 +-- src/{arch/x86_64 => }/pmm.c | 46 ++------- src/pmm.h | 9 ++ src/{ => stdlib}/mem.c | 0 src/{ => stdlib}/mem.h | 0 src/stdlib/stdio.c | 84 ++++++++++++++++ src/stdlib/stdio.h | 3 + src/{ => stdlib}/string.c | 0 src/{ => stdlib}/string.h | 4 +- 26 files changed, 353 insertions(+), 287 deletions(-) create mode 100644 .clangd create mode 100644 src/arch/arch.h create mode 100644 src/arch/mmap.h create mode 100644 src/arch/x86_64/mmap.c create mode 100644 src/arch/x86_64/mmap.h delete mode 100644 src/arch/x86_64/pmm.h rename src/{ => arch/x86_64}/util.h (96%) rename src/{ => arch/x86_64}/vga.c (100%) rename src/{ => arch/x86_64}/vga.h (100%) create mode 100644 src/arch/x86_64/x86_64.c rename src/{arch/x86_64 => }/pmm.c (64%) create mode 100644 src/pmm.h rename src/{ => stdlib}/mem.c (100%) rename src/{ => stdlib}/mem.h (100%) create mode 100644 src/stdlib/stdio.c create mode 100644 src/stdlib/stdio.h rename src/{ => stdlib}/string.c (100%) rename src/{ => stdlib}/string.h (67%) diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..4ad4a3d --- /dev/null +++ b/.clangd @@ -0,0 +1,10 @@ +CompileFlags: + Add: + - "-target" + - "x86_64-unknown-none" + - "-ffreestanding" + - "-fno-builtin" + - "-fno-common" + - "-fno-strict-aliasing" + - "-nostdlib" + - "-Istdlib" diff --git a/makefile b/makefile index 07e82d6..b6183f1 100644 --- a/makefile +++ b/makefile @@ -3,12 +3,12 @@ LD = x86_64-elf-ld AS = nasm TARGET_PATH = src/arch/x86_64 -CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c11 -g +CFLAGS = -m64 -ffreestanding -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c11 -I src/stdlib -g LDFLAGS = -g ASFLAGS = -f elf64 -g -F dwarf -SRC_C := $(shell find src -name '*.c') -SRC_ASM := $(shell find src -name '*.asm') +SRC_C := $(shell find src -name '*.c' ) +SRC_ASM := $(shell find src -name '*.asm' ) OBJS := $(patsubst src/%.c, .build/%.o, $(SRC_C)) $(patsubst src/%.asm, .build/%.o, $(SRC_ASM)) diff --git a/src/arch/arch.h b/src/arch/arch.h new file mode 100644 index 0000000..37e677d --- /dev/null +++ b/src/arch/arch.h @@ -0,0 +1,4 @@ +#pragma once + +void panic(); +void put_char(char character); \ No newline at end of file diff --git a/src/arch/mmap.h b/src/arch/mmap.h new file mode 100644 index 0000000..3278d65 --- /dev/null +++ b/src/arch/mmap.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +typedef struct +{ + uint64_t base_address; + uint64_t length; +} memory_region_t; + +typedef struct +{ + uint64_t num_regions; + memory_region_t* regions; +} memory_map_t; + +extern memory_map_t memory_map; \ No newline at end of file diff --git a/src/arch/x86_64/interrupts.c b/src/arch/x86_64/interrupts.c index 594c375..f699efc 100644 --- a/src/arch/x86_64/interrupts.c +++ b/src/arch/x86_64/interrupts.c @@ -1,5 +1,7 @@ #include "interrupts.h" -#include "../../util.h" +#include "../arch.h" +#include "util.h" +#include #define PIC1_COMMAND 0x20 #define PIC1_DATA 0x21 @@ -84,7 +86,7 @@ void disable_pic() printf("PIC disabled\n"); } -void handle_exception(const isr_frame_t* frame) +static void handle_exception(const isr_frame_t* frame) { printf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code); panic(); @@ -103,7 +105,7 @@ void register_irq_handler(uint8_t irq, irq_handler_t handler) } } -void handle_irq(const isr_frame_t* frame) +static void handle_irq(const isr_frame_t* frame) { uint8_t irq = frame->int_no - 32; diff --git a/src/arch/x86_64/interrupts.h b/src/arch/x86_64/interrupts.h index 2fdcff6..5cfbd2d 100644 --- a/src/arch/x86_64/interrupts.h +++ b/src/arch/x86_64/interrupts.h @@ -1,6 +1,5 @@ #pragma once -#include "../../kernel.h" #include #include @@ -26,11 +25,9 @@ void register_irq_handler(uint8_t irq, irq_handler_t handler); static inline void enable_interrupts() { __asm__ volatile("sti"); - printf("Interrupts enabled\n"); } static inline void disable_interrupts() { __asm__ volatile("cli"); - printf("Interrupts disabled\n"); } \ No newline at end of file diff --git a/src/arch/x86_64/keyboard.c b/src/arch/x86_64/keyboard.c index d443789..8bd5d88 100644 --- a/src/arch/x86_64/keyboard.c +++ b/src/arch/x86_64/keyboard.c @@ -1,110 +1,107 @@ -#include "keyboard.h" -#include "../../kernel.h" -#include "../../util.h" -#include "interrupts.h" -#include +// #include "keyboard.h" +// #include "interrupts.h" +// #include "util.h" +// #include -#define SCANCODE_LEFT_SHIFT 42 -#define SCANCODE_RIGHT_SHIFT 54 -#define SCANCODE_CAPS_LOCK 58 +// #define SCANCODE_LEFT_SHIFT 42 +// #define SCANCODE_RIGHT_SHIFT 54 +// #define SCANCODE_CAPS_LOCK 58 -#define KEYBOARD_HANDLERS_LENGTH 32 +// #define KEYBOARD_HANDLERS_LENGTH 32 -unsigned const char us_keymap[128] = { - 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', - 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', - 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', - 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; +// unsigned const char us_keymap[128] = { +// 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', +// 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', +// 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', +// 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// }; -unsigned const char us_keymap_shift[128] = { - 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', - 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', - 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', - 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; +// unsigned const char us_keymap_shift[128] = { +// 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', +// 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', +// 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', +// 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// }; -bool shift = false; -bool caps_lock = false; +// 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 size_t handler_index = 0; +// // todo(nub): make dynamic when a memory allocator is implemented +// static keyboard_handler_t keyboard_handlers[KEYBOARD_HANDLERS_LENGTH]; +// static size_t handler_index = 0; -char scan_code_to_ascii(uint8_t scan_code) -{ - if (scan_code >= 128) - { - return 0; - } +// char scan_code_to_ascii(uint8_t scan_code) +// { +// if (scan_code >= 128) +// { +// return 0; +// } - if ((!caps_lock && shift) || (caps_lock && !shift)) - { - return us_keymap_shift[scan_code]; - } - else - { - return us_keymap[scan_code]; - } -} +// if ((!caps_lock && shift) || (caps_lock && !shift)) +// { +// return us_keymap_shift[scan_code]; +// } +// else +// { +// return us_keymap[scan_code]; +// } +// } -void handle_keyboard(const isr_frame_t* frame) -{ - uint8_t code = inb(0x60); - uint8_t scan_code = code & 0x7F; - bool pressed = (code & 0x80) == 0; +// void handle_keyboard(const 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, - .ascii = scan_code_to_ascii(scan_code), - }; +// 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, +// .ascii = scan_code_to_ascii(scan_code), +// }; - for (size_t i = 0; i < handler_index; i++) - { - keyboard_handlers[i](&event); - } - } - } -} +// for (size_t i = 0; i < handler_index; i++) +// { +// keyboard_handlers[i](&event); +// } +// } +// } +// } -void register_keypress_handler(const 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) - { - printf("Maximum keyboard handlers reached\n"); - panic(); - } +// void register_keypress_handler(const 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) +// { +// } - keyboard_handlers[handler_index] = handler; - handler_index += 1; -} +// keyboard_handlers[handler_index] = handler; +// handler_index += 1; +// } -void init_keyboard() -{ - register_irq_handler(1, handle_keyboard); -} \ No newline at end of file +// void init_keyboard() +// { +// register_irq_handler(1, handle_keyboard); +// } \ No newline at end of file diff --git a/src/arch/x86_64/keyboard.h b/src/arch/x86_64/keyboard.h index 104a409..eac0d16 100644 --- a/src/arch/x86_64/keyboard.h +++ b/src/arch/x86_64/keyboard.h @@ -1,19 +1,19 @@ -#pragma once +// #pragma once -#include -#include +// #include +// #include -typedef struct -{ - uint8_t scan_code; - bool pressed; - bool shift; - bool caps_lock; - char ascii; -} keyboard_event_t; +// typedef struct +// { +// uint8_t scan_code; +// bool pressed; +// bool shift; +// bool caps_lock; +// char ascii; +// } keyboard_event_t; -typedef void (*keyboard_handler_t)(const keyboard_event_t*); +// 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(uint8_t scan_code); \ No newline at end of file +// void init_keyboard(); +// void register_keypress_handler(keyboard_handler_t handler); +// char scan_code_to_ascii(uint8_t scan_code); \ No newline at end of file diff --git a/src/arch/x86_64/mmap.c b/src/arch/x86_64/mmap.c new file mode 100644 index 0000000..f2e701d --- /dev/null +++ b/src/arch/x86_64/mmap.c @@ -0,0 +1,44 @@ +#include "mmap.h" +#include "../mmap.h" +#include +#include + +#define USABLE_REGION_SIZE 32 + +memory_map_t memory_map; + +static memory_region_t usable_regions[USABLE_REGION_SIZE]; + +void map_memory(multiboot_info_t* mbd) +{ + if (!(mbd->flags & (1 << 6))) + { + printf("Invalid memory map given by bootloader\n"); + panic(); + } + + size_t num_regions = 0; + + uint64_t offset = 0; + while (offset < mbd->mmap_length) + { + multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + offset); + + if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE && num_regions < USABLE_REGION_SIZE) + { + usable_regions[num_regions] = (memory_region_t){ + .base_address = mmmt->addr, + .length = mmmt->len, + }; + + num_regions++; + } + + offset += mmmt->size + sizeof(mmmt->size); + } + + memory_map = (memory_map_t){ + .num_regions = num_regions, + .regions = usable_regions, + }; +} \ No newline at end of file diff --git a/src/arch/x86_64/mmap.h b/src/arch/x86_64/mmap.h new file mode 100644 index 0000000..838c45c --- /dev/null +++ b/src/arch/x86_64/mmap.h @@ -0,0 +1,6 @@ +#pragma once + +#include "../arch.h" +#include "multiboot.h" + +void map_memory(multiboot_info_t* mbd); diff --git a/src/arch/x86_64/pmm.h b/src/arch/x86_64/pmm.h deleted file mode 100644 index 500b58b..0000000 --- a/src/arch/x86_64/pmm.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "multiboot.h" -#include - -#define PAGE_SIZE 4096 - -void init_pmm(multiboot_info_t* mbd); -uint64_t pmm_alloc_page(); -void pmm_free_page(uint64_t addr); \ No newline at end of file diff --git a/src/arch/x86_64/start.asm b/src/arch/x86_64/start.asm index 1890481..65effce 100644 --- a/src/arch/x86_64/start.asm +++ b/src/arch/x86_64/start.asm @@ -1,5 +1,5 @@ global _start -extern kmain +extern entry extern handle_isr extern pml4 @@ -205,7 +205,7 @@ section .text ; Finally, we call in to c mov rdi, [multiboot_info] - call kmain + call entry .hang: hlt jmp .hang diff --git a/src/util.h b/src/arch/x86_64/util.h similarity index 96% rename from src/util.h rename to src/arch/x86_64/util.h index a0a4863..a843e64 100644 --- a/src/util.h +++ b/src/arch/x86_64/util.h @@ -102,4 +102,12 @@ static inline void wrmsr(uint32_t msr, uint64_t value) uint32_t lo = (uint32_t)value; uint32_t hi = (uint32_t)(value >> 32); __asm__ volatile("wrmsr" : : "c"(msr), "a"(lo), "d"(hi)); +} + +static inline void halt() +{ + while (true) + { + __asm__ volatile("hlt"); + } } \ No newline at end of file diff --git a/src/vga.c b/src/arch/x86_64/vga.c similarity index 100% rename from src/vga.c rename to src/arch/x86_64/vga.c diff --git a/src/vga.h b/src/arch/x86_64/vga.h similarity index 100% rename from src/vga.h rename to src/arch/x86_64/vga.h diff --git a/src/arch/x86_64/x86_64.c b/src/arch/x86_64/x86_64.c new file mode 100644 index 0000000..b2d381c --- /dev/null +++ b/src/arch/x86_64/x86_64.c @@ -0,0 +1,37 @@ +#include "../../kernel.h" +#include "../arch.h" +#include "interrupts.h" +#include "mmap.h" +#include "multiboot.h" +#include "util.h" +#include "vga.h" +#include +#include + +void entry(multiboot_info_t* mbd) +{ + vga_clear(); + map_memory(mbd); + remap_pic(); + enable_interrupts(); + kmain(); +} + +void arch_callback() +{ + printf("Kernel panic!\n"); + disable_interrupts(); + halt(); +} + +void panic() +{ + printf("Kernel panic!"); + disable_interrupts(); + halt(); +} + +void put_char(char character) +{ + vga_put_char(character, VGA_DEFAULT_COLOR); +} \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index d834a6a..d88e7fd 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,105 +1,9 @@ #include "kernel.h" -#include "arch/x86_64/interrupts.h" -#include "arch/x86_64/multiboot.h" -#include "arch/x86_64/pmm.h" -#include "string.h" -#include "vga.h" -#include +#include "pmm.h" +#include -void kmain(multiboot_info_t* mbd) +void kmain() { - vga_clear(); - - init_pmm(mbd); - - remap_pic(); - enable_interrupts(); - + init_pmm(); printf("Welcome to nub OS :)\n"); - halt(); } - -void panic() -{ - printf("Kernel panic!\n"); - disable_interrupts(); - halt(); -} - -void printf(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - bool should_format = false; - - for (size_t i = 0; fmt[i] != '\0'; i++) - { - if (should_format) - { - should_format = false; - - if (fmt[i] == '%') - { - vga_put_char('%', VGA_DEFAULT_COLOR); - } - else 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], VGA_DEFAULT_COLOR); - } - } - else if (fmt[i] == 'c') - { - char character = (char)va_arg(args, int64_t); - vga_put_char(character, VGA_DEFAULT_COLOR); - } - else if (fmt[i] == 'd') - { - int64_t val = va_arg(args, int64_t); - char buf[21]; - itoa64(val, buf); - for (size_t j = 0; buf[j] != '\0'; j++) - { - vga_put_char(buf[j], VGA_DEFAULT_COLOR); - } - } - else if (fmt[i] == 'u') - { - uint64_t val = va_arg(args, uint64_t); - char buf[21]; - uitoa64(val, buf); - for (size_t j = 0; buf[j] != '\0'; j++) - { - vga_put_char(buf[j], VGA_DEFAULT_COLOR); - } - } - else if (fmt[i] == 'x') - { - uint64_t val = va_arg(args, uint64_t); - char buf[17]; - uitoa64_hex(val, buf); - for (size_t j = 0; buf[j] != '\0'; j++) - { - vga_put_char(buf[j], VGA_DEFAULT_COLOR); - } - } - else - { - vga_put_char(fmt[i], VGA_DEFAULT_COLOR); - } - } - else if (fmt[i] == '%') - { - should_format = true; - } - else - { - vga_put_char(fmt[i], VGA_DEFAULT_COLOR); - } - } - - va_end(args); -} \ No newline at end of file diff --git a/src/kernel.h b/src/kernel.h index daebd26..e80bba2 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -1,15 +1,3 @@ #pragma once -#include - -void panic(); - -void printf(const char* fmt, ...); - -static inline void halt() -{ - while (true) - { - __asm__ volatile("hlt"); - } -} \ No newline at end of file +void kmain(); \ No newline at end of file diff --git a/src/arch/x86_64/pmm.c b/src/pmm.c similarity index 64% rename from src/arch/x86_64/pmm.c rename to src/pmm.c index 1bb65fe..b3856e1 100644 --- a/src/arch/x86_64/pmm.c +++ b/src/pmm.c @@ -1,58 +1,24 @@ #include "pmm.h" -#include "../../kernel.h" -#include "../../mem.h" +#include "arch/mmap.h" +#include #include #include +#include #define BITMAP_SIZE 32768 // Supports up to 1GB of RAM #define USABLE_REGION_SIZE 32 -typedef struct -{ - uint64_t base_address; - uint64_t length; -} memory_region_t; - static uint8_t page_bitmap[BITMAP_SIZE]; static uint64_t total_pages = 0; static uint64_t free_pages = 0; -void init_pmm(multiboot_info_t* mbd) +void init_pmm() { - memory_region_t usable_regions[USABLE_REGION_SIZE]; - size_t num_regions = 0; - - if (!(mbd->flags & (1 << 6))) - { - printf("Invalid memory map given by bootloader\n"); - panic(); - } - - uint64_t offset = 0; - while (offset < mbd->mmap_length) - { - multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + offset); - - if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE && num_regions < USABLE_REGION_SIZE) - { - usable_regions[num_regions] = (memory_region_t){ - .base_address = mmmt->addr, - .length = mmmt->len, - }; - - num_regions++; - - printf("Available memory: 0x%x - 0x%x (%u KB)\n", mmmt->addr, mmmt->addr + mmmt->len, mmmt->len / 1024); - } - - offset += mmmt->size + sizeof(mmmt->size); - } - memset(page_bitmap, 0xFF, BITMAP_SIZE); - for (size_t i = 0; i < num_regions; i++) + for (size_t i = 0; i < memory_map.num_regions; i++) { - memory_region_t region = usable_regions[i]; + memory_region_t region = memory_map.regions[i]; uint64_t start_page = region.base_address / PAGE_SIZE; uint64_t num_pages = region.length / PAGE_SIZE; diff --git a/src/pmm.h b/src/pmm.h new file mode 100644 index 0000000..421f758 --- /dev/null +++ b/src/pmm.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#define PAGE_SIZE 4096 + +void init_pmm(); +uint64_t pmm_alloc_page(); +void pmm_free_page(uint64_t addr); \ No newline at end of file diff --git a/src/mem.c b/src/stdlib/mem.c similarity index 100% rename from src/mem.c rename to src/stdlib/mem.c diff --git a/src/mem.h b/src/stdlib/mem.h similarity index 100% rename from src/mem.h rename to src/stdlib/mem.h diff --git a/src/stdlib/stdio.c b/src/stdlib/stdio.c new file mode 100644 index 0000000..f23cd1d --- /dev/null +++ b/src/stdlib/stdio.c @@ -0,0 +1,84 @@ +#include "stdio.h" +#include "../arch/arch.h" +#include "string.h" +#include +#include +#include + +void printf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + bool should_format = false; + + for (size_t i = 0; fmt[i] != '\0'; i++) + { + if (should_format) + { + should_format = false; + + if (fmt[i] == '%') + { + put_char('%'); + } + else if (fmt[i] == 's') + { + const char* str = va_arg(args, const char*); + for (size_t j = 0; str[j] != '\0'; j++) + { + put_char(str[j]); + } + } + else if (fmt[i] == 'c') + { + char character = (char)va_arg(args, int64_t); + put_char(character); + } + else if (fmt[i] == 'd') + { + int64_t val = va_arg(args, int64_t); + char buf[21]; + itoa64(val, buf); + for (size_t j = 0; buf[j] != '\0'; j++) + { + put_char(buf[j]); + } + } + else if (fmt[i] == 'u') + { + uint64_t val = va_arg(args, uint64_t); + char buf[21]; + uitoa64(val, buf); + for (size_t j = 0; buf[j] != '\0'; j++) + { + put_char(buf[j]); + } + } + else if (fmt[i] == 'x') + { + uint64_t val = va_arg(args, uint64_t); + char buf[17]; + uitoa64_hex(val, buf); + for (size_t j = 0; buf[j] != '\0'; j++) + { + put_char(buf[j]); + } + } + else + { + put_char(fmt[i]); + } + } + else if (fmt[i] == '%') + { + should_format = true; + } + else + { + put_char(fmt[i]); + } + } + + va_end(args); +} \ No newline at end of file diff --git a/src/stdlib/stdio.h b/src/stdlib/stdio.h new file mode 100644 index 0000000..7f8738c --- /dev/null +++ b/src/stdlib/stdio.h @@ -0,0 +1,3 @@ +#pragma once + +void printf(const char* fmt, ...); \ No newline at end of file diff --git a/src/string.c b/src/stdlib/string.c similarity index 100% rename from src/string.c rename to src/stdlib/string.c diff --git a/src/string.h b/src/stdlib/string.h similarity index 67% rename from src/string.h rename to src/stdlib/string.h index 4a395e8..68706e2 100644 --- a/src/string.h +++ b/src/stdlib/string.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include "stddef.h" +#include "stdint.h" int strcmp(const char* a, const char* b); void reverse(char* str, size_t length);