diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp index bc1b85e..e9144da 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/Core/Crash/CrashDetails.cpp @@ -191,9 +191,9 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) #endif #if defined(a64) - Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x64::readcr3().raw)); + Memory::Virtual vma = Memory::Virtual(((Memory::PageTable *)CPU::x64::readcr3().raw)); #elif defined(a32) - Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x32::readcr3().raw)); + Memory::Virtual vma = Memory::Virtual(((Memory::PageTable *)CPU::x32::readcr3().raw)); #elif defined(aa64) Memory::Virtual vma = Memory::Virtual(); #warning "TODO: aa64" @@ -239,9 +239,9 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) Index.PDEIndex, Index.PTEIndex); #if defined(a64) - Memory::PageMapLevel4 PML4 = ((Memory::PageTable4 *)CPU::x64::readcr3().raw)->Entries[Index.PMLIndex]; + Memory::PageMapLevel4 PML4 = ((Memory::PageTable *)CPU::x64::readcr3().raw)->Entries[Index.PMLIndex]; #elif defined(a32) - Memory::PageMapLevel4 PML4 = ((Memory::PageTable4 *)CPU::x32::readcr3().raw)->Entries[Index.PMLIndex]; + Memory::PageMapLevel4 PML4 = ((Memory::PageTable *)CPU::x32::readcr3().raw)->Entries[Index.PMLIndex]; #elif defined(aa64) Memory::PageMapLevel4 PML4 = {.raw = 0}; #warning "TODO: aa64" diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 6eabd5b..3047318 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -430,7 +430,7 @@ namespace CrashHandler uintptr_t Address = NULL; Address = strtol(arg, NULL, 16); debug("Converted %s to %#lx", arg, Address); - Memory::PageTable4 *BasePageTable = (Memory::PageTable4 *)Address; + Memory::PageTable *BasePageTable = (Memory::PageTable *)Address; if (Memory::Virtual().Check(BasePageTable)) { for (int PMLIndex = 0; PMLIndex < 512; PMLIndex++) diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 827bee5..f1ae7f0 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -47,7 +47,7 @@ NewLock(OperatorAllocatorLock); using namespace Memory; Physical KernelAllocator; -PageTable4 *KernelPageTable = nullptr; +PageTable *KernelPageTable = nullptr; bool Page1GBSupport = false; bool PSESupport = false; @@ -55,7 +55,7 @@ static MemoryAllocatorType AllocatorType = MemoryAllocatorType::Pages; Xalloc::V1 *XallocV1Allocator = nullptr; #ifdef DEBUG -NIF void tracepagetable(PageTable4 *pt) +NIF void tracepagetable(PageTable *pt) { for (int i = 0; i < 512; i++) { @@ -74,7 +74,7 @@ NIF void tracepagetable(PageTable4 *pt) } #endif -NIF void MapFromZero(PageTable4 *PT, BootInfo *Info) +NIF void MapFromZero(PageTable *PT, BootInfo *Info) { debug("Mapping from 0x0 to %#llx", Info->Memory.Size); Virtual va = Virtual(PT); @@ -104,7 +104,7 @@ NIF void MapFromZero(PageTable4 *PT, BootInfo *Info) va.Unmap((void *)0); } -NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info) +NIF void MapFramebuffer(PageTable *PT, BootInfo *Info) { debug("Mapping Framebuffer"); Virtual va = Virtual(PT); @@ -143,7 +143,7 @@ NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info) } } -NIF void MapKernel(PageTable4 *PT, BootInfo *Info) +NIF void MapKernel(PageTable *PT, BootInfo *Info) { debug("Mapping Kernel"); uintptr_t KernelStart = (uintptr_t)&_kernel_start; @@ -303,7 +303,7 @@ NIF void InitializeMemoryManagement(BootInfo *Info) */ trace("Initializing Virtual Memory Manager"); - KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1)); + KernelPageTable = (PageTable *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1)); memset(KernelPageTable, 0, PAGE_SIZE); if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) diff --git a/Core/Memory/MemoryManager.cpp b/Core/Memory/MemoryManager.cpp index 11d7ee8..6b1edc9 100644 --- a/Core/Memory/MemoryManager.cpp +++ b/Core/Memory/MemoryManager.cpp @@ -125,7 +125,7 @@ namespace Memory if (User) Flags |= Memory::PTFlag::US; - Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Flags); + Memory::Virtual(this->Table).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Flags); } if (this->Directory) @@ -173,8 +173,8 @@ namespace Memory for (size_t i = 0; i < Count; i++) { - Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Memory::PTFlag::RW); - // Memory::Virtual(this->PageTable).Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); + Memory::Virtual(this->Table).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Memory::PTFlag::RW); + // Memory::Virtual(this->Table).Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); } if (this->Directory) @@ -213,16 +213,16 @@ namespace Memory } } - MemMgr::MemMgr(PageTable4 *PageTable, VirtualFileSystem::Node *Directory) + MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory) { - if (PageTable) - this->PageTable = PageTable; + if (Table) + this->Table = Table; else { #if defined(a64) - this->PageTable = (PageTable4 *)CPU::x64::readcr3().raw; + this->Table = (PageTable *)CPU::x64::readcr3().raw; #elif defined(a32) - this->PageTable = (PageTable4 *)CPU::x32::readcr3().raw; + this->Table = (PageTable *)CPU::x32::readcr3().raw; #endif } @@ -236,7 +236,7 @@ namespace Memory { KernelAllocator.FreePages(ap.Address, ap.PageCount); for (size_t i = 0; i < ap.PageCount; i++) - Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), (void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), Memory::PTFlag::RW); + Memory::Virtual(this->Table).Remap((void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), (void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), Memory::PTFlag::RW); } if (this->Directory) diff --git a/Core/Memory/PageTable.cpp b/Core/Memory/PageTable.cpp new file mode 100644 index 0000000..9970c35 --- /dev/null +++ b/Core/Memory/PageTable.cpp @@ -0,0 +1,20 @@ +#include + +namespace Memory +{ + void PageTable::Update() + { +#if defined(a86) + asmv("mov %0, %%cr3" ::"r"(this)); +#elif defined(aa64) + asmv("msr ttbr0_el1, %0" ::"r"(this)); +#endif + } + + PageTable PageTable::Fork() + { + PageTable NewTable; + memcpy(&NewTable, this, sizeof(PageTable)); + return NewTable; + } +} diff --git a/Core/Memory/StackGuard.cpp b/Core/Memory/StackGuard.cpp index e9ac402..a506f2c 100644 --- a/Core/Memory/StackGuard.cpp +++ b/Core/Memory/StackGuard.cpp @@ -21,60 +21,6 @@ namespace Memory { - StackGuard::StackGuard(bool User, PageTable4 *Table) - { - this->UserMode = User; - this->Table = Table; - - if (this->UserMode) - { - void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); - memset(AllocatedStack, 0, USER_STACK_SIZE); - debug("AllocatedStack: %p", AllocatedStack); - - Virtual va = Virtual(Table); - for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) - { - va.Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)), - (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), - PTFlag::RW | PTFlag::US); - - debug("Mapped %p to %p", (void *)(USER_STACK_BASE + (i * PAGE_SIZE)), - (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE))); - } - - this->StackBottom = (void *)USER_STACK_BASE; - this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); - - this->StackPhyiscalBottom = AllocatedStack; - this->StackPhyiscalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); - - this->Size = USER_STACK_SIZE; - } - else - { - this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); - memset(this->StackBottom, 0, STACK_SIZE); - debug("StackBottom: %p", this->StackBottom); - - this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); - - this->StackPhyiscalBottom = this->StackBottom; - this->StackPhyiscalTop = this->StackTop; - - this->Size = STACK_SIZE; - } - - debug("Allocated stack at %p", this->StackBottom); - } - - StackGuard::~StackGuard() - { - fixme("Temporarily disabled stack guard deallocation"); - // KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size + 1)); - // debug("Freed stack at %p", this->StackBottom); - } - bool StackGuard::Expand(uintptr_t FaultAddress) { if (this->UserMode) @@ -82,22 +28,35 @@ namespace Memory if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE || FaultAddress > (uintptr_t)this->StackTop) { + info("Fault address %#lx is not in range of stack %#lx - %#lx", FaultAddress, + (uintptr_t)this->StackBottom - USER_STACK_SIZE, (uintptr_t)this->StackTop); return false; /* It's not about the stack. */ } else { void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); - debug("AllocatedStack: %p", AllocatedStack); + debug("AllocatedStack: %#lx", AllocatedStack); memset(AllocatedStack, 0, USER_STACK_SIZE); + Virtual va = Virtual(this->Table); - for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) + for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) { - va.Map((void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), PTFlag::RW | PTFlag::US); - debug("Mapped %p to %p", (void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE))); + void *VirtualPage = (void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)); + void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); + + va.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); + AllocatedPages pa = { + .PhysicalAddress = PhysicalPage, + .VirtualAddress = VirtualPage, + }; + AllocatedPagesList.push_back(pa); + debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); } + this->StackBottom = (void *)((uintptr_t)this->StackBottom - USER_STACK_SIZE); this->Size += USER_STACK_SIZE; - info("Stack expanded to %p", this->StackBottom); + info("Stack expanded to %#lx", this->StackBottom); + this->Expanded = true; return true; } } @@ -107,4 +66,116 @@ namespace Memory return false; } } + + void StackGuard::Fork(StackGuard *Parent) + { + this->UserMode = Parent->GetUserMode(); + this->StackBottom = Parent->GetStackBottom(); + this->StackTop = Parent->GetStackTop(); + this->StackPhysicalBottom = Parent->GetStackPhysicalBottom(); + this->StackPhysicalTop = Parent->GetStackPhysicalTop(); + this->Size = Parent->GetSize(); + this->Expanded = Parent->IsExpanded(); + + if (this->UserMode) + { + std::vector ParentAllocatedPages = Parent->GetAllocatedPages(); + + Virtual va = Virtual(Table); + + foreach (auto Page in AllocatedPagesList) + { + va.Unmap(Page.VirtualAddress); + KernelAllocator.FreePage(Page.PhysicalAddress); + debug("Freed %#lx and unmapped %#lx", Page.PhysicalAddress, Page.VirtualAddress); + } + + foreach (auto Page in ParentAllocatedPages) + { + void *NewPhysical = KernelAllocator.RequestPage(); + memcpy(NewPhysical, Page.PhysicalAddress, PAGE_SIZE); + va.Map(Page.VirtualAddress, NewPhysical, PTFlag::RW | PTFlag::US); + + AllocatedPages pa = { + .PhysicalAddress = NewPhysical, + .VirtualAddress = Page.VirtualAddress, + }; + AllocatedPagesList.push_back(pa); + debug("Mapped %#lx to %#lx", NewPhysical, Page.VirtualAddress); + } + } + else + { + fixme("Kernel mode stack fork not implemented"); + } + } + + StackGuard::StackGuard(bool User, PageTable *Table) + { + this->UserMode = User; + this->Table = Table; + + if (this->UserMode) + { + void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); + memset(AllocatedStack, 0, USER_STACK_SIZE); + debug("AllocatedStack: %#lx", AllocatedStack); + + Virtual va = Virtual(Table); + for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) + { + void *VirtualPage = (void *)(USER_STACK_BASE + (i * PAGE_SIZE)); + void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); + va.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); + + AllocatedPages pa = { + .PhysicalAddress = PhysicalPage, + .VirtualAddress = VirtualPage, + }; + AllocatedPagesList.push_back(pa); + debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); + } + + this->StackBottom = (void *)USER_STACK_BASE; + this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); + + this->StackPhysicalBottom = AllocatedStack; + this->StackPhysicalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); + + this->Size = USER_STACK_SIZE; + } + else + { + this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); + memset(this->StackBottom, 0, STACK_SIZE); + debug("StackBottom: %#lx", this->StackBottom); + + this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); + + this->StackPhysicalBottom = this->StackBottom; + this->StackPhysicalTop = this->StackTop; + + this->Size = STACK_SIZE; + + for (size_t i = 0; i < TO_PAGES(STACK_SIZE); i++) + { + AllocatedPages pa = { + .PhysicalAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), + .VirtualAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), + }; + AllocatedPagesList.push_back(pa); + } + } + + debug("Allocated stack at %#lx", this->StackBottom); + } + + StackGuard::~StackGuard() + { + foreach (auto Page in AllocatedPagesList) + { + KernelAllocator.FreePage(Page.PhysicalAddress); + debug("Freed page at %#lx", Page.PhysicalAddress); + } + } } diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index a758c71..eff29b1 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -292,12 +292,12 @@ namespace Memory #endif } - Virtual::Virtual(PageTable4 *Table) + Virtual::Virtual(PageTable *Table) { if (Table) this->Table = Table; else - this->Table = (PageTable4 *)CPU::PageTable(); + this->Table = (PageTable *)CPU::PageTable(); } Virtual::~Virtual() {} diff --git a/Core/StackGuard.cpp b/Core/StackCheck.cpp similarity index 98% rename from Core/StackGuard.cpp rename to Core/StackCheck.cpp index 2a139f9..a08ba12 100644 --- a/Core/StackGuard.cpp +++ b/Core/StackCheck.cpp @@ -46,7 +46,7 @@ Retry: EXTERNC __constructor __no_stack_protector void __guard_setup(void) { - debug("StackGuard: __guard_setup"); + debug("__guard_setup"); if (__stack_chk_guard == 0) __stack_chk_guard = __stack_chk_guard_init(); debug("Stack guard value: %ld", __stack_chk_guard); diff --git a/Core/Symbols.cpp b/Core/Symbols.cpp index 5745e15..18fdf41 100644 --- a/Core/Symbols.cpp +++ b/Core/Symbols.cpp @@ -27,6 +27,7 @@ namespace SymbolResolver { Symbols::Symbols(uintptr_t ImageAddress) { + this->Image = (void *)ImageAddress; debug("Solving symbols for address: %#llx", ImageAddress); Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress; if (Header->e_ident[0] != 0x7F && @@ -87,25 +88,14 @@ namespace SymbolResolver this->TotalEntries--; } -#ifdef DEBUG - static int once = 0; -#endif - trace("Symbol table loaded, %d entries (%ldKB)", this->TotalEntries, TO_KB(this->TotalEntries * sizeof(SymbolTable))); for (uintptr_t i = 0, g = this->TotalEntries; i < g; i++) { this->SymTable[i].Address = ElfSymbols[i].st_value; this->SymTable[i].FunctionName = &strtab[ElfSymbols[i].st_name]; -#ifdef DEBUG - if (once) - debug("Symbol %d: %#llx %s", i, this->SymTable[i].Address, this->SymTable[i].FunctionName); -#endif - } -#ifdef DEBUG - if (!once) - once++; -#endif + // debug("Symbol %d: %#llx %s", i, this->SymTable[i].Address, this->SymTable[i].FunctionName); + } } } diff --git a/Execute/Elf/Exec.cpp b/Execute/Elf/Exec.cpp index d9d8a9f..b61142d 100644 --- a/Execute/Elf/Exec.cpp +++ b/Execute/Elf/Exec.cpp @@ -125,7 +125,7 @@ namespace Execute debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); - uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal; + uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Physical; fixme("Address: %#lx %s%s%s", MAddr, (ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "", @@ -216,7 +216,7 @@ namespace Execute ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}}); ELFBase.InstructionPointer = EntryPoint; - ELFBase.MemoryImage = MemoryImage.Phyiscal; + ELFBase.MemoryImage = MemoryImage.Physical; ELFBase.VirtualMemoryImage = MemoryImage.Virtual; ELFBase.Success = true; diff --git a/Execute/Elf/Parse.cpp b/Execute/Elf/Parse.cpp index 8973299..c480809 100644 --- a/Execute/Elf/Parse.cpp +++ b/Execute/Elf/Parse.cpp @@ -291,7 +291,7 @@ namespace Execute debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); - uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal; + uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Physical; fixme("Address: %#lx %s%s%s", MAddr, (ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "", @@ -303,8 +303,8 @@ namespace Execute } vfs->Close(File); - debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry, - (uintptr_t)MemoryImage.Phyiscal, ELFHeader->e_entry); - return (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry; + debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage.Physical + ELFHeader->e_entry, + (uintptr_t)MemoryImage.Physical, ELFHeader->e_entry); + return (uintptr_t)MemoryImage.Physical + ELFHeader->e_entry; } } diff --git a/Execute/Elf/SharedObjects.cpp b/Execute/Elf/SharedObjects.cpp index f6c096b..49ebba9 100644 --- a/Execute/Elf/SharedObjects.cpp +++ b/Execute/Elf/SharedObjects.cpp @@ -97,7 +97,7 @@ namespace Execute Memory::Virtual().Map(LibFile, LibFile, Length, Memory::RW | Memory::US | Memory::G); Memory::Virtual ncpV = pV; - sl.MemoryImage = r_cst(uint64_t, ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal); + sl.MemoryImage = r_cst(uint64_t, ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Physical); debug("MemoryImage: %#lx", sl.MemoryImage); { diff --git a/Kernel.cpp b/Kernel.cpp index bc9b56b..74d9f54 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -75,6 +75,7 @@ LockClass mExtTrkLock; * - [ ] Mutex implementation. * - [ ] Vector should have a mutex. * - [ ] Update SMBIOS functions to support newer versions and actually use it. + * - [ ] COW (Copy On Write) for the virtual memory. (https://en.wikipedia.org/wiki/Copy-on-write) * * ISSUES: * - [x] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) @@ -83,6 +84,7 @@ LockClass mExtTrkLock; * - [ ] GlobalDescriptorTable::SetKernelStack() is not working properly. * - [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock. * - [ ] CPU usage is not working properly. + * - [ ] fork() syscall is not working. * * CREDITS AND REFERENCES: * - General: diff --git a/KernelThread.cpp b/KernelThread.cpp index 360c84a..6cf6bda 100644 --- a/KernelThread.cpp +++ b/KernelThread.cpp @@ -129,6 +129,8 @@ uint64_t GetUsage(uint64_t OldSystemTime, Tasking::TaskInfo *Info) void TaskMgr() { + TaskManager->GetCurrentThread()->Rename("Debug Task Manager"); + TaskManager->GetCurrentThread()->SetPriority(Tasking::Low); TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)TaskMgr_Dummy100Usage)->Rename("Dummy 100% Usage"); TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)TaskMgr_Dummy0Usage)->Rename("Dummy 0% Usage"); @@ -136,7 +138,7 @@ void TaskMgr() { static int sanity = 0; Video::ScreenBuffer *sb = Display->GetBuffer(0); - for (short i = 0; i < 500; i++) + for (short i = 0; i < 1000; i++) { for (short j = 0; j < 500; j++) { @@ -152,6 +154,8 @@ void TaskMgr() static uint64_t OldSystemTime = 0; foreach (auto Proc in TaskManager->GetProcessList()) { + if (!Proc) + continue; int Status = Proc->Status; uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info); printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n", @@ -159,10 +163,14 @@ void TaskMgr() foreach (auto Thd in Proc->Threads) { + if (!Thd) + continue; Status = Thd->Status; uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info); - printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n\eAABBCC", - Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, Thd->Info.UserTime); + printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", + Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, + Thd->Info.UserTime, Thd->Registers.rip, + Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.rip) : "unknown"); } } OldSystemTime = TimeManager->GetCounter(); @@ -355,10 +363,7 @@ void KernelMainThread() } #ifdef DEBUG - /* TODO: This should not be enabled because it may cause a deadlock. Not sure where or how. */ - // Tasking::PCB *tskMgr = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), "Debug Task Manager", Tasking::TaskTrustLevel::Kernel); - // TaskManager->CreateThread(tskMgr, (Tasking::IP)TaskMgr)->SetPriority(Tasking::Low); - + // Tasking::TCB *tskMgr = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)TaskMgr); TreeFS(vfs->GetRootNode(), 0); #endif diff --git a/Network/NetworkTimeProtocol.cpp b/Network/NetworkTimeProtocol.cpp index 36ad699..7489ff0 100644 --- a/Network/NetworkTimeProtocol.cpp +++ b/Network/NetworkTimeProtocol.cpp @@ -47,7 +47,7 @@ namespace NetworkNTP netdbg("Requesting time"); this->TimeReceived = false; - NTPHeader ReqPacket; // This may require phyiscal memory allocation but Ethernet already has this job. + NTPHeader ReqPacket; // This may require physical memory allocation but Ethernet already has this job. memset(&ReqPacket, 0, sizeof(NTPHeader)); // Zero out the packet *((char *)&ReqPacket) = 0x1b; // byteswap nightmare, this is the code below but in little endian // ReqPacket.LeapIndicator = 0; diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index e8f42ba..b8990eb 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -25,7 +25,7 @@ #include "../syscalls.h" #include "../kernel.h" -#include "../../Userspace/libs/include/sysbase.h" +#include "../../Userspace/libs/include/libsys/base.h" /* KCtl */ #include "../ipc.h" using InterProcessCommunication::IPC; @@ -315,6 +315,69 @@ static int sys_sleep(SyscallsFrame *Frame, uint64_t Milliseconds) return 0; } +static int _ChildPID = 0; + +static int sys_fork(SyscallsFrame *Frame) +{ + UNUSED(Frame); + if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) + return SYSCALL_ACCESS_DENIED; + + fixme("sys_fork: %#lx", Frame); + return SYSCALL_NOT_IMPLEMENTED; + + Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent; + Tasking::TCB *Thread = TaskManager->GetCurrentThread(); + + Tasking::PCB *NewProcess = TaskManager->CreateProcess(Parent, + Parent->Name, + Parent->Security.TrustLevel, + Parent->ELFSymbolTable ? Parent->ELFSymbolTable->GetImage() : nullptr); + + if (!NewProcess) + { + error("Failed to create process for fork"); + return SYSCALL_ERROR; + } + + strncpy(NewProcess->Name, Parent->Name, sizeof(NewProcess->Name)); + NewProcess->IPC->Fork(Parent->IPC); // FIXME: Do we need to do this? + + Tasking::TCB *NewThread = TaskManager->CreateThread(NewProcess, + 0, + nullptr, + nullptr, + std::vector(), + 0, + Thread->Info.Architecture, + Thread->Info.Compatibility, + true); + + if (!NewThread) + { + error("Failed to create thread for fork"); + return SYSCALL_ERROR; + } + _ChildPID = (int)NewThread->ID; + + memcpy(NewThread->FPU, Thread->FPU, sizeof(CPU::x64::FXState)); + NewThread->Stack->Fork(Thread->Stack); + + strncpy(NewThread->Name, Thread->Name, sizeof(Thread->Name)); + NewThread->Info = Thread->Info; + NewThread->GSBase = Thread->GSBase; + NewThread->FSBase = Thread->FSBase; + TaskManager->Sleep(10); /* Re-schedule */ + NewThread->Registers = Thread->Registers; + + debug("Forked thread \"%s\"(%d) from process \"%s\"(%d)", NewThread->Name, NewThread->ID, NewProcess->Name, NewProcess->ID); + NewThread->Status = Tasking::TaskStatus::Ready; + + if (_ChildPID == (int)TaskManager->GetCurrentThread()->ID) + return 0; + return (int)NewThread->ID; +} + static int sys_wait(SyscallsFrame *Frame) { fixme("sys_wait: %#lx", Frame); @@ -333,10 +396,12 @@ static int sys_spawn(SyscallsFrame *Frame) return SYSCALL_NOT_IMPLEMENTED; } -static int sys_spawn_thread(SyscallsFrame *Frame) +static int sys_spawn_thread(SyscallsFrame *Frame, uint64_t InstructionPointer) { - fixme("sys_spawn_thread: %#lx", Frame); - return SYSCALL_NOT_IMPLEMENTED; + Tasking::TCB *thread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), InstructionPointer); + if (thread) + return (int)thread->ID; + return SYSCALL_ERROR; } static int sys_get_thread_list_of_process(SyscallsFrame *Frame) @@ -357,6 +422,16 @@ static int sys_get_current_thread(SyscallsFrame *Frame) return SYSCALL_NOT_IMPLEMENTED; } +static int sys_get_current_process_id(SyscallsFrame *Frame) +{ + return (int)TaskManager->GetCurrentProcess()->ID; +} + +static int sys_get_current_thread_id(SyscallsFrame *Frame) +{ + return (int)TaskManager->GetCurrentThread()->ID; +} + static int sys_get_process_by_pid(SyscallsFrame *Frame) { fixme("sys_get_process_by_pid: %#lx", Frame); @@ -412,6 +487,7 @@ static void *NativeSyscallsTable[] = { [_FileStatus] = (void *)sys_file_status, [_Sleep] = (void *)sys_sleep, + [_Fork] = (void *)sys_fork, [_Wait] = (void *)sys_wait, [_Kill] = (void *)sys_kill, [_Spawn] = (void *)sys_spawn, @@ -419,6 +495,8 @@ static void *NativeSyscallsTable[] = { [_GetThreadListOfProcess] = (void *)sys_get_thread_list_of_process, [_GetCurrentProcess] = (void *)sys_get_current_process, [_GetCurrentThread] = (void *)sys_get_current_thread, + [_GetCurrentProcessID] = (void *)sys_get_current_process_id, + [_GetCurrentThreadID] = (void *)sys_get_current_thread_id, [_GetProcessByPID] = (void *)sys_get_process_by_pid, [_GetThreadByTID] = (void *)sys_get_thread_by_tid, [_KillProcess] = (void *)sys_kill_process, diff --git a/Tasking/InterProcessCommunication.cpp b/Tasking/InterProcessCommunication.cpp index b68954c..ac78fda 100644 --- a/Tasking/InterProcessCommunication.cpp +++ b/Tasking/InterProcessCommunication.cpp @@ -24,6 +24,20 @@ namespace InterProcessCommunication { + void IPC::Fork(IPC *Parent) + { + std::vector ParentHandles = Parent->GetHandles(); + + foreach (auto Hnd in ParentHandles) + { + debug("Forking IPC with ID %d", Hnd->ID); + IPCHandle *NewHnd = (IPCHandle *)mem->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); + memcpy(NewHnd, Hnd, sizeof(IPCHandle)); + NewHnd->Node = vfs->Create(Hnd->Node->Name, VirtualFileSystem::NodeFlags::FILE, IPCNode); + Handles.push_back(NewHnd); + } + } + IPCHandle *IPC::Create(IPCType Type, char UniqueToken[16]) { SmartLock(this->IPCLock); diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index aefda10..db930d3 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -140,7 +140,7 @@ namespace Tasking delete ProcessList[i]->ELFSymbolTable, ProcessList[i]->ELFSymbolTable = nullptr; SecurityManager.DestroyToken(ProcessList[i]->Security.UniqueToken); if (ProcessList[i]->Security.TrustLevel == TaskTrustLevel::User) - KernelAllocator.FreePages((void *)ProcessList[i]->PageTable, TO_PAGES(sizeof(Memory::PageTable4) + 1)); + KernelAllocator.FreePages((void *)ProcessList[i]->PageTable, TO_PAGES(sizeof(Memory::PageTable) + 1)); // Remove the process from parent's children list if (ProcessList[i]->Parent) @@ -306,7 +306,7 @@ namespace Tasking { SecurityManager.DestroyToken(Process->Security.UniqueToken); if (Process->Security.TrustLevel == TaskTrustLevel::User) - KernelAllocator.FreePages((void *)Process->PageTable, TO_PAGES(sizeof(Memory::PageTable4) + 1)); + KernelAllocator.FreePages((void *)Process->PageTable, TO_PAGES(sizeof(Memory::PageTable) + 1)); if (Process->Parent) for (size_t j = 0; j < Process->Parent->Children.size(); j++) @@ -353,7 +353,8 @@ namespace Tasking const std::vector &auxv, IPOffset Offset, TaskArchitecture Architecture, - TaskCompatibility Compatibility) + TaskCompatibility Compatibility, + bool ThreadNotReady) { SmartLock(TaskingLock); TCB *Thread = new TCB; @@ -382,10 +383,13 @@ namespace Tasking Thread->EntryPoint = EntryPoint; Thread->Offset = Offset; Thread->ExitCode = 0xdead; - Thread->Status = TaskStatus::Ready; + if (ThreadNotReady) + Thread->Status = TaskStatus::Waiting; + else + Thread->Status = TaskStatus::Ready; Thread->Memory = new Memory::MemMgr(Parent->PageTable, Parent->memDirectory); Thread->FPU = (CPU::x64::FXState *)Thread->Memory->RequestPages(TO_PAGES(sizeof(CPU::x64::FXState) + 1)); - memset(Thread->FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState)))); + memset(Thread->FPU, 0, sizeof(CPU::x64::FXState)); Thread->Security.TrustLevel = Parent->Security.TrustLevel; Thread->Security.UniqueToken = SecurityManager.CreateToken(); @@ -395,7 +399,7 @@ namespace Tasking Thread->FPU->mxcsrmask = 0b1111111110111111; Thread->FPU->fcw = 0b0000001100111111; - CPU::x64::fxrstor(Thread->FPU); + // CPU::x64::fxrstor(Thread->FPU); // uint16_t FCW = 0b1100111111; // asmv("fldcw %0" // : @@ -451,10 +455,12 @@ namespace Tasking Thread->Registers.rflags.AlwaysOne = 1; Thread->Registers.rflags.IF = 1; Thread->Registers.rflags.ID = 1; - Thread->Registers.rsp = ((uintptr_t)Thread->Stack->GetStackTop()); + /* We need to leave the libc's crt + to make a syscall when the Thread + is exited or we are going to get + GPF or PF exception. */ #pragma region - size_t ArgvSize = 0; if (argv) while (argv[ArgvSize] != nullptr) @@ -477,8 +483,12 @@ namespace Tasking char *StackStringsVirtual = (char *)Thread->Stack->GetStackTop(); // Store string pointers for later - uintptr_t *ArgvStrings = new uintptr_t[ArgvSize]; - uintptr_t *EnvpStrings = new uintptr_t[EnvpSize]; + uintptr_t *ArgvStrings = nullptr; + uintptr_t *EnvpStrings = nullptr; + if (ArgvSize > 0) + ArgvStrings = new uintptr_t[ArgvSize]; + if (EnvpSize > 0) + EnvpStrings = new uintptr_t[EnvpSize]; for (size_t i = 0; i < ArgvSize; i++) { @@ -570,8 +580,10 @@ namespace Tasking // Set the stack pointer to the new stack Thread->Registers.rsp = ((uintptr_t)Thread->Stack->GetStackTop() - SubtractStack); - delete[] ArgvStrings; - delete[] EnvpStrings; + if (ArgvSize > 0) + delete[] ArgvStrings; + if (EnvpSize > 0) + delete[] EnvpStrings; #ifdef DEBUG DumpData("Stack Data", (void *)((uintptr_t)Thread->Stack->GetStackPhysicalTop() - (uintptr_t)SubtractStack), SubtractStack); @@ -584,14 +596,6 @@ namespace Tasking #pragma endregion - /* We need to leave the libc's crt to make a syscall when the Thread is exited or we are going to get GPF or PF exception. */ - - Memory::Virtual uva = Memory::Virtual(Parent->PageTable); - if (!uva.Check((void *)Offset, Memory::PTFlag::US)) - { - error("Offset is not user accessible"); - uva.Map((void *)Offset, (void *)Offset, Memory::PTFlag::RW | Memory::PTFlag::US); // We try one more time. - } #elif defined(a32) #elif defined(aa64) #endif @@ -686,7 +690,7 @@ namespace Tasking SecurityManager.TrustToken(Process->Security.UniqueToken, TTL::TrustedByKernel); #if defined(a64) if (!DoNotCreatePageTable) - Process->PageTable = (Memory::PageTable4 *)CPU::x64::readcr3().raw; + Process->PageTable = (Memory::PageTable *)CPU::x64::readcr3().raw; #elif defined(a32) #elif defined(aa64) #endif @@ -698,8 +702,8 @@ namespace Tasking #if defined(a64) if (!DoNotCreatePageTable) { - Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(sizeof(Memory::PageTable4) + 1)); - memcpy(Process->PageTable, (void *)KernelPageTable, PAGE_SIZE); + Process->PageTable = (Memory::PageTable *)KernelAllocator.RequestPages(TO_PAGES(sizeof(Memory::PageTable) + 1)); + memcpy(Process->PageTable, (void *)KernelPageTable, sizeof(Memory::PageTable)); } #elif defined(a32) #elif defined(aa64) @@ -730,7 +734,7 @@ namespace Tasking Process->Info.Priority = TaskPriority::Normal; debug("Process page table: %#lx", Process->PageTable); - debug("Created process \"%s\"(%d) in process \"%s\"(%d)", + debug("Created process \"%s\"(%d). Parent \"%s\"(%d)", Process->Name, Process->ID, Parent ? Process->Parent->Name : "None", Parent ? Process->Parent->ID : 0); @@ -771,6 +775,7 @@ namespace Tasking TaskArchitecture Arch = TaskArchitecture::ARM64; #endif PCB *kproc = CreateProcess(nullptr, "Kernel", TaskTrustLevel::Kernel); + kproc->ELFSymbolTable = KernelSymbolTable; TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector(), 0, Arch); kthrd->Rename("Main Thread"); debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name); @@ -803,6 +808,7 @@ namespace Tasking TaskingLock.Unlock(); IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Kernel); + IdleProcess->ELFSymbolTable = KernelSymbolTable; for (int i = 0; i < SMP::CPUCores; i++) { IdleThread = CreateThread(IdleProcess, reinterpret_cast(IdleProcessLoop)); diff --git a/include/exec.hpp b/include/exec.hpp index 2de1808..9682991 100644 --- a/include/exec.hpp +++ b/include/exec.hpp @@ -91,7 +91,7 @@ namespace Execute struct MmImage { - void *Phyiscal; + void *Physical; void *Virtual; }; diff --git a/include/ipc.hpp b/include/ipc.hpp index 1ffc0a3..2b6df6b 100644 --- a/include/ipc.hpp +++ b/include/ipc.hpp @@ -73,6 +73,8 @@ namespace InterProcessCommunication void *Process; public: + std::vector GetHandles() { return Handles; } + void Fork(IPC *Parent); IPCHandle *Create(IPCType Type, char UniqueToken[16]); IPCErrorCode Destroy(IPCID ID); IPCErrorCode Allocate(IPCID ID, long Size); diff --git a/include/memory.hpp b/include/memory.hpp index b3d2845..7b1fd4d 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -56,6 +56,7 @@ extern uintptr_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end; #define PAGE_SIZE 0x1000 // 4KB #define PAGE_SIZE_4K PAGE_SIZE // 4KB #define PAGE_SIZE_2M 0x200000 // 2MB +#define PAGE_SIZE_4M 0x400000 // 4MB #define PAGE_SIZE_1G 0x40000000 // 1GB #define STACK_SIZE 0x4000 // 16kb @@ -228,7 +229,7 @@ namespace Memory struct __packed PageTableEntryPtr { - PageTableEntry Entries[511]; + PageTableEntry Entries[512]; }; union __packed PageDirectoryEntry @@ -304,7 +305,7 @@ namespace Memory struct __packed PageDirectoryEntryPtr { - PageDirectoryEntry Entries[511]; + PageDirectoryEntry Entries[512]; }; union __packed PageDirectoryPointerTableEntry @@ -380,7 +381,7 @@ namespace Memory struct __packed PageDirectoryPointerTableEntryPtr { - PageDirectoryPointerTableEntry Entries[511]; + PageDirectoryPointerTableEntry Entries[512]; }; union __packed PageMapLevel4 @@ -433,31 +434,22 @@ namespace Memory } }; - struct PageTable4 + class PageTable { - PageMapLevel4 Entries[511]; + public: + PageMapLevel4 Entries[512]; /** - * @brief Update CR3 with this PageTable4 + * @brief Update CR3 with this PageTable */ - void Update() - { -#if defined(a86) - asmv("mov %0, %%cr3" ::"r"(this)); -#elif defined(aa64) - asmv("msr ttbr0_el1, %0" ::"r"(this)); -#endif - } - } __aligned(0x1000); + void Update(); - struct __packed PageMapLevel5 - { - /* FIXME: NOT IMPLEMENTED! */ - }; - - struct PageTable5 - { - PageMapLevel5 Entries[511]; + /** + * @brief Fork this PageTable + * + * @return A new PageTable with the same content + */ + PageTable Fork(); } __aligned(0x1000); class Physical @@ -605,7 +597,7 @@ namespace Memory { private: NewLock(MemoryLock); - PageTable4 *Table = nullptr; + PageTable *Table = nullptr; public: enum MapType @@ -796,7 +788,7 @@ namespace Memory * * @param Table Page table. If null, it will use the current page table. */ - Virtual(PageTable4 *Table = nullptr); + Virtual(PageTable *Table = nullptr); /** * @brief Destroy the Virtual object @@ -808,30 +800,70 @@ namespace Memory class StackGuard { private: + struct AllocatedPages + { + void *PhysicalAddress; + void *VirtualAddress; + }; + void *StackBottom = nullptr; void *StackTop = nullptr; - void *StackPhyiscalBottom = nullptr; - void *StackPhyiscalTop = nullptr; + void *StackPhysicalBottom = nullptr; + void *StackPhysicalTop = nullptr; uint64_t Size = 0; bool UserMode = false; - PageTable4 *Table = nullptr; + bool Expanded = false; + PageTable *Table = nullptr; + std::vector AllocatedPagesList; public: + std::vector GetAllocatedPages() { return AllocatedPagesList; } + + /** @brief Fork stack guard */ + void Fork(StackGuard *Parent); + + /** @brief For general info */ + uint64_t GetSize() { return Size; } + + /** @brief For general info */ + bool GetUserMode() { return UserMode; } + + /** @brief For general info */ + bool IsExpanded() { return Expanded; } + /** @brief For general info */ void *GetStackBottom() { return StackBottom; } + /** @brief For RSP */ void *GetStackTop() { return StackTop; } - /** @brief For general info */ - void *GetStackPhysicalBottom() { return StackPhyiscalBottom; } - /** @brief For general info */ - void *GetStackPhysicalTop() { return StackPhyiscalTop; } + + /** @brief For general info (avoid if possible) + * @note This can be used only if the stack was NOT expanded. + */ + void *GetStackPhysicalBottom() + { + if (Expanded) + return nullptr; + return StackPhysicalBottom; + } + + /** @brief For general info (avoid if possible) + * @note This can be used only if the stack was NOT expanded. + */ + void *GetStackPhysicalTop() + { + if (Expanded) + return nullptr; + return StackPhysicalTop; + } + /** @brief Called by exception handler */ bool Expand(uintptr_t FaultAddress); /** * @brief Construct a new Stack Guard object * @param User Stack for user mode? */ - StackGuard(bool User, PageTable4 *Table); + StackGuard(bool User, PageTable *Table); /** * @brief Destroy the Stack Guard object */ @@ -857,12 +889,12 @@ namespace Memory void DetachAddress(void *Address); - MemMgr(PageTable4 *PageTable = nullptr, VirtualFileSystem::Node *Directory = nullptr); + MemMgr(PageTable *Table = nullptr, VirtualFileSystem::Node *Directory = nullptr); ~MemMgr(); private: Bitmap PageBitmap; - PageTable4 *PageTable; + PageTable *Table; VirtualFileSystem::Node *Directory; std::vector AllocatedPagesList; @@ -880,7 +912,7 @@ void operator delete(void *Pointer, long unsigned int Size); void operator delete[](void *Pointer, long unsigned int Size); extern Memory::Physical KernelAllocator; -extern Memory::PageTable4 *KernelPageTable; +extern Memory::PageTable *KernelPageTable; #endif // __cplusplus diff --git a/include/symbols.hpp b/include/symbols.hpp index 78699b8..6214a7a 100644 --- a/include/symbols.hpp +++ b/include/symbols.hpp @@ -31,13 +31,13 @@ namespace SymbolResolver SymbolTable SymTable[0x10000]; uintptr_t TotalEntries = 0; + void *Image; public: + void *GetImage() { return this->Image; } Symbols(uintptr_t ImageAddress); ~Symbols(); const char *GetSymbolFromAddress(uintptr_t Address); void AddSymbol(uintptr_t Address, const char *Name); }; } - -extern SymbolResolver::Symbols *SymTbl; diff --git a/include/task.hpp b/include/task.hpp index 95e828b..0d92a00 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -101,7 +101,7 @@ namespace Tasking uint64_t SleepUntil = 0; uint64_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0; uint64_t Year, Month, Day, Hour, Minute, Second; - bool Affinity[256]; // MAX_CPU + bool Affinity[256]; // MAX_CPU TaskPriority Priority; TaskArchitecture Architecture; TaskCompatibility Compatibility; @@ -188,7 +188,7 @@ namespace Tasking std::vector Threads; std::vector Children; InterProcessCommunication::IPC *IPC; - Memory::PageTable4 *PageTable; + Memory::PageTable *PageTable; SymbolResolver::Symbols *ELFSymbolTable; VirtualFileSystem::Node *ProcessDirectory; VirtualFileSystem::Node *memDirectory; @@ -341,7 +341,8 @@ namespace Tasking const std::vector &auxv = std::vector(), IPOffset Offset = 0, TaskArchitecture Architecture = TaskArchitecture::x64, - TaskCompatibility Compatibility = TaskCompatibility::Native); + TaskCompatibility Compatibility = TaskCompatibility::Native, + bool ThreadNotReady = false); Task(const IP EntryPoint); ~Task(); diff --git a/include_std/std/vector.hpp b/include_std/std/vector.hpp index ecb81e0..911ec60 100644 --- a/include_std/std/vector.hpp +++ b/include_std/std/vector.hpp @@ -76,10 +76,12 @@ namespace std #ifdef DEBUG_MEM_ALLOCATION debug("VECTOR INIT: vector( )->Size: %lld", VectorSize); #endif - assert(VectorSize > 0); - VectorBuffer = new T[VectorSize]; - for (size_t i = 0; i < VectorSize; i++) - VectorBuffer[i] = v.VectorBuffer[i]; + if (VectorSize > 0) + { + VectorBuffer = new T[VectorSize]; + for (size_t i = 0; i < VectorSize; i++) + VectorBuffer[i] = v.VectorBuffer[i]; + } } NIF ~vector() diff --git a/syscalls.h b/syscalls.h index 7034aba..03a2177 100644 --- a/syscalls.h +++ b/syscalls.h @@ -126,6 +126,12 @@ enum NativeSyscalls */ _Sleep, + /** @brief Fork the current process + * @fn int Fork() + * This syscall is used to create a new process that is a copy of the current process. + */ + _Fork, + /** @brief Wait for a process or a thread * @fn * This syscall is used to wait for a specific process or thread to terminate. It returns the exit code of the process or thread. @@ -145,7 +151,7 @@ enum NativeSyscalls _Spawn, /** @brief Spawn a new thread - * @fn + * @fn int SpawnThread(uint64_t InstructionPointer) * This syscall is used to create a new thread within the current process with the provided function and arguments. */ _SpawnThread, @@ -168,6 +174,18 @@ enum NativeSyscalls */ _GetCurrentThread, + /** @brief Get current process ID + * @fn int GetCurrentProcessID() + * This syscall is used to retrieve information about the current process. + */ + _GetCurrentProcessID, + + /** @brief Get current thread ID + * @fn int GetCurrentThreadID() + * This syscall is used to retrieve information about the current thread. + */ + _GetCurrentThreadID, + /** @brief Get process by PID * @fn * This syscall is used to retrieve information about a specific process by its PID.