[FREELDR]
[reactos.git] / reactos / boot / freeldr / freeldr / mm / meminit.c
index 86a5716..b9e8877 100644 (file)
@@ -53,13 +53,13 @@ ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
 #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;
@@ -67,11 +67,11 @@ extern ULONG_PTR    MmHeapStart;
 
 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;
@@ -147,8 +147,8 @@ AddMemoryDescriptor(
     return c;
 }
 
-const MEMORY_DESCRIPTOR*
-ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
+const FREELDR_MEMORY_DESCRIPTOR*
+ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR* Current)
 {
     if (Current == NULL)
     {
@@ -163,14 +163,60 @@ ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
 }
 
 
+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
@@ -209,7 +255,7 @@ BOOLEAN MmInitializeMemoryManager(VOID)
 
        MmInitializeHeap(PageLookupTableAddress);
 
-       TRACE("Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable);
+       TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);
 
 
        return TRUE;
@@ -232,15 +278,15 @@ PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
 }
 #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
@@ -255,7 +301,8 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
             //
             // 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;
         }
 
         //
@@ -270,18 +317,18 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
         }
     }
 
-    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
@@ -315,12 +362,11 @@ PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
     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");
 
@@ -332,42 +378,55 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
     // 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;
@@ -376,10 +435,10 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page
        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++)
@@ -389,11 +448,11 @@ VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG
        }
 }
 
-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++)
@@ -407,11 +466,11 @@ ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
        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)
        {
@@ -442,7 +501,7 @@ ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG Pa
        }
        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++)
                {
@@ -466,11 +525,11 @@ ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG Pa
        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)
        {
@@ -499,10 +558,10 @@ ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG 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--)
        {
@@ -514,11 +573,11 @@ VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
        }
 }
 
-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);