fuck that fork syscall
This commit is contained in:
+1
-1
@@ -265,5 +265,5 @@ uint32_t* copy_page_dir(uint32_t* page_dir_virt)
|
|||||||
}
|
}
|
||||||
debug_log("ENDENDENDEND\n");
|
debug_log("ENDENDENDEND\n");
|
||||||
|
|
||||||
return new_pagedir - 0xC0000000;
|
return new_pagedir;
|
||||||
}
|
}
|
||||||
+25
-19
@@ -58,9 +58,12 @@ int sys_exit(TrapFrame *tf)
|
|||||||
return error_code;
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void trapret(void);
|
||||||
|
|
||||||
int sys_fork(TrapFrame *tf)
|
int sys_fork(TrapFrame *tf)
|
||||||
{
|
{
|
||||||
debug_log("FORKFORKFORKFORK\n");
|
debug_log("FORKFORKFORKFORK\n");
|
||||||
|
scheduler_lock();
|
||||||
|
|
||||||
uint32_t* new_pd = copy_page_dir(current->pagedir);
|
uint32_t* new_pd = copy_page_dir(current->pagedir);
|
||||||
if (!new_pd) {
|
if (!new_pd) {
|
||||||
@@ -94,38 +97,41 @@ int sys_fork(TrapFrame *tf)
|
|||||||
map_page(kstack_physical, child->kstack, PAGE_PRESENT | PAGE_RW);
|
map_page(kstack_physical, child->kstack, PAGE_PRESENT | PAGE_RW);
|
||||||
debug_log("child->kstack: %X\n", child->kstack);
|
debug_log("child->kstack: %X\n", child->kstack);
|
||||||
|
|
||||||
memcpy(child->kstack, current->kstack, KSTACKSIZE);
|
uint8_t* sp = (uint8_t*)(child->kstack + KSTACKSIZE);
|
||||||
debug_log("Kernel stack copied\n");
|
|
||||||
|
|
||||||
uint32_t tf_offset = (uint32_t)current->tf - (uint32_t)current->kstack;
|
// 1. Place the TrapFrame on the child's stack.
|
||||||
child->tf = (TrapFrame*)((uint32_t)child->kstack + tf_offset);
|
sp -= sizeof(TrapFrame);
|
||||||
debug_log("child->tf: %X\n", child->tf);
|
child->tf = (TrapFrame*)sp;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
*child->tf = *tf;
|
*child->tf = *tf;
|
||||||
child->tf->eax = 0; // Child returns 0
|
child->tf->eax = 0; // Child returns 0
|
||||||
debug_log("Parent returns PID: %X, Child returns 0\n", child->pid);
|
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++) {
|
for (int i = 0; i < MAX_OPEN_FILES; i++) {
|
||||||
child->file_descriptors[i] = current->file_descriptors[i];
|
child->file_descriptors[i] = current->file_descriptors[i];
|
||||||
}
|
}
|
||||||
debug_log("File descriptors copied\n");
|
debug_log("File descriptors copied\n");
|
||||||
|
|
||||||
if (!queue) {
|
Process* curr = queue;
|
||||||
queue = child;
|
while (curr->next) {
|
||||||
current = queue;
|
curr = curr->next;
|
||||||
} else {
|
|
||||||
Process* curr = queue;
|
|
||||||
while (curr->next)
|
|
||||||
curr = curr->next;
|
|
||||||
curr->next = child;
|
|
||||||
}
|
}
|
||||||
|
curr->next = child;
|
||||||
debug_log("Child added to queue\n");
|
debug_log("Child added to queue\n");
|
||||||
|
|
||||||
|
scheduler_unlock(); // Release the lock
|
||||||
|
|
||||||
return child->pid;
|
return child->pid;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user