From d15609e5c008dcd76f6b02ecd8a3ba9f7566083a Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 30 Dec 2025 22:25:51 +0100 Subject: [PATCH] ... --- src/boot/main.c | 20 +++++++++++------- src/boot/start.asm | 51 ++++++++++++++++++++++++++++++++-------------- src/boot/util.h | 8 ++++++-- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/boot/main.c b/src/boot/main.c index 8949380..0cccffc 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -21,7 +21,7 @@ static void *multiboot_find_tag(uptr multiboot_info, u32 type) { return tag; } - next = align(next + tag->size, MULTIBOOT_TAG_ALIGN); + next = align_up(next + tag->size, MULTIBOOT_TAG_ALIGN); } } @@ -30,13 +30,13 @@ static void *multiboot_find_tag(uptr multiboot_info, u32 type) { typedef struct { u64 base_address; u64 length; -} region; +} memory_region; extern uptr kernel_start; extern uptr kernel_end; -static region regions[MAX_REGIONS] = {0}; -static size_t region_count = 0; +static memory_region memory_regions[MAX_REGIONS] = {0}; +static size_t memory_region_count = 0; static void find_memory_regions(uptr multiboot_info) { multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP); @@ -51,17 +51,23 @@ static void find_memory_regions(uptr multiboot_info) { multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr; if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) { - if (region_count >= MAX_REGIONS) { + if (memory_region_count >= MAX_REGIONS) { boot_panic("Too many memory regions"); } - regions[region_count++] = (region){ entry->base_address, entry->length }; + memory_regions[memory_region_count++] = (memory_region){ entry->base_address, entry->length }; } entry_ptr += tag->entry_size; } } -void kmain(uptr multiboot_info) { +// We are now in long mode with kernel pages and vga buffer identity mapped +void x86_64_main(uptr multiboot_info) { + console_clear(); find_memory_regions(multiboot_info); + + for (u32 i = 0; i < memory_region_count; ++i) { + kprintf("region: base_address=0x%X, length=0x%X\n", memory_regions[i].base_address, memory_regions[i].length); + } } \ No newline at end of file diff --git a/src/boot/start.asm b/src/boot/start.asm index fcddbf3..8a4d6a7 100644 --- a/src/boot/start.asm +++ b/src/boot/start.asm @@ -1,7 +1,7 @@ global _start extern kernel_start extern kernel_end -extern kmain +extern x86_64_main %define MAGIC 0xe85250d6 %define ARCH 0x0 @@ -21,10 +21,6 @@ header: dd 8 .end: -section .data -align 8 -multiboot_info: dq 0 - %define PRESENT 1 << 7 %define NOT_SYS 1 << 4 %define EXEC 1 << 3 @@ -58,6 +54,11 @@ gdt: dq gdt section .bss +%define MULTIBOOT_INFO_MAX_SIZE 1024 * 64 + +align 8 +multiboot_info: resb MULTIBOOT_INFO_MAX_SIZE + align 16 stack: .bottom: @@ -79,29 +80,38 @@ _start: cmp eax, BOOTLOADER_MAGIC jne .halt - ; Save pointer to info gathered by multiboot - mov [multiboot_info], ebx + ; Copy multiboot structure to kernel owned memory + mov esi, ebx + mov eax, [esi] + + cmp eax, MULTIBOOT_INFO_MAX_SIZE + ja .halt + + mov edi, multiboot_info + mov ecx, eax + cld + rep movsb ; Tell the cpu where the pages area mov edi, pml4t mov cr3, edi - %define PT_PRESENT 1 - %define PT_READABLE 2 + %define PT_PRESENT 1 + %define PT_RW 2 ; pml4t[0] -> pdpt mov edi, pdpt - or edi, PT_PRESENT | PT_READABLE + or edi, PT_PRESENT | PT_RW mov [pml4t], edi ; pdpt[0] -> pdt mov edi, pdt - or edi, PT_PRESENT | PT_READABLE + or edi, PT_PRESENT | PT_RW mov [pdpt], edi ; pdt[0] -> pt mov edi, pt - or edi, PT_PRESENT | PT_READABLE + or edi, PT_PRESENT | PT_RW mov [pdt], edi %define ENTRIES_PER_PT 512 @@ -113,7 +123,7 @@ _start: mov edi, pt mov ebx, kernel_start and ebx, 0xfffff000 - or ebx, PT_PRESENT | PT_READABLE + or ebx, PT_PRESENT | PT_RW mov eax, kernel_end sub eax, kernel_start @@ -127,6 +137,17 @@ _start: add edi, SIZEOF_PT_ENTRY loop .set_pt_entry + ; note(nub31): Vga buffer is already page aligned + %define VGA_BUFFER 0xb8000 + + ; Identity map vga buffer + mov ebx, VGA_BUFFER + or ebx, PT_PRESENT | PT_RW + + mov edi, pt + add edi, VGA_BUFFER / PAGE_SIZE * SIZEOF_PT_ENTRY + mov [edi], ebx + %define CR4_PAE_ENABLE 1 << 5 ; Enable pae @@ -169,8 +190,8 @@ start64: mov ss, ax mov rsp, stack.top - mov rdi, [multiboot_info] - call kmain + mov rdi, multiboot_info + call x86_64_main .halt: cli hlt diff --git a/src/boot/util.h b/src/boot/util.h index 361ca39..75d41e4 100644 --- a/src/boot/util.h +++ b/src/boot/util.h @@ -1,7 +1,11 @@ #pragma once -static inline u32 align(u32 num, u32 alignment) { - return (num + alignment - 1) & ~(alignment - 1); +static inline uptr align_up(uptr value, uptr alignment) { + return (value + alignment - 1) / alignment * alignment; +} + +static inline uptr align_down(uptr value, uptr alignment) { + return value - (value % alignment); } static inline void hlt() {