]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
mm: avoid phys/virt assumptions in early vmm/scheduler
authorTulio A M Mendes <[email protected]>
Thu, 5 Feb 2026 20:46:41 +0000 (17:46 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 5 Feb 2026 20:46:41 +0000 (17:46 -0300)
src/arch/x86/vmm.c
src/kernel/scheduler.c

index 2a5fd42540261a8378f69a9082cd729da9fd3ad1..987a6fd10d34b474905bb1bd8e0f265c5ab9c452 100644 (file)
    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");
 }
@@ -41,7 +55,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
index ae45b97dd5b197bd4210a7380b4f9c7d5c1794e7..ab5d057415a9b68828388780ccbd99fd14f196db 100644 (file)
@@ -19,11 +19,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;
@@ -44,7 +59,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++;
@@ -52,11 +67,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;