From eae48320f33dd586190272a677522f0674f5f90a Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Sat, 13 Dec 2025 21:01:13 +0100 Subject: [PATCH] Harden PFN initialization and expose page count --- xtoskrnl/includes/mm/pfn.hh | 3 +- xtoskrnl/mm/data.cc | 4 +-- xtoskrnl/mm/mmgr.cc | 2 +- xtoskrnl/mm/pfn.cc | 58 +++++++++++++++++++++++++------------ 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/xtoskrnl/includes/mm/pfn.hh b/xtoskrnl/includes/mm/pfn.hh index d8806d9..543d958 100644 --- a/xtoskrnl/includes/mm/pfn.hh +++ b/xtoskrnl/includes/mm/pfn.hh @@ -22,9 +22,10 @@ namespace MM STATIC ULONG_PTR HighestPhysicalPage; STATIC ULONG_PTR LowestPhysicalPage; STATIC ULONG NumberOfPhysicalPages; - STATIC LOADER_MEMORY_DESCRIPTOR OldFreeDescriptor; + STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor; public: + STATIC XTAPI ULONG GetNumberOfPhysicalPages(VOID); STATIC XTAPI VOID ScanMemoryDescriptors(VOID); }; } diff --git a/xtoskrnl/mm/data.cc b/xtoskrnl/mm/data.cc index 19ea38c..c8715b2 100644 --- a/xtoskrnl/mm/data.cc +++ b/xtoskrnl/mm/data.cc @@ -22,7 +22,7 @@ ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0; UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}}; /* Biggest free memory descriptor */ -PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor; +PLOADER_MEMORY_DESCRIPTOR MM::Pfn::FreeDescriptor; /* Highest physical page number */ ULONG_PTR MM::Pfn::HighestPhysicalPage; @@ -34,7 +34,7 @@ ULONG_PTR MM::Pfn::LowestPhysicalPage = -1; ULONG MM::Pfn::NumberOfPhysicalPages; /* Old biggest free memory descriptor */ -LOADER_MEMORY_DESCRIPTOR MM::Pfn::OldFreeDescriptor; +LOADER_MEMORY_DESCRIPTOR MM::Pfn::OriginalFreeDescriptor; /* Instance of the page map routines for the current PML level */ MM::PPAGEMAP MM::Paging::PmlRoutines; diff --git a/xtoskrnl/mm/mmgr.cc b/xtoskrnl/mm/mmgr.cc index 4a77196..ab192ab 100644 --- a/xtoskrnl/mm/mmgr.cc +++ b/xtoskrnl/mm/mmgr.cc @@ -25,7 +25,7 @@ MM::Manager::InitializeMemoryManager(VOID) MM::Pfn::ScanMemoryDescriptors(); /* Check if there are enough physical pages */ - if(NumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) + if(MM::Pfn::GetNumberOfPhysicalPages() < MM_MINIMUM_PHYSICAL_PAGES) { /* Insufficient physical pages, kernel panic */ DebugPrint(L"Insufficient physical pages! Install additional memory\n"); diff --git a/xtoskrnl/mm/pfn.cc b/xtoskrnl/mm/pfn.cc index 555fc3b..ac58496 100644 --- a/xtoskrnl/mm/pfn.cc +++ b/xtoskrnl/mm/pfn.cc @@ -10,6 +10,21 @@ #include +/** + * Retrieves the total number of physical pages managed by the system. + * + * @return Returns the total count of physical memory pages. + * + * @since XT 1.0 + */ +XTAPI +ULONG +MM::Pfn::GetNumberOfPhysicalPages(VOID) +{ + /* Return the number of physical pages */ + return NumberOfPhysicalPages; +} + /** * Scans memory descriptors provided by the boot loader. * @@ -28,53 +43,53 @@ MM::Pfn::ScanMemoryDescriptors(VOID) /* Initially, set number of free pages to 0 */ FreePages = 0; - /* Get a list of memory descriptors provided by the boot loader */ + /* Get the list head of memory descriptors */ LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors(); - /* Iterate through memory mappings provided by the boot loader */ + /* Iterate through the memory descriptors */ MemoryMappings = LoaderMemoryDescriptors->Flink; while(MemoryMappings != LoaderMemoryDescriptors) { - /* Get memory descriptor */ + /* Get the memory descriptor */ MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry); - /* Check if memory type is invisible or cached */ + /* Skip invisible or hardware cached memory regions */ if(MM::Manager::VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || - (MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory)) + (MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory)) { - /* Skip this mapping */ + /* Move to the next descriptor and skip further processing */ MemoryMappings = MemoryMappings->Flink; continue; } - /* Make sure that memory type is not bad */ + /* Count the number of physical pages, excluding bad memory */ if(MemoryDescriptor->MemoryType != LoaderBad) { - /* Increment number of physical pages */ + /* Add the pages from this descriptor to the total count */ NumberOfPhysicalPages += MemoryDescriptor->PageCount; } - /* Find lowest physical page */ + /* Check if this physical page is the lowest one yet */ if(MemoryDescriptor->BasePage < LowestPhysicalPage) { - /* Update lowest physical page */ + /* Update the lowest physical page number found so far */ LowestPhysicalPage = MemoryDescriptor->BasePage; } - /* Find highest physical page */ - if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > HighestPhysicalPage) + /* Check if this physical page is the highest one yet */ + if((MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) > HighestPhysicalPage) { - /* Update highest physical page */ + /* Update the highest physical page number found so far */ HighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; } - /* Check if memory type should be considered as free */ + /* Identify the largest block of free memory */ if(MM::Manager::VerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) { - /* Check if this descriptor contains more free pages */ + /* Check if this free memory block is the largest one yet */ if(MemoryDescriptor->PageCount >= FreePages) { - /* Update free descriptor */ + /* Update the largest free block size and save the descriptor */ FreePages = MemoryDescriptor->PageCount; FreeDescriptor = MemoryDescriptor; } @@ -84,6 +99,13 @@ MM::Pfn::ScanMemoryDescriptors(VOID) MemoryMappings = MemoryMappings->Flink; } - /* Store original free descriptor */ - RTL::Memory::CopyMemory(&OldFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); + /* Ensure a free memory descriptor was found */ + if(!FreeDescriptor) + { + /* No free memory available to bootstrap the system */ + KE::Crash::Panic(0); + } + + /* Save a copy of the original free descriptor before it gets modified */ + RTL::Memory::CopyMemory(&OriginalFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); }