#endif
PVOID PageLookupTableAddress = NULL;
-ULONG TotalPagesInLookupTable = 0;
-ULONG FreePagesInLookupTable = 0;
-ULONG LastFreePageHint = 0;
-ULONG MmLowestPhysicalPage = 0xFFFFFFFF;
-ULONG MmHighestPhysicalPage = 0;
+PFN_NUMBER TotalPagesInLookupTable = 0;
+PFN_NUMBER FreePagesInLookupTable = 0;
+PFN_NUMBER LastFreePageHint = 0;
+PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
+PFN_NUMBER MmHighestPhysicalPage = 0;
-PMEMORY_DESCRIPTOR BiosMemoryMap;
+PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
ULONG BiosMemoryMapEntryCount;
extern ULONG_PTR MmHeapPointer;
ULONG
AddMemoryDescriptor(
- IN OUT PMEMORY_DESCRIPTOR List,
+ IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
IN ULONG MaxCount,
IN PFN_NUMBER BasePage,
IN PFN_NUMBER PageCount,
- IN MEMORY_TYPE MemoryType)
+ IN TYPE_OF_MEMORY MemoryType)
{
ULONG i, c;
PFN_NUMBER NextBase;
return c;
}
-const MEMORY_DESCRIPTOR*
-ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
+const FREELDR_MEMORY_DESCRIPTOR*
+ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR* Current)
{
if (Current == NULL)
{
}
+BOOLEAN
+MmCheckFreeldrImageFile()
+{
+ PIMAGE_NT_HEADERS NtHeaders;
+ PIMAGE_FILE_HEADER FileHeader;
+ PIMAGE_OPTIONAL_HEADER OptionalHeader;
+
+ /* Get the NT headers */
+ NtHeaders = RtlImageNtHeader(&__ImageBase);
+ if (!NtHeaders)
+ {
+ ERR("Coult not get NtHeaders!\n");
+ return FALSE;
+ }
+
+ /* Check the file header */
+ FileHeader = &NtHeaders->FileHeader;
+ if ((FileHeader->Machine != IMAGE_FILE_MACHINE_NATIVE) ||
+ (FileHeader->NumberOfSections != FREELDR_SECTION_COUNT) ||
+ (FileHeader->PointerToSymbolTable != 0) ||
+ (FileHeader->NumberOfSymbols != 0) ||
+ (FileHeader->SizeOfOptionalHeader != 0xE0))
+ {
+ return FALSE;
+ }
+
+ /* Check the optional header */
+ OptionalHeader = &NtHeaders->OptionalHeader;
+ if ((OptionalHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) ||
+ (OptionalHeader->Subsystem != 1) || // native
+ (OptionalHeader->ImageBase != FREELDR_PE_BASE) ||
+ (OptionalHeader->SizeOfImage > MAX_FREELDR_PE_SIZE) ||
+ (OptionalHeader->SectionAlignment != OptionalHeader->FileAlignment))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
BOOLEAN MmInitializeMemoryManager(VOID)
{
#if DBG
- const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+ const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
#endif
TRACE("Initializing Memory Manager.\n");
+ /* Check the freeldr binary */
+ if (!MmCheckFreeldrImageFile())
+ {
+ FrLdrBugCheck(FREELDR_IMAGE_CORRUPTION);
+ }
+
BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
#if DBG
MmInitializeHeap(PageLookupTableAddress);
- TRACE("Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable);
+ TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);
return TRUE;
}
#endif
-ULONG MmGetPageNumberFromAddress(PVOID Address)
+PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
{
return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
}
-ULONG MmGetAddressablePageCountIncludingHoles(VOID)
+PFN_NUMBER MmGetAddressablePageCountIncludingHoles(VOID)
{
- const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
- ULONG PageCount;
+ const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+ PFN_NUMBER PageCount;
//
// Go through the whole memory map to get max address
//
// Yes, remember it if this is real memory
//
- if (MemoryDescriptor->MemoryType == LoaderFree) MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
+ if (MemoryDescriptor->MemoryType == LoaderFree)
+ MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
}
//
}
}
- TRACE("lo/hi %lx %lxn", MmLowestPhysicalPage, MmHighestPhysicalPage);
+ TRACE("lo/hi %lx %lx\n", MmLowestPhysicalPage, MmHighestPhysicalPage);
PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
return PageCount;
}
-PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
+PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
{
- const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
- ULONG PageLookupTableSize;
- ULONG PageLookupTablePages;
- ULONG PageLookupTableStartPage = 0;
+ const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+ SIZE_T PageLookupTableSize;
+ PFN_NUMBER PageLookupTablePages;
+ PFN_NUMBER PageLookupTableStartPage = 0;
PVOID PageLookupTableMemAddress = NULL;
// Calculate how much pages we need to keep the page lookup table
return PageLookupTableMemAddress;
}
-VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
+VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
{
- const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
- TYPE_OF_MEMORY MemoryMapPageAllocated;
- ULONG PageLookupTableStartPage;
- ULONG PageLookupTablePageCount;
+ const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+ PFN_NUMBER PageLookupTableStartPage;
+ PFN_NUMBER PageLookupTablePageCount;
TRACE("MmInitPageLookupTable()\n");
// Parse the whole memory map
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
{
- TRACE("Got range: 0x%lx-0x%lx, type=%s\n",
- MemoryDescriptor->BasePage,
- MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
- MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
-
- MemoryMapPageAllocated = MemoryDescriptor->MemoryType;
-
// 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);
+
+ 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: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
+ TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount);
MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
}
-VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated)
+VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
{
- PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG Index;
+ PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
+ PFN_NUMBER Index;
TRACE("MmMarkPagesInLookupTable()\n");
+ /* Validate the range */
+ if ((StartPage < MmLowestPhysicalPage) ||
+ ((StartPage + PageCount - 1) > MmHighestPhysicalPage))
+ {
+ ERR("Memory (0x%lx:0x%lx) outside of lookup table! Valid range: 0x%lx-0x%lx.\n",
+ StartPage, PageCount, MmLowestPhysicalPage, MmHighestPhysicalPage);
+ return;
+ }
+
StartPage -= MmLowestPhysicalPage;
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
{
#if 0
if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
{
- TRACE("Index = %d StartPage = %d PageCount = %d\n", Index, StartPage, PageCount);
+ TRACE("Index = 0x%x StartPage = 0x%x PageCount = 0x%x\n", Index, StartPage, PageCount);
}
#endif
RealPageLookupTable[Index].PageAllocated = PageAllocated;
TRACE("MmMarkPagesInLookupTable() Done\n");
}
-VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType)
+VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG Index;
+ PFN_NUMBER Index;
StartPage -= MmLowestPhysicalPage;
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
}
}
-ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
+PFN_NUMBER MmCountFreePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG Index;
- ULONG FreePageCount;
+ PFN_NUMBER Index;
+ PFN_NUMBER FreePageCount;
FreePageCount = 0;
for (Index=0; Index<TotalPageCount; Index++)
return FreePageCount;
}
-ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd)
+PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG AvailablePagesSoFar;
- ULONG Index;
+ PFN_NUMBER AvailablePagesSoFar;
+ PFN_NUMBER Index;
if (LastFreePageHint > TotalPageCount)
{
}
else
{
- TRACE("Alloc low memory, LastFreePageHint %d, TPC %d\n", LastFreePageHint, TotalPageCount);
+ TRACE("Alloc low memory, LastFreePageHint 0x%x, TPC 0x%x\n", LastFreePageHint, TotalPageCount);
/* Allocate "low" pages */
for (Index=1; Index < LastFreePageHint; Index++)
{
return 0;
}
-ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage)
+PFN_NUMBER MmFindAvailablePagesBeforePage(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG AvailablePagesSoFar;
- ULONG Index;
+ PFN_NUMBER AvailablePagesSoFar;
+ PFN_NUMBER Index;
if (LastPage > TotalPageCount)
{
return 0;
}
-VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
+VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG Index;
+ PFN_NUMBER Index;
for (Index=TotalPageCount-1; Index>0; Index--)
{
}
}
-BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount)
+BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
- ULONG StartPage;
- ULONG Index;
+ PFN_NUMBER StartPage;
+ PFN_NUMBER Index;
StartPage = MmGetPageNumberFromAddress(PageAddress);