From cd31762fb0dce5acd7005d34bc5f93d5c9c9722c Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 30 Dec 2025 02:54:54 +0100 Subject: [PATCH] ... --- src/boot/boot.asm | 85 ++++++++++++++++++++++++++++++++++++++++++++--- src/boot/mem.c | 60 +++++++++++++++++++++++++++++++++ src/boot/start.c | 68 +------------------------------------ 3 files changed, 141 insertions(+), 72 deletions(-) create mode 100644 src/boot/mem.c diff --git a/src/boot/boot.asm b/src/boot/boot.asm index fb08473..c56443b 100644 --- a/src/boot/boot.asm +++ b/src/boot/boot.asm @@ -1,5 +1,4 @@ global _start -extern c_start %define MAGIC 0xe85250d6 %define ARCH 0x0 @@ -19,6 +18,10 @@ header: dd 8 .end: +section .data +align 8 +multiboot_info: dd 0 + section .bss align 4096 stack: @@ -26,13 +29,85 @@ stack: resb 1024 * 16 .top: +align 4096 +pml4t: resb 4096 +pdpt: resb 4096 +pdt: resb 4096 +pt: resb 4096 + section .text _start: mov esp, stack.top - push ebx - push eax - call c_start - add esp, 8 + + %define BOOTLOADER_MAGIC 0x36d76289 + + ; Make sure we booted with multiboot 2 + cmp eax, BOOTLOADER_MAGIC + jne .halt + + ; Save pointer to info gathered by multiboot + mov [multiboot_info], ebx + + ; Tell the cpu where the pages area + mov edi, pml4t + mov cr3, edi + + %define PT_PRESENT 1 + %define PT_READABLE 2 + + ; pml4t[0] -> pdpt + mov edi, pdpt + or edi, PT_PRESENT | PT_READABLE + mov [pml4t], edi + + ; pdpt[0] -> pdt + mov edi, pdt + or edi, PT_PRESENT | PT_READABLE + mov [pdpt], edi + + ; pdt[0] -> pt + mov edi, pt + or edi, PT_PRESENT | PT_READABLE + mov [pdt], edi + + %define ENTRIES_PER_PT 512 + %define SIZEOF_PT_ENTRY 8 + %define PAGE_SIZE 0x1000 + %define START_ADDRESS 0x0 + + ; Identity map first 2mb of memory + mov edi, pt + mov ebx, START_ADDRESS | PT_PRESENT | PT_READABLE + mov ecx, ENTRIES_PER_PT + +.set_pt_entry: + mov [edi], ebx + add ebx, PAGE_SIZE + add edi, SIZEOF_PT_ENTRY + loop .set_pt_entry + + %define CR4_PAE_ENABLE 1 << 5 + + ; Enable pae + mov eax, cr4 + or eax, CR4_PAE_ENABLE + mov cr4, eax + + %define EFER_MSR 0xc0000080 + %define EFER_LM_ENABLE 1 << 8 + + ; Switch to compatibility mode + mov ecx, EFER_MSR + rdmsr + or eax, EFER_LM_ENABLE + wrmsr + + %define CR0_PG_ENABLE 1 << 31 + + ; Enable paging + mov eax, cr0 + or eax, CR0_PG_ENABLE + mov cr0, eax .halt: cli hlt diff --git a/src/boot/mem.c b/src/boot/mem.c new file mode 100644 index 0000000..c689238 --- /dev/null +++ b/src/boot/mem.c @@ -0,0 +1,60 @@ +#include +#include "console.h" +#include "multiboot2.h" +#include "panic.h" +#include "util.h" + +static void *multiboot_find_tag(uptr multiboot_info, u32 type) { + uptr next = multiboot_info + 8; + + while (true) { + multiboot_tag *tag = (multiboot_tag*)next; + + if (tag->type == MULTIBOOT_TAG_TYPE_END) { + return NULL; + } + + if (tag->type == type) { + return tag; + } + + next = align(next + tag->size, MULTIBOOT_TAG_ALIGN); + } +} + +#define MAX_REGIONS 64 + +typedef struct { + u64 base_address; + u64 length; +} region; + +extern uptr kernel_start; +extern uptr kernel_end; + +static region regions[MAX_REGIONS] = {0}; +static size_t region_count = 0; + +static void find_memory_regions(uptr multiboot_info) { + multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP); + if (tag == NULL) { + boot_panic("Multiboot did not provide mmap tag"); + } + + u32 entry_count = (tag->size - 16) / tag->entry_size; + u8 *entry_ptr = (u8*)tag->entries; + + for (u32 i = 0; i < entry_count; ++i) { + multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr; + + if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) { + if (region_count >= MAX_REGIONS) { + boot_panic("Too many memory regions"); + } + + regions[region_count++] = (region){ entry->base_address, entry->length }; + } + + entry_ptr += tag->entry_size; + } +} \ No newline at end of file diff --git a/src/boot/start.c b/src/boot/start.c index cb280db..51e0cc8 100644 --- a/src/boot/start.c +++ b/src/boot/start.c @@ -2,73 +2,7 @@ #include "console.h" #include "multiboot2.h" #include "panic.h" -#include "util.h" -static void *multiboot_find_tag(uptr multiboot_info, u32 type) { - uptr next = multiboot_info + 8; - - while (true) { - multiboot_tag *tag = (multiboot_tag*)next; - - if (tag->type == MULTIBOOT_TAG_TYPE_END) { - return NULL; - } - - if (tag->type == type) { - return tag; - } - - next = align(next + tag->size, MULTIBOOT_TAG_ALIGN); - } -} - -#define MAX_REGIONS 64 - -typedef struct { - u64 base_address; - u64 length; -} region; - -extern uptr kernel_start; -extern uptr kernel_end; - -static region regions[MAX_REGIONS] = {0}; -static size_t region_count = 0; - -static void find_memory_regions(uptr multiboot_info) { - multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP); - if (tag == NULL) { - boot_panic("Multiboot did not provide mmap tag"); - } - - u32 entry_count = (tag->size - 16) / tag->entry_size; - u8 *entry_ptr = (u8*)tag->entries; - - for (u32 i = 0; i < entry_count; ++i) { - multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr; - - if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) { - if (region_count >= MAX_REGIONS) { - boot_panic("Too many memory regions"); - } - - regions[region_count++] = (region){ entry->base_address, entry->length }; - } - - entry_ptr += tag->entry_size; - } -} - -void c_start(u32 magic, uptr multiboot_info) { +void c_start() { console_clear(); - - if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { - boot_panic("Expected bootloader magic 0x%x, got 0x%x", MULTIBOOT_BOOTLOADER_MAGIC, magic); - } - - find_memory_regions(multiboot_info); - - for (size_t i = 0; i < region_count; i++) { - kprintf("Memory region %d: base=0x%X, length=0x%X\n", i, regions[i].base_address, regions[i].length); - } } \ No newline at end of file