Harden PFN initialization and expose page count
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 28s
Builds / ExectOS (amd64, release) (push) Successful in 25s
Builds / ExectOS (i686, debug) (push) Successful in 26s
Builds / ExectOS (i686, release) (push) Successful in 24s

This commit is contained in:
2025-12-13 21:01:13 +01:00
parent 17b5649362
commit eae48320f3
4 changed files with 45 additions and 22 deletions

View File

@@ -22,9 +22,10 @@ namespace MM
STATIC ULONG_PTR HighestPhysicalPage; STATIC ULONG_PTR HighestPhysicalPage;
STATIC ULONG_PTR LowestPhysicalPage; STATIC ULONG_PTR LowestPhysicalPage;
STATIC ULONG NumberOfPhysicalPages; STATIC ULONG NumberOfPhysicalPages;
STATIC LOADER_MEMORY_DESCRIPTOR OldFreeDescriptor; STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor;
public: public:
STATIC XTAPI ULONG GetNumberOfPhysicalPages(VOID);
STATIC XTAPI VOID ScanMemoryDescriptors(VOID); STATIC XTAPI VOID ScanMemoryDescriptors(VOID);
}; };
} }

View File

@@ -22,7 +22,7 @@ ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}}; UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
/* Biggest free memory descriptor */ /* Biggest free memory descriptor */
PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor; PLOADER_MEMORY_DESCRIPTOR MM::Pfn::FreeDescriptor;
/* Highest physical page number */ /* Highest physical page number */
ULONG_PTR MM::Pfn::HighestPhysicalPage; ULONG_PTR MM::Pfn::HighestPhysicalPage;
@@ -34,7 +34,7 @@ ULONG_PTR MM::Pfn::LowestPhysicalPage = -1;
ULONG MM::Pfn::NumberOfPhysicalPages; ULONG MM::Pfn::NumberOfPhysicalPages;
/* Old biggest free memory descriptor */ /* 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 */ /* Instance of the page map routines for the current PML level */
MM::PPAGEMAP MM::Paging::PmlRoutines; MM::PPAGEMAP MM::Paging::PmlRoutines;

View File

@@ -25,7 +25,7 @@ MM::Manager::InitializeMemoryManager(VOID)
MM::Pfn::ScanMemoryDescriptors(); MM::Pfn::ScanMemoryDescriptors();
/* Check if there are enough physical pages */ /* 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 */ /* Insufficient physical pages, kernel panic */
DebugPrint(L"Insufficient physical pages! Install additional memory\n"); DebugPrint(L"Insufficient physical pages! Install additional memory\n");

View File

@@ -10,6 +10,21 @@
#include <xtos.hh> #include <xtos.hh>
/**
* 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. * Scans memory descriptors provided by the boot loader.
* *
@@ -28,53 +43,53 @@ MM::Pfn::ScanMemoryDescriptors(VOID)
/* Initially, set number of free pages to 0 */ /* Initially, set number of free pages to 0 */
FreePages = 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(); LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors();
/* Iterate through memory mappings provided by the boot loader */ /* Iterate through the memory descriptors */
MemoryMappings = LoaderMemoryDescriptors->Flink; MemoryMappings = LoaderMemoryDescriptors->Flink;
while(MemoryMappings != LoaderMemoryDescriptors) while(MemoryMappings != LoaderMemoryDescriptors)
{ {
/* Get memory descriptor */ /* Get the memory descriptor */
MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry); 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) || 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; MemoryMappings = MemoryMappings->Flink;
continue; continue;
} }
/* Make sure that memory type is not bad */ /* Count the number of physical pages, excluding bad memory */
if(MemoryDescriptor->MemoryType != LoaderBad) if(MemoryDescriptor->MemoryType != LoaderBad)
{ {
/* Increment number of physical pages */ /* Add the pages from this descriptor to the total count */
NumberOfPhysicalPages += MemoryDescriptor->PageCount; NumberOfPhysicalPages += MemoryDescriptor->PageCount;
} }
/* Find lowest physical page */ /* Check if this physical page is the lowest one yet */
if(MemoryDescriptor->BasePage < LowestPhysicalPage) if(MemoryDescriptor->BasePage < LowestPhysicalPage)
{ {
/* Update lowest physical page */ /* Update the lowest physical page number found so far */
LowestPhysicalPage = MemoryDescriptor->BasePage; LowestPhysicalPage = MemoryDescriptor->BasePage;
} }
/* Find highest physical page */ /* Check if this physical page is the highest one yet */
if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > HighestPhysicalPage) 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; 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)) 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) if(MemoryDescriptor->PageCount >= FreePages)
{ {
/* Update free descriptor */ /* Update the largest free block size and save the descriptor */
FreePages = MemoryDescriptor->PageCount; FreePages = MemoryDescriptor->PageCount;
FreeDescriptor = MemoryDescriptor; FreeDescriptor = MemoryDescriptor;
} }
@@ -84,6 +99,13 @@ MM::Pfn::ScanMemoryDescriptors(VOID)
MemoryMappings = MemoryMappings->Flink; MemoryMappings = MemoryMappings->Flink;
} }
/* Store original free descriptor */ /* Ensure a free memory descriptor was found */
RTL::Memory::CopyMemory(&OldFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); 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));
} }