From f05e7c9e64057cc9c12037e2d48a8396ae95ea47 Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 3 Sep 2025 18:31:10 +0200 Subject: [PATCH] ... --- .clangd | 6 ++- makefile | 2 +- src/arch/api.h | 21 --------- src/arch/arch.h | 30 +++++++++++++ src/arch/x86_64/arch.c | 45 +++++++++++++++++++ src/arch/x86_64/boot/boot.asm | 4 +- .../x86_64/{vga/vga.c => console/console.c} | 11 +++-- .../x86_64/{vga/vga.h => console/console.h} | 6 +-- src/arch/x86_64/entry.c | 44 ------------------ src/arch/x86_64/interrupts/exceptions.c | 4 +- src/arch/x86_64/interrupts/irq.h | 1 - src/arch/x86_64/interrupts/isr.c | 1 - src/arch/x86_64/interrupts/isr.h | 3 +- src/arch/x86_64/memory/mmap.c | 6 +-- src/arch/x86_64/memory/mmap.h | 4 +- src/arch/x86_64/util.h | 2 +- src/kernel/kernel.c | 5 +-- src/kernel/kernel.h | 2 +- src/kernel/pmm.c | 15 +++---- src/kernel/pmm.h | 4 +- src/std.h | 6 +++ src/stdlib/{stdint.h => def.h} | 24 ++++++++++ src/stdlib/{stdio.c => io.c} | 23 ++++------ src/stdlib/{stdio.h => io.h} | 0 src/stdlib/mem.c | 9 ++++ src/stdlib/mem.h | 5 +++ src/stdlib/stdarg.h | 8 ---- src/stdlib/stdbool.h | 7 --- src/stdlib/stddef.h | 12 ----- src/stdlib/string.c | 12 +---- src/stdlib/string.h | 5 +-- 31 files changed, 164 insertions(+), 163 deletions(-) delete mode 100644 src/arch/api.h create mode 100644 src/arch/arch.h create mode 100644 src/arch/x86_64/arch.c rename src/arch/x86_64/{vga/vga.c => console/console.c} (93%) rename src/arch/x86_64/{vga/vga.h => console/console.h} (82%) delete mode 100644 src/arch/x86_64/entry.c create mode 100644 src/std.h rename src/stdlib/{stdint.h => def.h} (65%) rename src/stdlib/{stdio.c => io.c} (80%) rename src/stdlib/{stdio.h => io.h} (100%) create mode 100644 src/stdlib/mem.c create mode 100644 src/stdlib/mem.h delete mode 100644 src/stdlib/stdarg.h delete mode 100644 src/stdlib/stdbool.h delete mode 100644 src/stdlib/stddef.h diff --git a/.clangd b/.clangd index 7427527..37513fd 100644 --- a/.clangd +++ b/.clangd @@ -12,4 +12,8 @@ CompileFlags: - "-nostdinc" - "-nostdlib" - "-I" - - "/home/oliste/repos/nub-os/src/stdlib" + - "/home/oliste/repos/nub-os/src" + - "-I" + - "/home/oliste/repos/nub-os/src/kernel" + - "-I" + - "/home/oliste/repos/nub-os/src/arch" diff --git a/makefile b/makefile index ba15961..e314399 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ CC = x86_64-elf-gcc LD = x86_64-elf-ld AS = nasm -CFLAGS = -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c11 -I src/stdlib -g +CFLAGS = -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c11 -I src -I src/kernel -I src/arch -g LDFLAGS = -g ASFLAGS = -f elf64 -g -F dwarf diff --git a/src/arch/api.h b/src/arch/api.h deleted file mode 100644 index 316fe35..0000000 --- a/src/arch/api.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -typedef struct -{ - uint64_t base_address; - size_t length; -} memory_region_t; - -typedef struct -{ - memory_region_t* regions; - size_t num_regions; -} memory_map_t; - -extern memory_map_t memory_map; - -void panic(); -void put_char(char character); \ No newline at end of file diff --git a/src/arch/arch.h b/src/arch/arch.h new file mode 100644 index 0000000..c338dc0 --- /dev/null +++ b/src/arch/arch.h @@ -0,0 +1,30 @@ +#pragma once + +#include "std.h" + +typedef struct +{ + uint64_t base_address; + size_t length; +} memory_region_t; + +typedef struct +{ + memory_region_t* regions; + size_t num_regions; +} memory_map_t; + +extern memory_map_t memory_map; + +void arch_panic(const char* msg); +void arch_putchar(char c); + +uintptr_t arch_kernel_base(); +uintptr_t arch_page_size(); + +void arch_interrupts_enable(); +void arch_interrupts_disable(); + +void arch_register_interrupt_handler(int vector, void (*handler)(void)); + +void arch_halt(); \ No newline at end of file diff --git a/src/arch/x86_64/arch.c b/src/arch/x86_64/arch.c new file mode 100644 index 0000000..7e9a75c --- /dev/null +++ b/src/arch/x86_64/arch.c @@ -0,0 +1,45 @@ +#include "arch.h" +#include "console/console.h" +#include "interrupts/idt.h" +#include "interrupts/irq.h" +#include "kernel.h" +#include "memory/mmap.h" +#include "multiboot.h" + +void x86_64_main(uint32_t magic, multiboot_info_t* info) +{ + console_clear(); + + if (magic != 0x2BADB002) + { + arch_panic("Multiboot magic does not match\n"); + } + + if (info == NULL) + { + arch_panic("Multiboot info is NULL\n"); + } + + idt_init(); + remap_pic(); + map_memory(info); + enable_interrupts(); + kernel_main(); +} + +void arch_panic(const char* msg); + +void arch_putchar(char c) +{ + console_put_char(c, VGA_DEFAULT_COLOR); +} + +uintptr_t arch_kernel_base(); +uintptr_t arch_page_size(); + +void arch_interrupts_enable(); +void arch_interrupts_disable(); + +void arch_register_interrupt_handler(int vector, void (*handler)(void)); + +void arch_halt(); \ No newline at end of file diff --git a/src/arch/x86_64/boot/boot.asm b/src/arch/x86_64/boot/boot.asm index ad67d1d..e053b9d 100644 --- a/src/arch/x86_64/boot/boot.asm +++ b/src/arch/x86_64/boot/boot.asm @@ -1,6 +1,6 @@ global _start global pml4 -extern entry +extern x86_64_main %define FLAGS 0b10 %define MAGIC 0x1BADB002 @@ -150,7 +150,7 @@ section .text ; Finally, we call in to c mov edi, [multiboot_magic] mov esi, [multiboot_info] - call entry + call x86_64_main .hang: hlt jmp .hang \ No newline at end of file diff --git a/src/arch/x86_64/vga/vga.c b/src/arch/x86_64/console/console.c similarity index 93% rename from src/arch/x86_64/vga/vga.c rename to src/arch/x86_64/console/console.c index 580276c..39b0eb9 100644 --- a/src/arch/x86_64/vga/vga.c +++ b/src/arch/x86_64/console/console.c @@ -1,5 +1,4 @@ -#include "vga.h" -#include +#include "console.h" #define ROWS 25 #define COLUMNS 80 @@ -14,9 +13,9 @@ static vga_char_t* vga_buffer = (vga_char_t*)0xb8000; static uint8_t cursor_row = 0; static uint8_t cursor_col = 0; -void vga_put_char(char character, uint8_t color) +void console_put_char(char c, uint8_t color) { - switch (character) + switch (c) { case '\n': { @@ -66,7 +65,7 @@ void vga_put_char(char character, uint8_t color) default: { vga_buffer[COLUMNS * cursor_row + cursor_col] = (vga_char_t){ - .character = character, + .character = c, .color = color, }; cursor_col += 1; @@ -102,7 +101,7 @@ void vga_put_char(char character, uint8_t color) } } -void vga_clear() +void console_clear() { for (size_t row = 0; row < ROWS; row++) { diff --git a/src/arch/x86_64/vga/vga.h b/src/arch/x86_64/console/console.h similarity index 82% rename from src/arch/x86_64/vga/vga.h rename to src/arch/x86_64/console/console.h index da55117..0e72d9a 100644 --- a/src/arch/x86_64/vga/vga.h +++ b/src/arch/x86_64/console/console.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "std.h" #define VGA_BLACK 0 #define VGA_BLUE 1 @@ -21,5 +21,5 @@ #define VGA_DEFAULT_COLOR VGA_LIGHT_GRAY | VGA_BLACK << 4 -void vga_put_char(char character, uint8_t color); -void vga_clear(); \ No newline at end of file +void console_put_char(char character, uint8_t color); +void console_clear(); \ No newline at end of file diff --git a/src/arch/x86_64/entry.c b/src/arch/x86_64/entry.c deleted file mode 100644 index ed8da34..0000000 --- a/src/arch/x86_64/entry.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "../../kernel/kernel.h" -#include "../api.h" -#include "interrupts/idt.h" -#include "interrupts/irq.h" -#include "memory/mmap.h" -#include "multiboot.h" -#include "util.h" -#include "vga/vga.h" -#include -#include - -void entry(uint32_t magic, multiboot_info_t* info) -{ - if (magic != 0x2BADB002) - { - printf("Multiboot magic does not match\n"); - panic(); - } - - if (info == NULL) - { - printf("Multiboot info is NULL\n"); - panic(); - } - - vga_clear(); - idt_init(); - remap_pic(); - map_memory(info); - enable_interrupts(); - main(); -} - -void panic() -{ - printf("Kernel panic!\n"); - 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/arch/x86_64/interrupts/exceptions.c b/src/arch/x86_64/interrupts/exceptions.c index fee04d0..4493d59 100644 --- a/src/arch/x86_64/interrupts/exceptions.c +++ b/src/arch/x86_64/interrupts/exceptions.c @@ -1,5 +1,5 @@ #include "exceptions.h" -#include "../../api.h" +#include "arch.h" static const char* exception_messages[32] = { "divide by zero", @@ -39,5 +39,5 @@ static const char* exception_messages[32] = { 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(); + arch_panic("An unhandled exception occurred"); } \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/irq.h b/src/arch/x86_64/interrupts/irq.h index 2db3211..fe7e3cf 100644 --- a/src/arch/x86_64/interrupts/irq.h +++ b/src/arch/x86_64/interrupts/irq.h @@ -1,7 +1,6 @@ #pragma once #include "isr.h" -#include typedef void (*irq_handler_t)(const isr_frame_t*); diff --git a/src/arch/x86_64/interrupts/isr.c b/src/arch/x86_64/interrupts/isr.c index 08341e0..b2cf8b5 100644 --- a/src/arch/x86_64/interrupts/isr.c +++ b/src/arch/x86_64/interrupts/isr.c @@ -1,7 +1,6 @@ #include "isr.h" #include "exceptions.h" #include "irq.h" -#include void handle_isr(const isr_frame_t* frame) { diff --git a/src/arch/x86_64/interrupts/isr.h b/src/arch/x86_64/interrupts/isr.h index cd23032..065b7d3 100644 --- a/src/arch/x86_64/interrupts/isr.h +++ b/src/arch/x86_64/interrupts/isr.h @@ -1,7 +1,6 @@ #pragma once -#include -#include +#include "std.h" typedef struct { diff --git a/src/arch/x86_64/memory/mmap.c b/src/arch/x86_64/memory/mmap.c index 2ed8567..4907179 100644 --- a/src/arch/x86_64/memory/mmap.c +++ b/src/arch/x86_64/memory/mmap.c @@ -1,7 +1,4 @@ #include "mmap.h" -#include "../../api.h" -#include -#include #define USABLE_REGION_SIZE 32 @@ -13,8 +10,7 @@ void map_memory(multiboot_info_t* info) { if (!(info->flags & (1 << 6))) { - printf("Invalid memory map given by bootloader\n"); - panic(); + arch_panic("Invalid memory map given by bootloader\n"); } size_t num_regions = 0; diff --git a/src/arch/x86_64/memory/mmap.h b/src/arch/x86_64/memory/mmap.h index c5bf237..18412ad 100644 --- a/src/arch/x86_64/memory/mmap.h +++ b/src/arch/x86_64/memory/mmap.h @@ -1,6 +1,6 @@ #pragma once -#include "../../api.h" -#include "../multiboot.h" +#include "arch.h" +#include "x86_64/multiboot.h" void map_memory(multiboot_info_t* mbd); diff --git a/src/arch/x86_64/util.h b/src/arch/x86_64/util.h index a843e64..858954e 100644 --- a/src/arch/x86_64/util.h +++ b/src/arch/x86_64/util.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "std.h" enum { diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 3400007..21e158a 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,12 +1,11 @@ #include "kernel.h" #include "pmm.h" -#include -void main() +void kernel_main() { pmm_init(); uint64_t page = pmm_alloc_page(); printf("page: %u\n", page); printf("Welcome to nub OS :)\n"); -} +} \ No newline at end of file diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index f7a8c31..669d6ae 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,3 +1,3 @@ #pragma once -void main(); \ No newline at end of file +void kernel_main(); \ No newline at end of file diff --git a/src/kernel/pmm.c b/src/kernel/pmm.c index 04ac7d5..4cb2aed 100644 --- a/src/kernel/pmm.c +++ b/src/kernel/pmm.c @@ -1,8 +1,5 @@ #include "pmm.h" -#include "../arch/api.h" -#include -#include -#include +#include "arch.h" #define BITMAP_SIZE 32768 // Supports up to 1GB of RAM #define USABLE_REGION_SIZE 32 @@ -19,8 +16,8 @@ void pmm_init() { 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; + uint64_t start_page = region.base_address / arch_page_size(); + uint64_t num_pages = region.length / arch_page_size(); for (uint64_t page = start_page; page < start_page + num_pages; page++) { @@ -39,7 +36,7 @@ void pmm_init() } // Reserve first 64MB which is reserved by boot code - for (uint64_t page = 0; page < (64 * 1024 * 1024) / PAGE_SIZE; page++) + for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_page_size(); page++) { if (page < BITMAP_SIZE * 8) { @@ -65,7 +62,7 @@ uint64_t pmm_alloc_page() { page_bitmap[i] |= (1 << bit); free_pages--; - return ((i * 8 + bit) * PAGE_SIZE); + return ((i * 8 + bit) * arch_page_size()); } } } @@ -77,7 +74,7 @@ uint64_t pmm_alloc_page() // Frees the physical page at the specified address void pmm_free_page(uint64_t addr) { - uint64_t page = addr / PAGE_SIZE; + uint64_t page = addr / arch_page_size(); if (page < BITMAP_SIZE * 8) { if (page_bitmap[page / 8] & (1 << (page % 8))) diff --git a/src/kernel/pmm.h b/src/kernel/pmm.h index b04100f..701f371 100644 --- a/src/kernel/pmm.h +++ b/src/kernel/pmm.h @@ -1,8 +1,6 @@ #pragma once -#include - -#define PAGE_SIZE 4096 +#include "std.h" void pmm_init(); uint64_t pmm_alloc_page(); diff --git a/src/std.h b/src/std.h new file mode 100644 index 0000000..c412ae9 --- /dev/null +++ b/src/std.h @@ -0,0 +1,6 @@ +#pragma once + +#include "stdlib/def.h" +#include "stdlib/io.h" +#include "stdlib/mem.h" +#include "stdlib/string.h" \ No newline at end of file diff --git a/src/stdlib/stdint.h b/src/stdlib/def.h similarity index 65% rename from src/stdlib/stdint.h rename to src/stdlib/def.h index 96ad566..9c4a566 100644 --- a/src/stdlib/stdint.h +++ b/src/stdlib/def.h @@ -1,5 +1,29 @@ #pragma once +typedef __builtin_va_list va_list; + +#define va_start(ap, last) __builtin_va_start(ap, last) +#define va_arg(ap, type) __builtin_va_arg(ap, type) +#define va_end(ap) __builtin_va_end(ap) +#define va_copy(dest, src) __builtin_va_copy(dest, src) + +#define bool _Bool +#define true 1 +#define false 0 + +#define __bool_true_false_are_defined 1 + +#ifndef NULL +#define NULL ((void*)0) +#endif + +typedef unsigned long size_t; +typedef long ptrdiff_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; + +#define offsetof(type, member) __builtin_offsetof(type, member) + typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; diff --git a/src/stdlib/stdio.c b/src/stdlib/io.c similarity index 80% rename from src/stdlib/stdio.c rename to src/stdlib/io.c index d3d920e..37f2c1a 100644 --- a/src/stdlib/stdio.c +++ b/src/stdlib/io.c @@ -1,9 +1,4 @@ -#include "../arch/api.h" -#include -#include -#include -#include -#include +#include "arch.h" void printf(const char* fmt, ...) { @@ -20,20 +15,20 @@ void printf(const char* fmt, ...) if (fmt[i] == '%') { - put_char('%'); + arch_putchar('%'); } 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]); + arch_putchar(str[j]); } } else if (fmt[i] == 'c') { char character = (char)va_arg(args, int64_t); - put_char(character); + arch_putchar(character); } else if (fmt[i] == 'd') { @@ -42,7 +37,7 @@ void printf(const char* fmt, ...) itoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - put_char(buf[j]); + arch_putchar(buf[j]); } } else if (fmt[i] == 'u') @@ -52,7 +47,7 @@ void printf(const char* fmt, ...) uitoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - put_char(buf[j]); + arch_putchar(buf[j]); } } else if (fmt[i] == 'x') @@ -62,12 +57,12 @@ void printf(const char* fmt, ...) uitoa64_hex(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - put_char(buf[j]); + arch_putchar(buf[j]); } } else { - put_char(fmt[i]); + arch_putchar(fmt[i]); } } else if (fmt[i] == '%') @@ -76,7 +71,7 @@ void printf(const char* fmt, ...) } else { - put_char(fmt[i]); + arch_putchar(fmt[i]); } } diff --git a/src/stdlib/stdio.h b/src/stdlib/io.h similarity index 100% rename from src/stdlib/stdio.h rename to src/stdlib/io.h diff --git a/src/stdlib/mem.c b/src/stdlib/mem.c new file mode 100644 index 0000000..b8b9293 --- /dev/null +++ b/src/stdlib/mem.c @@ -0,0 +1,9 @@ +#include "mem.h" + +void memset(void* destination, uint8_t value, size_t length) +{ + for (size_t i = 0; i < length; i++) + { + ((uint8_t*)destination)[i] = value; + } +} \ No newline at end of file diff --git a/src/stdlib/mem.h b/src/stdlib/mem.h new file mode 100644 index 0000000..b3cfbf3 --- /dev/null +++ b/src/stdlib/mem.h @@ -0,0 +1,5 @@ +#pragma once + +#include "std.h" + +void memset(void* destination, uint8_t value, size_t length); \ No newline at end of file diff --git a/src/stdlib/stdarg.h b/src/stdlib/stdarg.h deleted file mode 100644 index 536ccb1..0000000 --- a/src/stdlib/stdarg.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -typedef __builtin_va_list va_list; - -#define va_start(ap, last) __builtin_va_start(ap, last) -#define va_arg(ap, type) __builtin_va_arg(ap, type) -#define va_end(ap) __builtin_va_end(ap) -#define va_copy(dest, src) __builtin_va_copy(dest, src) diff --git a/src/stdlib/stdbool.h b/src/stdlib/stdbool.h deleted file mode 100644 index 20c1842..0000000 --- a/src/stdlib/stdbool.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#define bool _Bool -#define true 1 -#define false 0 - -#define __bool_true_false_are_defined 1 diff --git a/src/stdlib/stddef.h b/src/stdlib/stddef.h deleted file mode 100644 index 2b35097..0000000 --- a/src/stdlib/stddef.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#ifndef NULL -#define NULL ((void*)0) -#endif - -typedef unsigned long size_t; -typedef long ptrdiff_t; -typedef long intptr_t; -typedef unsigned long uintptr_t; - -#define offsetof(type, member) __builtin_offsetof(type, member) diff --git a/src/stdlib/string.c b/src/stdlib/string.c index dfba224..1cc1924 100644 --- a/src/stdlib/string.c +++ b/src/stdlib/string.c @@ -1,14 +1,6 @@ -#include +#include "string.h" -void memset(void* destination, uint8_t value, size_t length) -{ - for (size_t i = 0; i < length; i++) - { - ((uint8_t*)destination)[i] = value; - } -} - -int strcmp(const char* a, const char* b) +int kstrcmp(const char* a, const char* b) { while ((*a != '\0' && *b != '\0') && *a == *b) { diff --git a/src/stdlib/string.h b/src/stdlib/string.h index 3e50283..0e0ab54 100644 --- a/src/stdlib/string.h +++ b/src/stdlib/string.h @@ -1,11 +1,8 @@ #pragma once -#include -#include +#include "std.h" -void memset(void* destination, uint8_t value, size_t length); int strcmp(const char* a, const char* b); -void reverse(char* str, size_t length); void uitoa64(uint64_t value, char* buffer); void itoa64(int64_t value, char* buffer); void uitoa64_hex(uint64_t value, char* buffer); \ No newline at end of file