Harden PFN initialization and expose page count
This commit is contained in:
@@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user