From: Tulio A M Mendes Date: Thu, 5 Feb 2026 20:46:41 +0000 (-0300) Subject: mm: avoid phys/virt assumptions in early vmm/scheduler X-Git-Url: https://projects.tadryanom.me/sitemap.xml?a=commitdiff_plain;h=00ec2bec3f5c8d70733dcdcd851bc9c581cb7f48;p=AdrOS.git mm: avoid phys/virt assumptions in early vmm/scheduler --- diff --git a/src/arch/x86/vmm.c b/src/arch/x86/vmm.c index fca2acb..2c8db83 100644 --- a/src/arch/x86/vmm.c +++ b/src/arch/x86/vmm.c @@ -21,6 +21,20 @@ So accessing boot_pd directly works fine! */ extern uint32_t boot_pd[1024]; +static void* pmm_alloc_page_low(void) { + // Bring-up safety: allocate only from identity-mapped area (0-4MB) + // until we have a general phys->virt mapping. + for (int tries = 0; tries < 1024; tries++) { + void* p = pmm_alloc_page(); + if (!p) return 0; + if ((uintptr_t)p < 0x00400000) { + return p; + } + pmm_free_page(p); + } + return 0; +} + static inline void invlpg(uintptr_t vaddr) { __asm__ volatile("invlpg (%0)" : : "r" (vaddr) : "memory"); } @@ -32,7 +46,7 @@ void vmm_map_page(uint64_t phys, uint64_t virt, uint32_t flags) { // Check if Page Table exists if (!(boot_pd[pd_index] & X86_PTE_PRESENT)) { // Allocate a new PT - uint32_t pt_phys = (uint32_t)pmm_alloc_page(); + uint32_t pt_phys = (uint32_t)pmm_alloc_page_low(); if (!pt_phys) return; // OOM // ACCESS SAFETY: Convert Physical to Virtual to write to it diff --git a/src/kernel/scheduler.c b/src/kernel/scheduler.c index be33a49..a9f2d3b 100644 --- a/src/kernel/scheduler.c +++ b/src/kernel/scheduler.c @@ -10,11 +10,26 @@ struct process* ready_queue_head = NULL; struct process* ready_queue_tail = NULL; static uint32_t next_pid = 1; +static void* pmm_alloc_page_low(void) { + // Bring-up safety: ensure we allocate from the identity-mapped area (0-4MB) + // until we have a full kernel virtual mapping for arbitrary phys pages. + for (int tries = 0; tries < 1024; tries++) { + void* p = pmm_alloc_page(); + if (!p) return 0; + if ((uint32_t)p < 0x00400000) { + return p; + } + // Not safe to touch yet; put it back. + pmm_free_page(p); + } + return 0; +} + void process_init(void) { uart_print("[SCHED] Initializing Multitasking...\n"); // Initial Kernel Thread (PID 0) - IDLE TASK - struct process* kernel_proc = (struct process*)pmm_alloc_page(); + struct process* kernel_proc = (struct process*)pmm_alloc_page_low(); kernel_proc->pid = 0; kernel_proc->state = PROCESS_RUNNING; @@ -35,7 +50,7 @@ void thread_wrapper(void (*fn)(void)) { } struct process* process_create_kernel(void (*entry_point)(void)) { - struct process* proc = (struct process*)pmm_alloc_page(); + struct process* proc = (struct process*)pmm_alloc_page_low(); if (!proc) return NULL; proc->pid = next_pid++; @@ -43,11 +58,15 @@ struct process* process_create_kernel(void (*entry_point)(void)) { proc->cr3 = current_process->cr3; proc->wake_at_tick = 0; - void* stack_phys = pmm_alloc_page(); - uint32_t stack_virt = (uint32_t)stack_phys + 0xC0000000; - proc->kernel_stack = (uint32_t*)stack_virt; + void* stack_phys = pmm_alloc_page_low(); + if (!stack_phys) return NULL; + + // Until we guarantee a linear phys->virt mapping, use the identity-mapped address + // for kernel thread stacks during bring-up. + uint32_t stack_addr = (uint32_t)stack_phys; + proc->kernel_stack = (uint32_t*)stack_addr; - uint32_t* sp = (uint32_t*)((uint8_t*)stack_virt + 4096); + uint32_t* sp = (uint32_t*)((uint8_t*)stack_addr + 4096); *--sp = (uint32_t)entry_point; *--sp = (uint32_t)thread_wrapper;