diff --git a/src/mm/paging.c b/src/mm/paging.c index 24d2ccf..84dae5a 100644 --- a/src/mm/paging.c +++ b/src/mm/paging.c @@ -265,5 +265,5 @@ uint32_t* copy_page_dir(uint32_t* page_dir_virt) } debug_log("ENDENDENDEND\n"); - return new_pagedir - 0xC0000000; + return new_pagedir; } \ No newline at end of file diff --git a/src/tasking/syscalls.c b/src/tasking/syscalls.c index 05dffb0..0051c30 100644 --- a/src/tasking/syscalls.c +++ b/src/tasking/syscalls.c @@ -58,9 +58,12 @@ int sys_exit(TrapFrame *tf) return error_code; } +extern void trapret(void); + int sys_fork(TrapFrame *tf) { debug_log("FORKFORKFORKFORK\n"); + scheduler_lock(); uint32_t* new_pd = copy_page_dir(current->pagedir); if (!new_pd) { @@ -94,38 +97,41 @@ int sys_fork(TrapFrame *tf) map_page(kstack_physical, child->kstack, PAGE_PRESENT | PAGE_RW); debug_log("child->kstack: %X\n", child->kstack); - memcpy(child->kstack, current->kstack, KSTACKSIZE); - debug_log("Kernel stack copied\n"); + uint8_t* sp = (uint8_t*)(child->kstack + KSTACKSIZE); - uint32_t tf_offset = (uint32_t)current->tf - (uint32_t)current->kstack; - child->tf = (TrapFrame*)((uint32_t)child->kstack + tf_offset); - debug_log("child->tf: %X\n", child->tf); - - if (current->context) { - uint32_t context_offset = (uint32_t)current->context - (uint32_t)current->kstack; - child->context = (Context*)((uint32_t)child->kstack + context_offset); - debug_log("child->context: %X\n", child->context); - } + // 1. Place the TrapFrame on the child's stack. + sp -= sizeof(TrapFrame); + child->tf = (TrapFrame*)sp; *child->tf = *tf; child->tf->eax = 0; // Child returns 0 debug_log("Parent returns PID: %X, Child returns 0\n", child->pid); + sp -= sizeof(Context); + child->context = (Context*)sp; + memset(child->context, 0, sizeof(Context)); + + // 5. Set the child's starting instruction pointer to trapret. + // When the child is scheduled, it will execute trapret, which will + // restore the registers from the TrapFrame and iret to user mode. + child->context->eip = (uint32_t)trapret; + + // 6. IMPORTANT: Set the child's kernel stack pointer for the scheduler. + child->kesp = (uint32_t)sp; + for (int i = 0; i < MAX_OPEN_FILES; i++) { child->file_descriptors[i] = current->file_descriptors[i]; } debug_log("File descriptors copied\n"); - if (!queue) { - queue = child; - current = queue; - } else { - Process* curr = queue; - while (curr->next) - curr = curr->next; - curr->next = child; + Process* curr = queue; + while (curr->next) { + curr = curr->next; } + curr->next = child; debug_log("Child added to queue\n"); + + scheduler_unlock(); // Release the lock return child->pid; }