diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 3179c58..1a103e8 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,14 +2,12 @@ "version": 4, "configurations": [ { - "name": "test", + "name": "kernel", "defines": [ "DEBUG" ], "includePath": [ - "src/kernel", - "src/arch", - "src" + "src/lib" ], "intelliSenseMode": "linux-gcc-x64", "compilerPath": "/usr/bin/x86_64-elf-gcc", diff --git a/.vscode/settings.json b/.vscode/settings.json index 6c288d2..15356ac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -31,6 +31,10 @@ "assert.h": "c", "io.h": "c", "mem.h": "c", - "string.h": "c" + "string.h": "c", + "kernel.h": "c", + "printf.h": "c", + "vmm.h": "c", + "console.h": "c" } } \ No newline at end of file diff --git a/makefile b/makefile index eb3ee2d..000c568 100644 --- a/makefile +++ b/makefile @@ -8,7 +8,7 @@ LDFLAGS = -g ASFLAGS = -g -F dwarf # Do not modify -CFLAGS += -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c23 -I src -I src/kernel -I src/arch +CFLAGS += -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c23 -I src/lib LDFLAGS += ASFLAGS += -f elf64 diff --git a/src/arch/x86_64/arch.c b/src/arch/x86_64/arch.c index 64fa22b..df88735 100644 --- a/src/arch/x86_64/arch.c +++ b/src/arch/x86_64/arch.c @@ -1,9 +1,11 @@ -#include "arch.h" #include "console.h" #include "mem/pmm.h" #include "mem/vmm.h" #include "panic.h" #include "util.h" +#include +#include +#include static void arch_halt() { @@ -20,9 +22,9 @@ static void arch_enable_interrupts() enable_interrupts(); } -static void arch_panic(const char* msg) +static void arch_panic() { - panic(msg); + panic(); } static void arch_console_putchar(char c) @@ -49,7 +51,8 @@ void* arch_alloc(size_t page_count) u64 physical_address = pmm_alloc(); if (!physical_address) { - panic("Out of physical memory"); + printf("Out of physical memory"); + panic(); } vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE); diff --git a/src/arch/x86_64/console.h b/src/arch/x86_64/console.h index 0eeeba4..2c547c2 100644 --- a/src/arch/x86_64/console.h +++ b/src/arch/x86_64/console.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include #define VGA_BLACK 0 #define VGA_BLUE 1 diff --git a/src/arch/x86_64/interrupts/exceptions.c b/src/arch/x86_64/interrupts/exceptions.c index bf2fee6..4ae69bd 100644 --- a/src/arch/x86_64/interrupts/exceptions.c +++ b/src/arch/x86_64/interrupts/exceptions.c @@ -1,5 +1,6 @@ #include "exceptions.h" #include "../panic.h" +#include static const char* exception_messages[32] = { "divide by zero", @@ -39,5 +40,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("An unhandled exception occurred"); + panic(); } \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/irq.c b/src/arch/x86_64/interrupts/irq.c index 02a50c2..ec89026 100644 --- a/src/arch/x86_64/interrupts/irq.c +++ b/src/arch/x86_64/interrupts/irq.c @@ -1,5 +1,6 @@ #include "irq.h" #include "../util.h" +#include #define PIC1_COMMAND 0x20 #define PIC1_DATA 0x21 diff --git a/src/arch/x86_64/interrupts/isr.c b/src/arch/x86_64/interrupts/isr.c index b2cf8b5..3892324 100644 --- a/src/arch/x86_64/interrupts/isr.c +++ b/src/arch/x86_64/interrupts/isr.c @@ -1,6 +1,8 @@ #include "isr.h" #include "exceptions.h" #include "irq.h" +#include +#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 e075bbd..05f4556 100644 --- a/src/arch/x86_64/interrupts/isr.h +++ b/src/arch/x86_64/interrupts/isr.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include typedef struct { diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 70a24b8..ce54848 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -1,11 +1,13 @@ #include "console.h" #include "interrupts/idt.h" #include "interrupts/irq.h" -#include "kernel.h" #include "mem/pmm.h" #include "mem/vmm.h" #include "panic.h" #include "util.h" +#include + +extern void kernel_main(); void x86_64_main(u32 magic, multiboot_info_t* info, u32 kernel_page_count) { @@ -13,12 +15,14 @@ void x86_64_main(u32 magic, multiboot_info_t* info, u32 kernel_page_count) if (magic != 0x2BADB002) { - panic("Multiboot magic does not match\n"); + printf("Multiboot magic does not match\n"); + panic(); } if (info == NULL) { - panic("Multiboot info is NULL\n"); + printf("Multiboot info is NULL\n"); + panic(); } idt_init(); diff --git a/src/arch/x86_64/mem/pmm.c b/src/arch/x86_64/mem/pmm.c index 20ab85a..69e562c 100644 --- a/src/arch/x86_64/mem/pmm.c +++ b/src/arch/x86_64/mem/pmm.c @@ -1,5 +1,7 @@ #include "pmm.h" -#include "x86_64/panic.h" +#include "../panic.h" +#include +#include typedef struct { @@ -27,7 +29,8 @@ void pmm_init(u32 kernel_page_count, multiboot_info_t* info) { if (!(info->flags & (1 << 6))) { - panic("Invalid memory map given by bootloader\n"); + printf("Invalid memory map given by bootloader\n"); + panic(); } u64 offset = 0; @@ -84,7 +87,8 @@ void pmm_init(u32 kernel_page_count, multiboot_info_t* info) { if (page >= BITMAP_PAGE_COUNT) { - panic("Bitmap is not large enough to hold the memory reserved by the kernel"); + printf("Bitmap is not large enough to hold the memory reserved by the kernel"); + panic(); } page_bitmap[page / 8] |= (1 << (page % 8)); @@ -123,7 +127,7 @@ void pmm_free(u64 physical_address) else { printf("Physical address %x is already free", physical_address); - panic("Failed to free physical address"); + panic(); } } } \ No newline at end of file diff --git a/src/arch/x86_64/mem/pmm.h b/src/arch/x86_64/mem/pmm.h index b9e3d61..d0f75d7 100644 --- a/src/arch/x86_64/mem/pmm.h +++ b/src/arch/x86_64/mem/pmm.h @@ -1,7 +1,7 @@ #pragma once -#include "std.h" -#include "x86_64/multiboot.h" +#include "../multiboot.h" +#include // todo(nub31): Fixed at 2mb for now, might add support for 4k pages later #define PAGE_SIZE MiB(2) diff --git a/src/arch/x86_64/mem/vmm.c b/src/arch/x86_64/mem/vmm.c index 4a43e6f..9c4d8cb 100644 --- a/src/arch/x86_64/mem/vmm.c +++ b/src/arch/x86_64/mem/vmm.c @@ -1,6 +1,7 @@ #include "vmm.h" +#include "../panic.h" #include "pmm.h" -#include "x86_64/panic.h" +#include #define PML4_INDEX(addr) (((addr) >> 39) & 0x1FF) #define PDPT_INDEX(addr) (((addr) >> 30) & 0x1FF) @@ -23,7 +24,8 @@ void vmm_init(u32 kernel_page_count) { if (page >= BITMAP_PAGE_COUNT) { - panic("Bitmap is not large enough to hold the addresses reserved by the kernel"); + printf("Bitmap is not large enough to hold the addresses reserved by the kernel"); + panic(); } page_bitmap[page / 8] |= (1 << (page % 8)); @@ -75,7 +77,7 @@ void vmm_free_address(u64 virtual_address, size_t page_count) if (start_page + page_count > BITMAP_PAGE_COUNT) { printf("Virtual address range exceeds bitmap bounds\n"); - panic("Failed to free virtual address"); + panic(); } for (size_t i = 0; i < page_count; i++) @@ -87,7 +89,7 @@ void vmm_free_address(u64 virtual_address, size_t page_count) if (!(page_bitmap[byte_index] & (1 << bit_index))) { printf("Virtual address 0x%x (page %u) is already free\n", virtual_address + (i * PAGE_SIZE), page); - panic("Failed to free virtual address"); + panic(); } } @@ -105,7 +107,7 @@ static u64 create_2mb_pte(u64 physical_address, u32 flags) if (physical_address & (PAGE_SIZE - 1)) { printf("Physical address not page aligned (0x%x)\n", physical_address); - panic("Failed to create PTE"); + panic(); } return (physical_address & PTE_MASK) | flags | PTE_PS; @@ -122,7 +124,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags) { // todo(nub31): Dynamically create a pdpt table printf("PDPT not present at PML4 index %u\n", pml4_idx); - panic("Failed to map virtual to physical page"); + panic(); } u64* pdpt_physical_address = (u64*)(pdpt & PTE_MASK); @@ -131,7 +133,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags) { // todo(nub31): Dynamically create a pd table printf("PD not present at PDPT index %u\n", pdpt_idx); - panic("Failed to map virtual to physical page"); + panic(); } u64* pd_physical_address = (u64*)(pd & PTE_MASK); @@ -140,7 +142,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags) if (entry & PTE_PRESENT) { printf("Virtual address 0x%x is already mapped\n", virtual_address); - panic("Failed to map virtual to physical page"); + panic(); } pd_physical_address[pd_idx] = create_2mb_pte(physical_address, flags); @@ -156,7 +158,7 @@ u64 vmm_unmap(u64 virtual_address) if (!(pdpt_entry & PTE_PRESENT)) { printf("PDPT not present at PML4 index %llu\n", pml4_idx); - panic("Failed to unmap virtual address"); + panic(); } u64* pdpt_physical_address = (u64*)(pdpt_entry & PTE_MASK); @@ -164,14 +166,14 @@ u64 vmm_unmap(u64 virtual_address) if (!(pd_entry & PTE_PRESENT)) { printf("PD not present at PDPT index %llu\n", pdpt_idx); - panic("Failed to unmap virtual address"); + panic(); } u64* pd_physical_address = (u64*)(pd_entry & PTE_MASK); if (!(pd_physical_address[pd_idx] & PTE_PRESENT)) { printf("Virtual address 0x%llx is not mapped\n", virtual_address); - panic("Failed to unmap virtual address"); + panic(); } u64 physical_address = pd_physical_address[pd_idx] & PTE_MASK; diff --git a/src/arch/x86_64/mem/vmm.h b/src/arch/x86_64/mem/vmm.h index 9837f71..0fcf66d 100644 --- a/src/arch/x86_64/mem/vmm.h +++ b/src/arch/x86_64/mem/vmm.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include // Defines the theoretical max virtual memory space the kernel can allocate // The value must be a multible of 8 diff --git a/src/arch/x86_64/panic.c b/src/arch/x86_64/panic.c index 90dc949..5103b3c 100644 --- a/src/arch/x86_64/panic.c +++ b/src/arch/x86_64/panic.c @@ -1,9 +1,8 @@ #include "panic.h" #include "util.h" -void panic(const char* msg) +void panic() { - printf(msg); disable_interrupts(); halt(); } \ No newline at end of file diff --git a/src/arch/x86_64/panic.h b/src/arch/x86_64/panic.h index e9e18af..0999141 100644 --- a/src/arch/x86_64/panic.h +++ b/src/arch/x86_64/panic.h @@ -1,3 +1,3 @@ #pragma once -void panic(const char* msg); \ No newline at end of file +void panic(); \ No newline at end of file diff --git a/src/arch/x86_64/util.h b/src/arch/x86_64/util.h index 6eb0c0f..fbfe00a 100644 --- a/src/arch/x86_64/util.h +++ b/src/arch/x86_64/util.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include enum { diff --git a/src/kernel/alloc.c b/src/kernel/alloc.c index 3f3c7ee..f83c2c8 100644 --- a/src/kernel/alloc.c +++ b/src/kernel/alloc.c @@ -1,5 +1,4 @@ -#include "arch.h" -#include "assert.h" +#include typedef struct block_header { diff --git a/src/kernel/alloc.h b/src/kernel/alloc.h index 1b80385..0171ef2 100644 --- a/src/kernel/alloc.h +++ b/src/kernel/alloc.h @@ -1,6 +1,4 @@ #pragma once -#include "std.h" - void* malloc(size_t size); void free(void* ptr); \ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 6a98bbd..297b381 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,22 +1,11 @@ #include "kernel.h" -#include "alloc.h" -#include "arch.h" -#include "assert.h" -#include "std.h" +#include +#include void kernel_main() { - assert(false, "test"); - arch_api.enable_interrupts(); - u64* mem = malloc(1); - *mem = 23; - - printf("%d\n", *mem); - - free(mem); - printf("Welcome to nub OS :)\n"); printf("Kernel has exited\n"); arch_api.halt(); diff --git a/src/arch/arch.h b/src/lib/arch.h similarity index 91% rename from src/arch/arch.h rename to src/lib/arch.h index 20b1923..00a55c5 100644 --- a/src/arch/arch.h +++ b/src/lib/arch.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include typedef void (*arch_console_putchar_t)(char c); typedef void (*arch_console_clear_t)(); @@ -22,7 +22,7 @@ typedef struct const arch_mem_free_t free; } arch_mem_api_t; -typedef void (*arch_panic_t)(const char* msg); +typedef void (*arch_panic_t)(); typedef void (*arch_enable_interrupts_t)(); typedef void (*arch_disable_interrupts_t)(); typedef void (*arch_halt_t)(); diff --git a/src/kernel/assert.h b/src/lib/assert.h similarity index 52% rename from src/kernel/assert.h rename to src/lib/assert.h index 817d850..f6e3202 100644 --- a/src/kernel/assert.h +++ b/src/lib/assert.h @@ -1,13 +1,14 @@ #pragma once -#include "arch.h" +#include +// In arch code, make sure arch_api.panic is set up befire calling static inline void assert(bool condition, const char* msg) { #if DEBUG if (!condition) { - arch_api.panic(msg); + arch_api.panic(); } #endif } \ No newline at end of file diff --git a/src/stdlib/def.h b/src/lib/def.h similarity index 83% rename from src/stdlib/def.h rename to src/lib/def.h index b76c668..70a9920 100644 --- a/src/stdlib/def.h +++ b/src/lib/def.h @@ -37,14 +37,20 @@ typedef signed long long i64; #define INT16_MIN (-32768) #define INT16_MAX 32767 + +#define UINT16_MIN 0x0 #define UINT16_MAX 0xffff #define INT32_MIN (-2147483647 - 1) #define INT32_MAX 2147483647 + +#define UINT32_MIN 0x0 #define UINT32_MAX 0xffffffffU #define INT64_MIN (-9223372036854775807LL - 1) #define INT64_MAX 9223372036854775807LL + +#define UINT64_MIN 0x0 #define UINT64_MAX 0xffffffffffffffffULL #define INT8_C(x) x @@ -59,10 +65,7 @@ typedef signed long long i64; #define INT64_C(x) x##LL #define UINT64_C(x) x##ULL -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL - -#define KiB(count) ((u64)count * 1024) -#define MiB(count) (KiB((u64)count) * 1024) -#define GiB(count) (MiB((u64)count) * 1024) -#define TiB(count) (GiB((u64)count) * 1024) \ No newline at end of file +#define KiB(count) (count * UINT64_C(count)) +#define MiB(count) (KiB(count) * UINT64_C(count)) +#define GiB(count) (MiB(count) * UINT64_C(count)) +#define TiB(count) (GiB(count) * UINT64_C(count)) \ No newline at end of file diff --git a/src/stdlib/mem.c b/src/lib/mem.c similarity index 100% rename from src/stdlib/mem.c rename to src/lib/mem.c diff --git a/src/lib/mem.h b/src/lib/mem.h new file mode 100644 index 0000000..786e3f0 --- /dev/null +++ b/src/lib/mem.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +void memset(void* destination, u8 value, size_t length); +void memcpy(void* destination, void* source, size_t length); \ No newline at end of file diff --git a/src/stdlib/io.c b/src/lib/printf.c similarity index 96% rename from src/stdlib/io.c rename to src/lib/printf.c index f725acd..b385c7f 100644 --- a/src/stdlib/io.c +++ b/src/lib/printf.c @@ -1,4 +1,7 @@ -#include "arch.h" +#include "printf.h" +#include +#include +#include void printf(const char* fmt, ...) { diff --git a/src/lib/printf.h b/src/lib/printf.h new file mode 100644 index 0000000..12c973b --- /dev/null +++ b/src/lib/printf.h @@ -0,0 +1,4 @@ +#pragma once + +// In arch code, make sure arch_api.console.putchar is set up befire calling +void printf(const char* fmt, ...); \ No newline at end of file diff --git a/src/stdlib/string.c b/src/lib/string.c similarity index 100% rename from src/stdlib/string.c rename to src/lib/string.c diff --git a/src/stdlib/string.h b/src/lib/string.h similarity index 74% rename from src/stdlib/string.h rename to src/lib/string.h index 8bbf4a7..846d807 100644 --- a/src/stdlib/string.h +++ b/src/lib/string.h @@ -1,6 +1,6 @@ #pragma once -#include "std.h" +#include int strcmp(const char* a, const char* b); void reverse(char* str, size_t length); diff --git a/src/std.h b/src/std.h deleted file mode 100644 index c412ae9..0000000 --- a/src/std.h +++ /dev/null @@ -1,6 +0,0 @@ -#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/io.h b/src/stdlib/io.h deleted file mode 100644 index 7f8738c..0000000 --- a/src/stdlib/io.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void printf(const char* fmt, ...); \ No newline at end of file diff --git a/src/stdlib/mem.h b/src/stdlib/mem.h deleted file mode 100644 index 2e469d1..0000000 --- a/src/stdlib/mem.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "std.h" - -void memset(void* destination, u8 value, size_t length); -void memcpy(void* destination, void* source, size_t length); \ No newline at end of file