BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount) { PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable; ULONG StartPage; ULONG Index; StartPage = MmGetPageNumberFromAddress(PageAddress); StartPage -= MmLowestPhysicalPage; // Make sure they aren't trying to go past the // end of availabe memory if ((StartPage + PageCount) > TotalPageCount) { return FALSE; } for (Index=StartPage; Index<(StartPage + PageCount); Index++) { // If this page is allocated then there obviously isn't // memory availabe so return FALSE if (RealPageLookupTable[Index].PageAllocated != LoaderFree) { return FALSE; } } return TRUE; }
VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount) { const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL; PFN_NUMBER PageLookupTableStartPage; PFN_NUMBER PageLookupTablePageCount; TRACE("MmInitPageLookupTable()\n"); // Mark every page as allocated initially // We will go through and mark pages again according to the memory map // But this will mark any holes not described in the map as allocated MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent); // Parse the whole memory map while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL) { // Mark used pages in the lookup table if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= TotalPageCount) { TRACE("Marking pages 0x%lx-0x%lx as type %s\n", MemoryDescriptor->BasePage, MemoryDescriptor->BasePage + MemoryDescriptor->PageCount, MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType)); MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType); } else TRACE("Ignoring pages 0x%lx-0x%lx (%s)\n", MemoryDescriptor->BasePage, MemoryDescriptor->BasePage + MemoryDescriptor->PageCount, MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType)); } // Mark the pages that the lookup table occupies as reserved PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable); PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage; TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount); MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary); }
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount) { const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL; TYPE_OF_MEMORY MemoryMapPageAllocated; ULONG PageLookupTableStartPage; ULONG PageLookupTablePageCount; TRACE("MmInitPageLookupTable()\n"); // // Mark every page as allocated initially // We will go through and mark pages again according to the memory map // But this will mark any holes not described in the map as allocated // MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent); // // Parse the whole memory map // while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL) { // // Convert ARC memory type to loader memory type // switch (MemoryDescriptor->MemoryType) { case MemoryFree: { // // Allocatable memory // MemoryMapPageAllocated = LoaderFree; break; } case MemoryFirmwarePermanent: { // // Firmware permanent memory // MemoryMapPageAllocated = LoaderFirmwarePermanent; break; } case MemoryFirmwareTemporary: { // // Firmware temporary memory // MemoryMapPageAllocated = LoaderFirmwareTemporary; break; } case MemoryLoadedProgram: { // // Bootloader code // MemoryMapPageAllocated = LoaderLoadedProgram; break; } case MemorySpecialMemory: { // // OS Loader Stack // MemoryMapPageAllocated = LoaderOsloaderStack; break; } default: { // // Put something sensible here, which won't be overwritten // MemoryMapPageAllocated = LoaderSpecialMemory; break; } } // // Mark used pages in the lookup table // TRACE("Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount); MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryMapPageAllocated); } // // Mark the pages that the lookup table occupies as reserved // PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable); PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage; TRACE("Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount); MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary); }