mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
fork() stub and QoL improvements
This commit is contained in:
parent
6e6d22403c
commit
61aea6aa8d
@ -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"
|
||||
|
@ -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++)
|
||||
|
@ -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)
|
||||
|
@ -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
20
Core/Memory/PageTable.cpp
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -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);
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -91,7 +91,7 @@ namespace Execute
|
||||
|
||||
struct MmImage
|
||||
{
|
||||
void *Phyiscal;
|
||||
void *Physical;
|
||||
void *Virtual;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
20
syscalls.h
20
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user