QoL improvements

This commit is contained in:
Alex
2023-03-24 16:22:42 +02:00
parent 3d03f8943b
commit 9ce301907a
15 changed files with 378 additions and 326 deletions

View File

@ -107,6 +107,7 @@ namespace Memory
int Flags = Memory::PTFlag::RW;
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);
}
@ -125,16 +126,18 @@ namespace Memory
AllocatedPagesList.push_back({Address, Count});
/* For security reasons, we clear the memory
if the page is user accessible. */
/* For security reasons, we clear the allocated page
if it's a user page. */
if (User)
memset(Address, 0, Count * PAGE_SIZE);
return Address;
}
void MemMgr::FreePages(void *Address, size_t Count)
{
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{
if (AllocatedPagesList[i].Address == Address)
{
/** TODO: Advanced checks. Allow if the page count is less than the requested one.
@ -150,9 +153,12 @@ namespace Memory
}
KernelAllocator.FreePages(Address, Count);
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->PageTable).Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE)));
}
if (this->Directory)
{
@ -166,11 +172,13 @@ namespace Memory
AllocatedPagesList.remove(i);
return;
}
}
}
void MemMgr::DetachAddress(void *Address)
{
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{
if (AllocatedPagesList[i].Address == Address)
{
if (this->Directory)
@ -185,6 +193,7 @@ namespace Memory
AllocatedPagesList.remove(i);
return;
}
}
}
MemMgr::MemMgr(PageTable4 *PageTable, VirtualFileSystem::Node *Directory)
@ -192,11 +201,13 @@ namespace Memory
if (PageTable)
this->PageTable = PageTable;
else
{
#if defined(a64)
this->PageTable = (PageTable4 *)CPU::x64::readcr3().raw;
#elif defined(a32)
this->PageTable = (PageTable4 *)CPU::x32::readcr3().raw;
#endif
}
this->Directory = Directory;
debug("+ %#lx", this);
@ -212,8 +223,10 @@ namespace Memory
}
if (this->Directory)
{
foreach (auto Child in this->Directory->Children)
vfs->Delete(Child, true);
}
debug("- %#lx", this);
}

View File

@ -42,8 +42,10 @@ namespace Memory
bool Physical::SwapPages(void *Address, size_t PageCount)
{
for (size_t i = 0; i < PageCount; i++)
{
if (!this->SwapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))))
return false;
}
return false;
}
@ -56,20 +58,23 @@ namespace Memory
bool Physical::UnswapPages(void *Address, size_t PageCount)
{
for (size_t i = 0; i < PageCount; i++)
{
if (!this->UnswapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))))
return false;
}
return false;
}
void *Physical::RequestPage()
{
SmartLock(this->MemoryLock);
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{
if (PageBitmap[PageBitmapIndex] == true)
continue;
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
#ifdef DEBUG
if (EnableExternalMemoryTracer)
{
@ -106,6 +111,7 @@ namespace Memory
void *Physical::RequestPages(size_t Count)
{
SmartLock(this->MemoryLock);
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{
if (PageBitmap[PageBitmapIndex] == true)
@ -117,8 +123,10 @@ namespace Memory
continue;
for (size_t i = 0; i < Count; i++)
{
if (PageBitmap[Index + i] == true)
goto NextPage;
}
this->LockPages((void *)(Index * PAGE_SIZE), Count);
#ifdef DEBUG
@ -152,26 +160,6 @@ namespace Memory
if (this->SwapPages((void *)(PageBitmapIndex * PAGE_SIZE), Count))
{
this->LockPages((void *)(PageBitmapIndex * PAGE_SIZE), Count);
#ifdef DEBUG
if (EnableExternalMemoryTracer)
{
char LockTmpStr[64];
strcpy_unsafe(LockTmpStr, __FUNCTION__);
strcat_unsafe(LockTmpStr, "_memTrk");
mExtTrkLock.TimeoutLock(LockTmpStr, 10000);
sprintf(mExtTrkLog, "RequestPages( %ld )=%p~%p\n\r",
Count,
(void *)(PageBitmapIndex * PAGE_SIZE), __builtin_return_address(0));
UniversalAsynchronousReceiverTransmitter::UART mTrkUART = UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3);
for (short i = 0; i < MEM_TRK_MAX_SIZE; i++)
{
if (mExtTrkLog[i] == '\r')
break;
mTrkUART.Write(mExtTrkLog[i]);
}
mExtTrkLock.Unlock();
}
#endif
return (void *)(PageBitmapIndex * PAGE_SIZE);
}
@ -183,12 +171,15 @@ namespace Memory
void Physical::FreePage(void *Address)
{
SmartLock(this->MemoryLock);
if (unlikely(Address == nullptr))
{
warn("Null pointer passed to FreePage.");
return;
}
size_t Index = (size_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == false))
{
warn("Tried to free an already free page. (%p)", Address);
@ -262,8 +253,10 @@ namespace Memory
warn("Trying to lock null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == true))
return;
if (PageBitmap.Set(Index, true))
{
FreeMemory -= PAGE_SIZE;
@ -286,6 +279,7 @@ namespace Memory
warn("Trying to reserve null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == true))
return;
@ -311,6 +305,7 @@ namespace Memory
warn("Trying to unreserve null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == false))
return;
@ -335,25 +330,33 @@ namespace Memory
void Physical::Init(BootInfo *Info)
{
SmartLock(this->MemoryLock);
uint64_t MemorySize = Info->Memory.Size;
TotalMemory = MemorySize;
FreeMemory = MemorySize;
void *LargestFreeMemorySegment = nullptr;
uint64_t LargestFreeMemorySegmentSize = 0;
uint64_t MemorySize = Info->Memory.Size;
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
{
if (Info->Memory.Entry[i].Type == Usable)
{
if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize)
{
// We don't want to use 0 as a memory address.
if (Info->Memory.Entry[i].BaseAddress == nullptr)
/* We don't want to use 0 as a memory address. */
if (Info->Memory.Entry[i].BaseAddress == 0x0)
continue;
LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
debug("Largest free memory segment: %llp (%lldMB)",
(void *)Info->Memory.Entry[i].BaseAddress,
TO_MB(Info->Memory.Entry[i].Length));
}
TotalMemory = MemorySize;
FreeMemory = MemorySize;
}
}
if (LargestFreeMemorySegment == nullptr)
{
@ -366,6 +369,7 @@ namespace Memory
LargestFreeMemorySegment,
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
BitmapSize);
PageBitmap.Size = BitmapSize;
PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment;
for (size_t i = 0; i < BitmapSize; i++)
@ -373,8 +377,11 @@ namespace Memory
trace("Reserving pages...");
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
{
if (Info->Memory.Entry[i].Type != Usable)
this->ReservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);
}
trace("Locking bitmap pages...");
this->ReservePages(0, 0x100);
this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1);

View File

@ -8,35 +8,45 @@ namespace Memory
{
this->UserMode = User;
this->Table = Table;
if (this->UserMode)
{
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
debug("AllocatedStack: %p", AllocatedStack);
memset(AllocatedStack, 0, USER_STACK_SIZE);
debug("AllocatedStack: %p", AllocatedStack);
for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
{
Virtual(Table).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));
this->StackPhyiscalBottom = this->StackBottom;
debug("StackBottom: %p", this->StackBottom);
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;
}
trace("Allocated stack at %p", this->StackBottom);
}
@ -54,7 +64,7 @@ namespace Memory
if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE ||
FaultAddress > (uintptr_t)this->StackTop)
{
return false; // It's not about the stack.
return false; /* It's not about the stack. */
}
else
{
@ -77,7 +87,5 @@ namespace Memory
fixme("Not implemented and probably not needed");
return false;
}
error("Reached end of function! How?");
return false;
}
}

View File

@ -155,6 +155,7 @@ namespace Memory
error("Page %#lx not present", PML4.GetAddress());
return;
}
PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.Address << 12);
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
if (!PDPTE.Present)
@ -162,6 +163,7 @@ namespace Memory
error("Page %#lx not present", PDPTE.GetAddress());
return;
}
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12);
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
if (!PDE.Present)
@ -169,6 +171,7 @@ namespace Memory
error("Page %#lx not present", PDE.GetAddress());
return;
}
PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12);
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
if (!PTE.Present)