diff options
| author | Amlal El Mahrouss <amlal@el-mahrouss-logic.com> | 2024-03-20 14:47:08 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@el-mahrouss-logic.com> | 2024-03-20 14:47:08 +0100 |
| commit | 4ba02280f19b8a2beb1ad8445be7df6b7f9e1805 (patch) | |
| tree | 4928e93b6463dcce6e0d74120882a6ec572bae5c /Private/Source | |
| parent | 055a896406af227e03708fa20a728259cace704a (diff) | |
kernel: Reworking kernel to support virtual memory.
Signed-off-by: Amlal El Mahrouss <amlal@el-mahrouss-logic.com>
Diffstat (limited to 'Private/Source')
| -rw-r--r-- | Private/Source/KernelHeap.cxx | 91 | ||||
| -rw-r--r-- | Private/Source/LockDelegate.cxx | 2 | ||||
| -rw-r--r-- | Private/Source/New+Delete.cxx | 45 | ||||
| -rw-r--r-- | Private/Source/PEFCodeManager.cxx | 2 | ||||
| -rw-r--r-- | Private/Source/PageManager.cxx | 37 | ||||
| -rw-r--r-- | Private/Source/Pmm.cxx | 33 | ||||
| -rw-r--r-- | Private/Source/ProcessScheduler.cxx | 6 | ||||
| -rw-r--r-- | Private/Source/UserHeap.cxx | 30 |
8 files changed, 94 insertions, 152 deletions
diff --git a/Private/Source/KernelHeap.cxx b/Private/Source/KernelHeap.cxx index e7dd09ed..359e3cbd 100644 --- a/Private/Source/KernelHeap.cxx +++ b/Private/Source/KernelHeap.cxx @@ -5,50 +5,35 @@ ------------------------------------------- */ #include <NewKit/Crc32.hpp> -#include <NewKit/KernelHeap.hpp> +#include <KernelKit/KernelHeap.hpp> +#include <NewKit/PageManager.hpp> -//! @file KernelHeap.cpp +//! @file KernelHeap.cxx //! @brief Kernel allocator. -#define kHeapMaxWrappers (4096 * 8) -#define kHeapMagic 0xAA55 +#define kHeapMagic 0xD4D7 namespace HCore { -STATIC Ref<PTEWrapper *> kWrapperList[kHeapMaxWrappers]; -STATIC SizeT kHeapCount = 0UL; -STATIC Ref<PTEWrapper *> kLastWrapper; -STATIC PageManager kPageManager; +STATIC SizeT kHeapCount = 0UL; +STATIC Ref<PTEWrapper> kHeapLastWrapper; +STATIC PageManager kHeapPageManager; namespace Detail { /// @brief Kernel heap information block. -/// Located before the address. -/// | HIB | ADDRESS | +/// Located before the address bytes. +/// | HIB | ADDRESS | struct HeapInformationBlock final { - UInt16 hMagic; + UInt16 hMagic; Boolean hPresent; - Int32 hCRC32; - Int64 hSizeAddress; - VoidPtr hAddress; + Int32 hCRC32; + Int64 hSizeAddress; + UIntPtr hAddress; }; typedef HeapInformationBlock *HeapInformationBlockPtr; - -STATIC VoidPtr ke_find_heap(const SizeT &sz, const bool rw, const bool user) { - for (SizeT indexWrapper = 0; indexWrapper < kHeapMaxWrappers; - ++indexWrapper) { - if (!kWrapperList[indexWrapper]->Present()) { - kWrapperList[indexWrapper] - ->Reclaim(); /* very straight-forward as you can see. */ - return reinterpret_cast<VoidPtr>( - kWrapperList[indexWrapper]->VirtualAddress()); - } - } - - return nullptr; -} } // namespace Detail -/// @brief Allocate pointer. +/// @brief allocate chunk of memory. /// @param sz size of pointer /// @param rw read write (true to enable it) /// @param user is it accesible by user processes? @@ -56,28 +41,21 @@ STATIC VoidPtr ke_find_heap(const SizeT &sz, const bool rw, const bool user) { VoidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user) { if (sz == 0) ++sz; - if (auto ptr = Detail::ke_find_heap(sz, rw, user); ptr) return ptr; - - Ref<PTEWrapper *> wrapper = kPageManager.Request(user, rw, false); - - Ref<PageManager> refMan(kPageManager); - wrapper->FlushTLB(refMan); - - kLastWrapper = wrapper; + auto wrapper = kHeapPageManager.Request(rw, user, false); + kHeapLastWrapper = wrapper; Detail::HeapInformationBlockPtr heapInfo = reinterpret_cast<Detail::HeapInformationBlockPtr>( - wrapper->VirtualAddress()); + wrapper.VirtualAddress()); heapInfo->hSizeAddress = sz; heapInfo->hMagic = kHeapMagic; - heapInfo->hCRC32 = ke_calculate_crc32((Char *)wrapper->VirtualAddress(), sz); - heapInfo->hAddress = (VoidPtr)wrapper->VirtualAddress(); + heapInfo->hCRC32 = 0; // dont fill it for now. + heapInfo->hAddress = wrapper.VirtualAddress(); - kWrapperList[kHeapCount] = wrapper; ++kHeapCount; - return reinterpret_cast<VoidPtr>(wrapper->VirtualAddress() + + return reinterpret_cast<VoidPtr>(wrapper.VirtualAddress() + sizeof(Detail::HeapInformationBlock)); } @@ -90,35 +68,12 @@ Int32 ke_delete_ke_heap(VoidPtr ptr) { reinterpret_cast<Detail::HeapInformationBlockPtr>(ptr) - sizeof(Detail::HeapInformationBlock); - if (kLastWrapper && virtualAddress->hMagic == kHeapMagic && - (UIntPtr)virtualAddress->hAddress == kLastWrapper->VirtualAddress()) { - if (kPageManager.Free(kLastWrapper)) { + if (kHeapLastWrapper && virtualAddress->hMagic == kHeapMagic && + virtualAddress->hAddress == kHeapLastWrapper.Leak().VirtualAddress()) { virtualAddress->hSizeAddress = 0UL; virtualAddress->hPresent = false; - return true; - } - - return false; - } - - Ref<PTEWrapper *> wrapper{nullptr}; - - for (SizeT indexWrapper = 0; indexWrapper < kHeapCount; ++indexWrapper) { - if (kWrapperList[indexWrapper]->VirtualAddress() == - (UIntPtr)virtualAddress->hAddress) { - wrapper = kWrapperList[indexWrapper]; - - // if page is no more, then mark it also as non executable. - if (kPageManager.Free(wrapper)) { - virtualAddress->hSizeAddress = 0UL; - virtualAddress->hPresent = false; - - return true; - } - - return false; - } + return true; } } diff --git a/Private/Source/LockDelegate.cxx b/Private/Source/LockDelegate.cxx index 30366a86..34cb490d 100644 --- a/Private/Source/LockDelegate.cxx +++ b/Private/Source/LockDelegate.cxx @@ -4,4 +4,4 @@ ------------------------------------------- */ -#include <NewKit/LockDelegate.hpp> +#include <KernelKit/LockDelegate.hpp> diff --git a/Private/Source/New+Delete.cxx b/Private/Source/New+Delete.cxx index fbcc7787..d8901ce0 100644 --- a/Private/Source/New+Delete.cxx +++ b/Private/Source/New+Delete.cxx @@ -4,48 +4,37 @@ ------------------------------------------- */ -#include <NewKit/KernelHeap.hpp> +#include <KernelKit/KernelHeap.hpp> #include <NewKit/New.hpp> -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new[](size_t sz) { + if (sz == 0) ++sz; - return HCore::ke_new_ke_heap(sz, true, false); + return HCore::ke_new_ke_heap(sz, true, false); } -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new(size_t sz) { + if (sz == 0) ++sz; - return HCore::ke_new_ke_heap(sz, true, false); + return HCore::ke_new_ke_heap(sz, true, false); } -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete[](void* ptr) { + if (ptr == nullptr) return; - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr) { + if (ptr == nullptr) return; - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr, size_t sz) { + if (ptr == nullptr) return; - (void)sz; + HCORE_UNUSED(sz); - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } - diff --git a/Private/Source/PEFCodeManager.cxx b/Private/Source/PEFCodeManager.cxx index ec9525dc..bd529dca 100644 --- a/Private/Source/PEFCodeManager.cxx +++ b/Private/Source/PEFCodeManager.cxx @@ -11,7 +11,7 @@ #include <NewKit/Defines.hpp> #include <NewKit/ErrorID.hpp> #include <NewKit/KernelCheck.hpp> -#include <NewKit/KernelHeap.hpp> +#include <KernelKit/KernelHeap.hpp> #include <NewKit/OwnPtr.hpp> #include <NewKit/String.hpp> diff --git a/Private/Source/PageManager.cxx b/Private/Source/PageManager.cxx index 843aa66c..6cedd5b6 100644 --- a/Private/Source/PageManager.cxx +++ b/Private/Source/PageManager.cxx @@ -37,21 +37,27 @@ PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, } PTEWrapper::~PTEWrapper() { - PTE *raw = reinterpret_cast<PTE *>(m_VirtAddr); + PDE* cr3 = (PDE*)hal_read_cr3(); + + PTE* raw = (PTE*)&cr3->Pte[(this->m_VirtAddr % kPTESize)]; raw->Present = false; raw->Rw = false; } -void PTEWrapper::FlushTLB(Ref<PageManager> &pm) { - PTE* ptIndex = (PTE*)((m_VirtAddr >> 12) & 0x1FF); - ptIndex->Wt = m_Wt; - ptIndex->Rw = m_Rw; - ptIndex->Cache = m_Cache; - ptIndex->Present = m_Present; - ptIndex->ExecDisable = m_ExecDisable; +void PTEWrapper::Flush() { + PDE* cr3 = (PDE*)hal_read_cr3(); + + kcout << "CR3: " << hex_number((UIntPtr)cr3) << endl; + kcout << "Index: " << hex_number((this->m_VirtAddr % kPTESize)) << endl; - pm.Leak().FlushTLB((UIntPtr)ptIndex); + cr3->Pte[(this->m_VirtAddr % kPTESize)].Wt = m_Wt; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Rw = m_Rw; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Cache = m_Cache; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Present = m_Present; + cr3->Pte[(this->m_VirtAddr % kPTESize)].ExecDisable = m_ExecDisable; + + kcout << "Wrote PTE to PDE: " << hex_number((UIntPtr)cr3) << endl; } void PageManager::FlushTLB(UIntPtr VirtAddr) { @@ -69,24 +75,19 @@ bool PTEWrapper::Reclaim() { return false; } -PTEWrapper *PageManager::Request(Boolean Rw, Boolean User, +PTEWrapper PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable) { // Store PTE wrapper right after PTE. - PTEWrapper *PageTableEntry = reinterpret_cast<PTEWrapper *>( - HCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User) + sizeof(PTE)); + VoidPtr ptr = reinterpret_cast<PTEWrapper *>( + HCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User)); - PageTableEntry->NoExecute(ExecDisable); - *PageTableEntry = PTEWrapper{Rw, User, ExecDisable, - reinterpret_cast<UIntPtr>(PageTableEntry)}; - return PageTableEntry; + return PTEWrapper{Rw, User, ExecDisable, (UIntPtr)ptr}; } bool PageManager::Free(Ref<PTEWrapper *> &wrapper) { if (wrapper) { if (!Detail::page_disable(wrapper->VirtualAddress())) return false; - - this->FlushTLB(wrapper->VirtualAddress()); return true; } diff --git a/Private/Source/Pmm.cxx b/Private/Source/Pmm.cxx index 6ac8c7d2..9112b3d9 100644 --- a/Private/Source/Pmm.cxx +++ b/Private/Source/Pmm.cxx @@ -13,16 +13,12 @@ Pmm::Pmm() : m_PageManager() { kcout << "[PMM] Allocate PageMemoryManager"; } Pmm::~Pmm() = default; /* If this returns Null pointer, enter emergency mode */ -Ref<PTEWrapper *> Pmm::RequestPage(Boolean user, Boolean readWrite) { - PTEWrapper *pt = m_PageManager.Leak().Request(user, readWrite, false); - - if (pt) { - pt->m_Present = true; - pt->FlushTLB(m_PageManager); +Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite) { + PTEWrapper pt = m_PageManager.Leak().Request(user, readWrite, false); + if (pt.m_Present) { kcout << "[PMM]: Allocation was successful."; - - return Ref<PTEWrapper *>(pt); + return Ref<PTEWrapper>(pt); } kcout << "[PMM]: Allocation failure."; @@ -30,42 +26,43 @@ Ref<PTEWrapper *> Pmm::RequestPage(Boolean user, Boolean readWrite) { return {}; } -Boolean Pmm::FreePage(Ref<PTEWrapper *> PageRef) { +Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef) { if (!PageRef) return false; - PageRef->m_Present = false; + PageRef.Leak().m_Present = false; + PageRef.Leak().Flush(); return true; } -Boolean Pmm::TogglePresent(Ref<PTEWrapper *> PageRef, Boolean Enable) { +Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Present = Enable; + PageRef.Leak().m_Present = Enable; return true; } -Boolean Pmm::ToggleUser(Ref<PTEWrapper *> PageRef, Boolean Enable) { +Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Rw = Enable; + PageRef.Leak().m_Rw = Enable; return true; } -Boolean Pmm::ToggleRw(Ref<PTEWrapper *> PageRef, Boolean Enable) { +Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Rw = Enable; + PageRef.Leak().m_Rw = Enable; return true; } -Boolean Pmm::ToggleShare(Ref<PTEWrapper *> PageRef, Boolean Enable) { +Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Shareable = Enable; + PageRef.Leak().m_Shareable = Enable; return true; } diff --git a/Private/Source/ProcessScheduler.cxx b/Private/Source/ProcessScheduler.cxx index a4f8dd2f..3432fe70 100644 --- a/Private/Source/ProcessScheduler.cxx +++ b/Private/Source/ProcessScheduler.cxx @@ -11,7 +11,7 @@ #include <KernelKit/ProcessScheduler.hpp> #include <KernelKit/SMPManager.hpp> -#include <NewKit/KernelHeap.hpp> +#include <KernelKit/KernelHeap.hpp> #include <NewKit/String.hpp> ///! bugs = 0 @@ -68,7 +68,7 @@ bool rt_in_pool_region(VoidPtr pool_ptr, VoidPtr pool, const SizeT &sz) { Char *_pool_ptr = (Char *)pool_ptr; Char *_pool = (Char *)pool; - for (SizeT index = sz; _pool[sz] != 0x55; --index) { + for (SizeT index = sz; _pool[sz] != kUserHeapMag; --index) { if (&_pool[index] > &_pool_ptr[sz]) continue; if (_pool[index] == _pool_ptr[index]) return true; @@ -151,7 +151,7 @@ SizeT ProcessManager::Add(Ref<Process> &process) { kcout << "ProcessManager::Add(Ref<Process>& process)\r\n"; - process.Leak().HeapPtr = rt_new_heap(kPoolUser | kPoolRw); + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); process.Leak().ProcessId = mTeam.AsArray().Count(); process.Leak().HeapCursor = process.Leak().HeapPtr; diff --git a/Private/Source/UserHeap.cxx b/Private/Source/UserHeap.cxx index beda5c65..83d40845 100644 --- a/Private/Source/UserHeap.cxx +++ b/Private/Source/UserHeap.cxx @@ -5,7 +5,7 @@ ------------------------------------------- */ #include <NewKit/PageManager.hpp> -#include <NewKit/UserHeap.hpp> +#include <KernelKit/UserHeap.hpp> #define kHeapHeaderPaddingSz 16 @@ -37,7 +37,7 @@ class HeapManager final { STATIC SizeT& Count() { return s_NumPools; } STATIC Ref<Pmm>& Leak() { return s_Pmm; } STATIC Boolean& IsEnabled() { return s_PoolsAreEnabled; } - STATIC Array<Ref<PTEWrapper*>, kPoolMaxSz>& The() { return s_Pool; } + STATIC Array<Ref<PTEWrapper>, kUserHeapMaxSz>& The() { return s_Pool; } private: STATIC Size s_NumPools; @@ -45,7 +45,7 @@ class HeapManager final { private: STATIC Boolean s_PoolsAreEnabled; - STATIC Array<Ref<PTEWrapper*>, kPoolMaxSz> s_Pool; + STATIC Array<Ref<PTEWrapper>, kUserHeapMaxSz> s_Pool; }; //! declare fields @@ -53,7 +53,7 @@ class HeapManager final { SizeT HeapManager::s_NumPools = 0UL; Ref<Pmm> HeapManager::s_Pmm; Boolean HeapManager::s_PoolsAreEnabled = true; -Array<Ref<PTEWrapper*>, kPoolMaxSz> HeapManager::s_Pool; +Array<Ref<PTEWrapper>, kUserHeapMaxSz> HeapManager::s_Pool; STATIC VoidPtr ke_find_unused_heap(Int flags); STATIC Void ke_free_heap_internal(VoidPtr vaddr); @@ -61,9 +61,9 @@ STATIC VoidPtr ke_make_heap(VoidPtr vaddr, Int flags); STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr); STATIC VoidPtr ke_find_unused_heap(Int flags) { - for (SizeT index = 0; index < kPoolMaxSz; ++index) { + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) { if (HeapManager::The()[index] && - !HeapManager::The()[index].Leak().Leak().Leak()->Present()) { + !HeapManager::The()[index].Leak().Leak().Leak().Present()) { HeapManager::Leak().Leak().TogglePresent( HeapManager::The()[index].Leak().Leak(), true); kcout << "[ke_find_unused_heap] Done, trying now to make a pool\r\n"; @@ -72,7 +72,7 @@ STATIC VoidPtr ke_find_unused_heap(Int flags) { .Leak() .Leak() .Leak() - ->VirtualAddress(), + .VirtualAddress(), flags); } } @@ -90,7 +90,7 @@ STATIC VoidPtr ke_make_heap(VoidPtr virtualAddress, Int flags) { } poolHdr->fFlags = flags; - poolHdr->fMagic = kPoolMag; + poolHdr->fMagic = kUserHeapMag; poolHdr->fFree = false; kcout << "[ke_make_heap] New allocation has been done.\n"; @@ -106,7 +106,7 @@ STATIC Void ke_free_heap_internal(VoidPtr virtualAddress) { HeapHeader* poolHdr = reinterpret_cast<HeapHeader*>( reinterpret_cast<UIntPtr>(virtualAddress) - sizeof(HeapHeader)); - if (poolHdr->fMagic == kPoolMag) { + if (poolHdr->fMagic == kUserHeapMag) { poolHdr->fFree = false; poolHdr->fFlags = 0; @@ -126,7 +126,7 @@ STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) { // ErrorOr<>::operator Boolean /// if (address matches) /// -> Free heap. - if (HeapManager::The()[index].Leak().Leak().Leak()->VirtualAddress() == + if (HeapManager::The()[index].Leak().Leak().Leak().VirtualAddress() == (UIntPtr)ptr) { HeapManager::Leak().Leak().FreePage( HeapManager::The()[index].Leak().Leak()); @@ -149,13 +149,13 @@ STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) { VoidPtr rt_new_heap(Int32 flags) { if (!HeapManager::IsEnabled()) return nullptr; - if (HeapManager::Count() > kPoolMaxSz) return nullptr; + if (HeapManager::Count() > kUserHeapMaxSz) return nullptr; if (VoidPtr ret = ke_find_unused_heap(flags)) return ret; // this wasn't set to true - auto ref_page = HeapManager::Leak().Leak().RequestPage(((flags & kPoolUser)), - (flags & kPoolRw)); + auto ref_page = HeapManager::Leak().Leak().RequestPage(((flags & kUserHeapUser)), + (flags & kUserHeapRw)); if (ref_page) { ///! reserve page. @@ -166,7 +166,7 @@ VoidPtr rt_new_heap(Int32 flags) { // finally make the pool address. return ke_make_heap( - reinterpret_cast<VoidPtr>(ref_page.Leak()->VirtualAddress()), flags); + reinterpret_cast<VoidPtr>(ref_page.Leak().VirtualAddress()), flags); } return nullptr; @@ -183,7 +183,7 @@ Int32 rt_free_heap(VoidPtr ptr) { if (ke_check_and_free_heap(base, ptr)) return 0; - for (SizeT index = 0; index < kPoolMaxSz; ++index) { + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) { if (ke_check_and_free_heap(index, ptr)) return 0; --base; |
