diff --git a/xtoskrnl/mm/init.c b/xtoskrnl/mm/init.c new file mode 100644 index 0000000..a8c7ab6 --- /dev/null +++ b/xtoskrnl/mm/init.c @@ -0,0 +1,147 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/init.c + * DESCRIPTION: Memory Manager initialization routines + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Performs an early initialization of the XTOS Memory Manager. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmInitializeMemoryManager() +{ + /* Scan memory descriptors provided by the boot loader */ + MmpScanMemoryDescriptors(); + + /* Check if there are enough physical pages */ + if(MmNumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) + { + /* Insufficient physical pages, kernel panic */ + DebugPrint(L"Insufficient physical pages! Install additional memory\n"); + KePanic(0); + } + + /* Proceed with architecture specific initialization */ + MmpInitializeArchitecture(); +} + +/** + * Scans memory descriptors provided by the boot loader. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpScanMemoryDescriptors() +{ + PLOADER_MEMORY_MAPPING MemoryDescriptor; + PLIST_ENTRY MemoryMappings; + PFN_NUMBER FreePages; + + /* Initially, set number of free pages to 0 */ + FreePages = 0; + + /* Iterate through memory mappings provided by the boot loader */ + MemoryMappings = KeInitializationBlock->MemoryDescriptorListHead.Flink; + while(MemoryMappings != &KeInitializationBlock->MemoryDescriptorListHead) + { + /* Get memory descriptor */ + MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_MAPPING, ListEntry); + + /* Check if memory type is invisible or cached */ + if(MmpVerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || + (MemoryDescriptor->MemoryType == LoaderHALCachedMemory)) + { + /* Skip this mapping */ + MemoryMappings = MemoryMappings->Flink; + continue; + } + + /* Make sure that memory type is not bad */ + if(MemoryDescriptor->MemoryType != LoaderBad) + { + /* Increment number of physical pages */ + MmNumberOfPhysicalPages += MemoryDescriptor->PageCount; + } + + /* Find lowest physical page */ + if(MemoryDescriptor->BasePage < MmLowestPhysicalPage) + { + /* Update lowest physical page */ + MmLowestPhysicalPage = MemoryDescriptor->BasePage; + } + + /* Find highest physical page */ + if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage) + { + /* Update highest physical page */ + MmHighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; + } + + /* Check if memory type should be considered as free */ + if(MmpVerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) + { + /* Check if this descriptor contains more free pages */ + if(MemoryDescriptor->PageCount >= FreePages) + { + /* Update free descriptor */ + FreePages = MemoryDescriptor->PageCount; + MmFreeDescriptor = MemoryDescriptor; + } + } + + /* Get next memory descriptor */ + MemoryMappings = MemoryMappings->Flink; + } + + /* Store original free descriptor */ + MmOldFreeDescriptor = *MmFreeDescriptor; +} + +/** Checks whether the specified memory type should be considered as free. + * + * @param MemoryType + * Specifies the memory type to verify. + * + * @return This routine returns TRUE if the specified memory type should be considered as free, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) +{ + return (MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) || + (MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack); +} + +/** + * Checks whether the specified memory type should be considered as invisible for the memory manager. + * + * @param MemoryType + * Specifies the memory type to verify. + * + * @return This routine returns TRUE if the specified memory type should be considered as invisible, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpVerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType) +{ + return (MemoryType == LoaderFirmwarePermanent) || + (MemoryType == LoaderSpecialMemory) || + (MemoryType == LoaderBBTMemory); +}