fork() stub and QoL improvements

This commit is contained in:
Alex 2023-05-03 06:37:39 +03:00
parent 6e6d22403c
commit 61aea6aa8d
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
25 changed files with 426 additions and 185 deletions

View File

@ -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"

View File

@ -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++)

View File

@ -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)

View File

@ -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)

20
Core/Memory/PageTable.cpp Normal file
View File

@ -0,0 +1,20 @@
#include <memory.hpp>
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;
}
}

View File

@ -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<AllocatedPages> 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);
}
}
}

View File

@ -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() {}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
{

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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<AuxiliaryVector>(),
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,

View File

@ -24,6 +24,20 @@
namespace InterProcessCommunication
{
void IPC::Fork(IPC *Parent)
{
std::vector<IPCHandle *> 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);

View File

@ -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<AuxiliaryVector> &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<AuxiliaryVector>(), 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<uintptr_t>(IdleProcessLoop));

View File

@ -91,7 +91,7 @@ namespace Execute
struct MmImage
{
void *Phyiscal;
void *Physical;
void *Virtual;
};

View File

@ -73,6 +73,8 @@ namespace InterProcessCommunication
void *Process;
public:
std::vector<IPCHandle *> GetHandles() { return Handles; }
void Fork(IPC *Parent);
IPCHandle *Create(IPCType Type, char UniqueToken[16]);
IPCErrorCode Destroy(IPCID ID);
IPCErrorCode Allocate(IPCID ID, long Size);

View File

@ -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<AllocatedPages> AllocatedPagesList;
public:
std::vector<AllocatedPages> 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<AllocatedPages> 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

View File

@ -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;

View File

@ -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<TCB *> Threads;
std::vector<PCB *> 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<AuxiliaryVector> &auxv = std::vector<AuxiliaryVector>(),
IPOffset Offset = 0,
TaskArchitecture Architecture = TaskArchitecture::x64,
TaskCompatibility Compatibility = TaskCompatibility::Native);
TaskCompatibility Compatibility = TaskCompatibility::Native,
bool ThreadNotReady = false);
Task(const IP EntryPoint);
~Task();

View File

@ -76,10 +76,12 @@ namespace std
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR INIT: vector( <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()

View File

@ -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.