From 20cffdb66c76cc3373675ada152cf9e021cd0563 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 18:01:35 +0200 Subject: [PATCH 1/8] Add an initial fork() implementation --- kernel/include/sys/Syscall.h | 4 +++- kernel/src/sys/Syscall.cpp | 1 + kernel/src/sys/exec.cpp | 37 +++++++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index e92a795f..5653c67a 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -18,6 +18,7 @@ #define SYS_fcntl 13 #define SYS_mprotect 14 #define SYS_clock 15 +#define SYS_fork 16 namespace Syscall { @@ -41,4 +42,5 @@ void sys_seek(Context* context, int fd, long offset, int whence); void sys_exec(Context* context, const char* pathname); void sys_fcntl(Context* context, int fd, int command, uintptr_t arg); void sys_mprotect(Context* context, void* address, size_t size, int prot); -void sys_clock(Context* context); \ No newline at end of file +void sys_clock(Context* context); +void sys_fork(Context* context); \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index 243756ed..a8e10126 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -27,6 +27,7 @@ void Syscall::entry(Context* context) case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break; case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break; case SYS_clock: sys_clock(context); break; + case SYS_fork: sys_fork(context); break; default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index 9e5df9f7..ce4b621a 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -11,12 +11,43 @@ #include "sys/Syscall.h" #include "sys/elf/ELFLoader.h" #include "thread/Scheduler.h" +#include "utils/Addresses.h" + +void sys_fork(Context* context) // FIXME: Even though both processes's address spaces are the same in content, writing + // to one should not affect the other. +{ + kinfoln("fork(): attempting fork"); + + Task* parent = Scheduler::current_task(); + + Task* child = Scheduler::create_user_task(); + + memcpy(&child->regs, &parent->regs, sizeof(Context)); + if (parent->floating_saved) + { + memcpy(child->floating_region, parent->floating_region, sizeof(parent->floating_region)); + child->floating_saved = true; + } + for (int i = 0; i < TASK_MAX_FDS; i++) { child->files[i] = parent->files[i]; } + + size_t stack_bytes = get_top_of_stack(parent->allocated_stack, TASK_PAGES_IN_STACK) - parent->regs.rsp; + + child->regs.rsp -= stack_bytes; + + memcpy((void*)child->regs.rsp, (void*)parent->regs.rsp, stack_bytes); + + child->address_space = parent->address_space.clone(); + + child->regs.rax = 0; + context->rax = child->id; + + kinfoln("fork(): forked parent %d into child %d", parent->id, child->id); + + return; +} void sys_exec(Context* context, const char* pathname) { - /*context->rax = -ENOSYS; // FIXME: Make exec() work under separate address spaces. - return;*/ - char* kpathname = Syscall::strdup_from_user(pathname); if (!kpathname) { -- 2.34.1 From e672f3994bfd4f903fc7ee05be307c800ff9db91 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 18:19:47 +0200 Subject: [PATCH 2/8] libc: Add support for fork() That doesn't mean it works. Why doesn't it work?? Oh well... --- apps/src/init.c | 12 ++++++++---- kernel/src/trace/StackTracer.cpp | 7 +++++++ libs/libc/include/luna/syscall.h | 1 + libs/libc/include/unistd.h | 3 ++- libs/libc/src/unistd.cpp | 4 +++- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/src/init.c b/apps/src/init.c index f83fd1f7..29f51333 100644 --- a/apps/src/init.c +++ b/apps/src/init.c @@ -141,9 +141,13 @@ int main() fclose(new_stderr); - execv("/bin/sym", NULL); + pid_t child = fork(); + if (child == 0) + { + msleep(500); + printf("I am the child, who is my parent?\n"); + } + else { printf("My child is %ld!", child); } - perror("execv"); // If we're here, execv failed - - return 1; + return 0; } diff --git a/kernel/src/trace/StackTracer.cpp b/kernel/src/trace/StackTracer.cpp index ea305c52..39a38e7f 100644 --- a/kernel/src/trace/StackTracer.cpp +++ b/kernel/src/trace/StackTracer.cpp @@ -1,5 +1,6 @@ #include "trace/StackTracer.h" #include "memory/Memory.h" +#include "memory/VMM.h" #include "std/stdio.h" #include "trace/Resolve.h" @@ -20,6 +21,11 @@ typedef struct stackframe void StackTracer::trace() { + if (!VMM::is_using_kernel_address_space()) + { + VMM::switch_back_to_kernel_address_space(); + VMM::apply_address_space(); + } stackframe* frame = (stackframe*)m_base_pointer; while (frame && frame->instruction) { @@ -27,6 +33,7 @@ void StackTracer::trace() get_symbol_name(frame->instruction, symbol_name, sizeof(symbol_name)); printf("%lx: %s\n", frame->instruction, symbol_name); frame = frame->next; + if (VMM::get_physical((uint64_t)frame) == (uint64_t)-1) return; } } diff --git a/libs/libc/include/luna/syscall.h b/libs/libc/include/luna/syscall.h index 6d92d320..b706db8d 100644 --- a/libs/libc/include/luna/syscall.h +++ b/libs/libc/include/luna/syscall.h @@ -17,6 +17,7 @@ #define SYS_fcntl 13 #define SYS_mprotect 14 #define SYS_clock 15 +#define SYS_fork 16 #ifndef __want_syscalls #ifdef __cplusplus diff --git a/libs/libc/include/unistd.h b/libs/libc/include/unistd.h index 80add4cb..3e5a00a0 100644 --- a/libs/libc/include/unistd.h +++ b/libs/libc/include/unistd.h @@ -22,7 +22,8 @@ extern "C" int execve(const char*, char* const[], char* const[]); /* Not implemented. */ int execvp(const char*, char* const[]); - /* Not implemented. */ + + /* Creates an identical copy of the current process and returns its process ID. */ pid_t fork(void); /* Terminates the program with the status code status. */ diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp index 86ac5df3..1c4577f0 100644 --- a/libs/libc/src/unistd.cpp +++ b/libs/libc/src/unistd.cpp @@ -19,9 +19,10 @@ extern "C" { NOT_IMPLEMENTED("execvp"); } + pid_t fork(void) { - NOT_IMPLEMENTED("fork"); + return syscall(SYS_fork); } long syscall(long number, ...) @@ -34,6 +35,7 @@ extern "C" { case SYS_clock: case SYS_yield: + case SYS_fork: case SYS_gettid: result = __luna_syscall0(number); break; case SYS_exit: case SYS_close: -- 2.34.1 From 7ab80014e1d659f4577700021112265ccbe4e3a1 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 18:42:53 +0200 Subject: [PATCH 3/8] More fork() work --- apps/Makefile | 1 - kernel/src/sys/exec.cpp | 11 +++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/Makefile b/apps/Makefile index 97187f7e..dba694f6 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -11,7 +11,6 @@ CFLAGS := -Wall -Wextra -Werror -Os $(APPS_BIN)/%: $(APPS_SRC)/%.c @mkdir -p $(@D) $(CC) $(CFLAGS) -o $@ $^ - $(STRIP) $@ build: $(REAL_APPS) diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index ce4b621a..ddb708cf 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -32,16 +32,23 @@ void sys_fork(Context* context) // FIXME: Even though both processes's address s size_t stack_bytes = get_top_of_stack(parent->allocated_stack, TASK_PAGES_IN_STACK) - parent->regs.rsp; - child->regs.rsp -= stack_bytes; + child->regs.rsp = get_top_of_stack(child->allocated_stack, TASK_PAGES_IN_STACK) - stack_bytes; memcpy((void*)child->regs.rsp, (void*)parent->regs.rsp, stack_bytes); + child->regs.rsp += sizeof(uintptr_t) * 2; // I don't know why this is... + child->address_space = parent->address_space.clone(); child->regs.rax = 0; context->rax = child->id; - kinfoln("fork(): forked parent %d into child %d", parent->id, child->id); + child->state = child->Running; + + kinfoln("fork(): parent RIP %lx, child RIP %lx, parent RSP %lx, child RSP %lx", parent->regs.rip, child->regs.rip, + parent->regs.rsp, child->regs.rsp); + + kinfoln("fork(): forked parent %ld into child %ld", parent->id, child->id); return; } -- 2.34.1 From 397b1a28190472f704762f117e08ce07cd3320db Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 18:59:05 +0200 Subject: [PATCH 4/8] Kernel: add memmem --- kernel/include/std/string.h | 1 + kernel/src/std/string.cpp | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/kernel/include/std/string.h b/kernel/include/std/string.h index ac1a2459..7c0db986 100644 --- a/kernel/include/std/string.h +++ b/kernel/include/std/string.h @@ -13,6 +13,7 @@ int strncmp(const char* a, const char* b, size_t n); char* strncat(char* dest, const char* src, size_t n); char* strstr(char* haystack, const char* needle); +void* memmem(void* haystack, size_t haystacklen, const void* needle, size_t needlelen); void* memcpy(void* dest, const void* src, size_t n); void* memset(void* dest, int c, size_t n); diff --git a/kernel/src/std/string.cpp b/kernel/src/std/string.cpp index ef5481fd..c133e9fa 100644 --- a/kernel/src/std/string.cpp +++ b/kernel/src/std/string.cpp @@ -87,20 +87,25 @@ char* strcat(char* dest, const char* src) char* strstr(char* haystack, const char* needle) { - size_t needle_size = strlen(needle); - size_t haystack_size = strlen(haystack); - while (*haystack) + return (char*)memmem(haystack, strlen(haystack), needle, strlen(needle)); +} + +void* memmem(void* haystack, size_t haystacklen, const void* needle, size_t needlelen) +{ + const char* hs = (const char*)haystack; + const char* nd = (const char*)needle; + while (haystacklen) { - if (*haystack == *needle) + if (*hs == *nd) { - if (needle_size <= haystack_size) + if (needlelen <= haystacklen) { - if (!strncmp(haystack, needle, needle_size)) return haystack; + if (!memcmp(hs, nd, needlelen)) return (void*)const_cast(hs); } else { return NULL; } } - haystack++; - haystack_size--; + hs++; + haystacklen--; } return NULL; } -- 2.34.1 From 16f797eeee0e27457530b362d98b528344548a7d Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 20:10:05 +0200 Subject: [PATCH 5/8] AddressSpace: make clone() perform a deep copy Which unlinks the address space from its parent. --- kernel/include/memory/AddressSpace.h | 9 --- kernel/src/memory/AddressSpace.cpp | 92 ++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 33 deletions(-) diff --git a/kernel/include/memory/AddressSpace.h b/kernel/include/memory/AddressSpace.h index ef40b774..151e35bd 100644 --- a/kernel/include/memory/AddressSpace.h +++ b/kernel/include/memory/AddressSpace.h @@ -7,8 +7,6 @@ struct AddressSpace void destroy(); - void detach(); - AddressSpace clone(); PageTable* get_pml4() @@ -16,13 +14,6 @@ struct AddressSpace return m_pml4; } - bool is_cloned() - { - return *m_refs > 1; - } - private: PageTable* m_pml4; - - int* m_refs; }; \ No newline at end of file diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp index bef29b71..f444a5ef 100644 --- a/kernel/src/memory/AddressSpace.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -4,27 +4,21 @@ #include "log/Log.h" #include "memory/PMM.h" #include "memory/VMM.h" +#include "misc/hang.h" #include "std/stdlib.h" +#include "std/string.h" #include "utils/move.h" AddressSpace AddressSpace::create() { AddressSpace result; result.m_pml4 = (PageTable*)PMM::request_page(); - result.m_refs = (int*)kmalloc(sizeof(int)); - *result.m_refs = 1; VMM::install_kernel_page_directory_into_address_space(result); return move(result); } void AddressSpace::destroy() { - if (is_cloned()) - { - kdbgln("Will not destroy a cloned address space, I don't own it"); - (*m_refs)--; - return; - } uint64_t pages_freed = 0; for (int i = 0; i < 512; i++) { @@ -78,26 +72,76 @@ void AddressSpace::destroy() pages_freed++; PMM::free_page(m_pml4); - kfree(m_refs); - kdbgln("Reclaimed %ld pages from address space!", pages_freed); } -void AddressSpace::detach() -{ - if (!is_cloned()) return; - (*m_refs)--; - m_refs = (int*)kmalloc(sizeof(int)); - *m_refs = 1; - m_pml4 = (PageTable*)PMM::request_page(); - VMM::install_kernel_page_directory_into_address_space(*this); -} - -AddressSpace AddressSpace::clone() +AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this function. { AddressSpace result; - result.m_pml4 = m_pml4; - result.m_refs = m_refs; - *m_refs = *m_refs + 1; + result.m_pml4 = (PageTable*)PMM::request_page(); + if (!result.m_pml4) return result; + memcpy(result.m_pml4, m_pml4, PAGE_SIZE); + for (int i = 0; i < 512; i++) + { + PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; + PageDirectoryEntry& cloned_pdp_pde = result.m_pml4->entries[i]; + if (!pdp_pde.present) continue; + if (pdp_pde.larger_pages) + { + void* cloned = PMM::request_page(); + memcpy(cloned, (void*)pdp_pde.get_address(), PAGE_SIZE); + cloned_pdp_pde.set_address((uint64_t)cloned); + continue; + } + PageTable* pdp = (PageTable*)pdp_pde.get_address(); + PageTable* cloned_pdp = (PageTable*)PMM::request_page(); + memcpy(cloned_pdp, pdp, PAGE_SIZE); + cloned_pdp_pde.set_address((uint64_t)cloned_pdp); + for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one + { + PageDirectoryEntry& pd_pde = pdp->entries[j]; + PageDirectoryEntry& cloned_pd_pde = cloned_pdp->entries[j]; + if (!pd_pde.present) continue; + if (pd_pde.larger_pages) + { + void* cloned = PMM::request_page(); + memcpy(cloned, (void*)pd_pde.get_address(), PAGE_SIZE); + cloned_pd_pde.set_address((uint64_t)cloned); + continue; + } + PageTable* pd = (PageTable*)pd_pde.get_address(); + PageTable* cloned_pd = (PageTable*)PMM::request_page(); + memcpy(cloned_pd, pd, PAGE_SIZE); + cloned_pd_pde.set_address((uint64_t)cloned_pd); + for (int k = 0; k < 512; k++) + { + PageDirectoryEntry& pt_pde = pd->entries[k]; + PageDirectoryEntry& cloned_pt_pde = cloned_pd->entries[k]; + if (!pt_pde.present) continue; + if (pt_pde.larger_pages) + { + void* cloned = PMM::request_page(); + memcpy(cloned, (void*)pt_pde.get_address(), PAGE_SIZE); + cloned_pt_pde.set_address((uint64_t)cloned); + continue; + } + PageTable* pt = (PageTable*)pt_pde.get_address(); + PageTable* cloned_pt = (PageTable*)PMM::request_page(); + memcpy(cloned_pt, pt, PAGE_SIZE); + cloned_pt_pde.set_address((uint64_t)cloned_pt); + for (int l = 0; l < 512; l++) + { + PageDirectoryEntry& pde = pt->entries[l]; + PageDirectoryEntry& cloned_pde = cloned_pt->entries[l]; + if (!pde.present) continue; + void* cloned = PMM::request_page(); + memcpy(cloned, (void*)pde.get_address(), PAGE_SIZE); + cloned_pde.set_address((uint64_t)cloned); + continue; + } + } + } + } + VMM::install_kernel_page_directory_into_address_space(result); return result; } \ No newline at end of file -- 2.34.1 From 145ea4094538b4ca7ca29257b9443a328c948426 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 20:30:54 +0200 Subject: [PATCH 6/8] fork() is almost working --- kernel/src/interrupts/Entry.cpp | 9 +++++-- kernel/src/std/string.cpp | 19 +++++++++++++-- kernel/src/sys/exec.cpp | 42 ++++----------------------------- kernel/src/thread/Scheduler.cpp | 6 ++--- 4 files changed, 30 insertions(+), 46 deletions(-) diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index f6562ae4..cd9ee88d 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -46,13 +46,18 @@ extern "C" void common_handler(Context* context) { kerrorln("Page fault in ring 3 (RIP %lx), while trying to access %lx, error code %ld", context->rip, context->cr2, context->error_code); + + if (Scheduler::current_task()) + { + kinfoln("Page fault ocurred while in task: %ld", Scheduler::current_task()->id); + } + + hang(); // FIXME: Remove this when multiple address spaces are working. kinfoln("Stack trace:"); StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); - hang(); // FIXME: Remove this when multiple address spaces are working. - Scheduler::task_misbehave(context, -3); } } diff --git a/kernel/src/std/string.cpp b/kernel/src/std/string.cpp index c133e9fa..d6540ca2 100644 --- a/kernel/src/std/string.cpp +++ b/kernel/src/std/string.cpp @@ -87,7 +87,22 @@ char* strcat(char* dest, const char* src) char* strstr(char* haystack, const char* needle) { - return (char*)memmem(haystack, strlen(haystack), needle, strlen(needle)); + size_t needle_size = strlen(needle); + size_t haystack_size = strlen(haystack); + while (*haystack) + { + if (*haystack == *needle) + { + if (needle_size <= haystack_size) + { + if (!strncmp(haystack, needle, needle_size)) return haystack; + } + else { return NULL; } + } + haystack++; + haystack_size--; + } + return NULL; } void* memmem(void* haystack, size_t haystacklen, const void* needle, size_t needlelen) @@ -100,7 +115,7 @@ void* memmem(void* haystack, size_t haystacklen, const void* needle, size_t need { if (needlelen <= haystacklen) { - if (!memcmp(hs, nd, needlelen)) return (void*)const_cast(hs); + if (!memcmp(hs, nd, needlelen)) return (void*)(const_cast(hs)); } else { return NULL; } } diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index ddb708cf..bf559a19 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -6,6 +6,7 @@ #include "memory/MemoryManager.h" #include "memory/PMM.h" #include "memory/VMM.h" +#include "misc/hang.h" #include "std/stdlib.h" #include "std/string.h" #include "sys/Syscall.h" @@ -13,8 +14,7 @@ #include "thread/Scheduler.h" #include "utils/Addresses.h" -void sys_fork(Context* context) // FIXME: Even though both processes's address spaces are the same in content, writing - // to one should not affect the other. +void sys_fork(Context* context) { kinfoln("fork(): attempting fork"); @@ -30,16 +30,10 @@ void sys_fork(Context* context) // FIXME: Even though both processes's address s } for (int i = 0; i < TASK_MAX_FDS; i++) { child->files[i] = parent->files[i]; } - size_t stack_bytes = get_top_of_stack(parent->allocated_stack, TASK_PAGES_IN_STACK) - parent->regs.rsp; - - child->regs.rsp = get_top_of_stack(child->allocated_stack, TASK_PAGES_IN_STACK) - stack_bytes; - - memcpy((void*)child->regs.rsp, (void*)parent->regs.rsp, stack_bytes); - - child->regs.rsp += sizeof(uintptr_t) * 2; // I don't know why this is... - child->address_space = parent->address_space.clone(); + child->regs.rsp += (2 * sizeof(uintptr_t)); + child->regs.rax = 0; context->rax = child->id; @@ -87,20 +81,9 @@ void sys_exec(Context* context, const char* pathname) return; } - uint64_t allocated_stack = (uint64_t)MemoryManager::get_pages(TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); - if (!allocated_stack) - { - kfree(kpathname); - context->rax = -ENOMEM; - return; - } - - uint64_t allocated_stack_phys = VMM::get_physical(allocated_stack); - if ((uint64_t)memusage > PMM::get_free()) { kfree(kpathname); - MemoryManager::release_pages((void*)allocated_stack, TASK_PAGES_IN_STACK); context->rax = -ENOMEM; return; } @@ -111,29 +94,12 @@ void sys_exec(Context* context, const char* pathname) Task* task = Scheduler::current_task(); ASSERT(task); - if (task->address_space.is_cloned()) - { - kdbgln("Detaching cloned address space, %p, %s", (void*)task->address_space.get_pml4(), - task->address_space.is_cloned() ? "is cloned" : "is not cloned"); - task->address_space.detach(); - VMM::switch_to_user_address_space(task->address_space); - kdbgln("Detached cloned address space, %p, %s", (void*)task->address_space.get_pml4(), - task->address_space.is_cloned() ? "is cloned" : "is not cloned"); - } - // At this point, pretty much nothing can fail. ELFImage* image = ELFLoader::load_elf_from_vfs(program); ASSERT(image); // If check_elf_image succeeded, load_elf_from_vfs MUST succeed, unless something has gone terribly // wrong. - task->allocated_stack = allocated_stack; - - for (uint64_t i = 0; i < TASK_PAGES_IN_STACK; i++) - { - VMM::map(allocated_stack + (i * PAGE_SIZE), allocated_stack_phys + (i * PAGE_SIZE), MAP_READ_WRITE | MAP_USER); - } - Scheduler::reset_task(task, image); set_context_from_task(*task, context); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 3544bb9d..4a9fa0bb 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -132,8 +132,8 @@ void Scheduler::load_user_task(const char* filename) new_task->user_task = true; new_task->regs.rip = image->entry; new_task->image = image; - new_task->allocated_stack = (uint64_t)MemoryManager::get_pages( - TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? + new_task->allocated_stack = (uint64_t)MemoryManager::get_pages_at( + 0x100000, TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); new_task->regs.cs = 0x18 | 0x03; new_task->regs.ss = 0x20 | 0x03; @@ -185,8 +185,6 @@ void Scheduler::reap_task(Task* task) VMM::switch_to_user_address_space(exiting_task->address_space); } kinfoln("reaping task %ld, exited with code %ld", exiting_task->id, exiting_task->exit_status); - if (exiting_task->allocated_stack) - MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK); if (exiting_task->image) // FIXME: Also free pages the task has mmap-ed but not munmap-ed. { // ELFLoader::release_elf_image(exiting_task->image); -- 2.34.1 From 9070d1747710e64bfdb59eee6ca439f88f2bb05d Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 16 Oct 2022 09:58:13 +0200 Subject: [PATCH 7/8] wait before letting the fork run for now still is not working why --- kernel/src/sys/exec.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index bf559a19..231edd40 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -32,12 +32,13 @@ void sys_fork(Context* context) child->address_space = parent->address_space.clone(); - child->regs.rsp += (2 * sizeof(uintptr_t)); + child->regs.rsp += sizeof(uintptr_t) * 2; child->regs.rax = 0; context->rax = child->id; - child->state = child->Running; + child->state = child->Sleeping; + child->task_sleep = 1000; kinfoln("fork(): parent RIP %lx, child RIP %lx, parent RSP %lx, child RSP %lx", parent->regs.rip, child->regs.rip, parent->regs.rsp, child->regs.rsp); -- 2.34.1 From 08eb18307b324baee294f5c9f5cbaa641b5feb3f Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 16 Oct 2022 10:35:21 +0200 Subject: [PATCH 8/8] The kernel page directory is already there This doesn't fix anything... --- kernel/src/memory/AddressSpace.cpp | 1 - kernel/src/memory/VMM.cpp | 16 +++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp index f444a5ef..95ecee94 100644 --- a/kernel/src/memory/AddressSpace.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -142,6 +142,5 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu } } } - VMM::install_kernel_page_directory_into_address_space(result); return result; } \ No newline at end of file diff --git a/kernel/src/memory/VMM.cpp b/kernel/src/memory/VMM.cpp index 3932a742..90c00f2c 100644 --- a/kernel/src/memory/VMM.cpp +++ b/kernel/src/memory/VMM.cpp @@ -275,13 +275,19 @@ void VMM::install_kernel_page_directory_into_address_space(AddressSpace& space) PageTable* kernel_last_pdp = (PageTable*)kernel_pml4->entries[511].get_address(); PageTable* kernel_last_pd = (PageTable*)kernel_last_pdp->entries[511].get_address(); - PageTable* space_last_pdp = (PageTable*)PMM::request_page(); - PageDirectoryEntry& space_last_pdp_pde = space_pml4->entries[511]; - space_last_pdp_pde.present = true; - space_last_pdp_pde.read_write = true; - space_last_pdp_pde.set_address((uint64_t)space_last_pdp); + PageTable* space_last_pdp; + + if (!space_last_pdp_pde.present) + { + space_last_pdp = (PageTable*)PMM::request_page(); + + space_last_pdp_pde.present = true; + space_last_pdp_pde.read_write = true; + space_last_pdp_pde.set_address((uint64_t)space_last_pdp); + } + else { space_last_pdp = (PageTable*)space_last_pdp_pde.get_address(); } PageDirectoryEntry& space_last_pd_pde = space_last_pdp->entries[511]; -- 2.34.1