[ros-diffs] [tkreuzer] 66087: [FREELDR] Make the DiskReadBuffer location and size dynamic. Should fix a number of issues with non-standard BIOSes. Many thanks to jeditobe for his help with testing/debugging of...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Sun Jan 25 23:24:31 UTC 2015


Author: tkreuzer
Date: Sun Jan 25 23:24:27 2015
New Revision: 66087

URL: http://svn.reactos.org/svn/reactos?rev=66087&view=rev
Log:
[FREELDR]
Make the DiskReadBuffer location and size dynamic. Should fix a number of issues with non-standard BIOSes. Many thanks to jeditobe for his help with testing/debugging of this issue.
CORE-8899 #resolve
CORE-9031 #resolve

Modified:
    trunk/reactos/boot/freeldr/bootsect/fatx.S
    trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c
    trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c
    trunk/reactos/boot/freeldr/freeldr/disk/partition.c
    trunk/reactos/boot/freeldr/freeldr/fs/ext2.c
    trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h
    trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h
    trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
    trunk/reactos/boot/freeldr/freeldr/include/disk.h
    trunk/reactos/boot/freeldr/freeldr/include/mm.h
    trunk/reactos/boot/freeldr/freeldr/mm/meminit.c

Modified: trunk/reactos/boot/freeldr/bootsect/fatx.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/bootsect/fatx.S?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/bootsect/fatx.S	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/bootsect/fatx.S	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -7,6 +7,7 @@
  *                  Timo Kreuzer
  */
 
+#define DISKREADBUFFER HEX(8E000)
 
 /*
  * Layout of a FAT volume:

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -307,10 +307,10 @@
     {
         NodeNumber = (UCHAR)i;
 
-        x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER);
+        x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
         if (x == 0)
         {
-            DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
+            DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
 
             TRACE("Node: %u  Size %u (0x%x)\n",
                   DeviceNode->Node,

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -42,6 +42,8 @@
 static CHAR Hex[] = "0123456789abcdef";
 UCHAR PcBiosDiskCount = 0;
 CHAR PcDiskIdentifier[32][20];
+PVOID DiskReadBuffer;
+SIZE_T DiskReadBufferSize;
 
 
 static ARC_STATUS DiskClose(ULONG FileId)
@@ -119,7 +121,7 @@
     ULONGLONG SectorOffset;
 
     TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
-    MaxSectors   = PcDiskReadBufferSize / Context->SectorSize;
+    MaxSectors   = DiskReadBufferSize / Context->SectorSize;
     SectorOffset = Context->SectorNumber + Context->SectorOffset;
 
     ret = 1;
@@ -134,7 +136,7 @@
             Context->DriveNumber,
             SectorOffset,
             ReadSectors,
-            (PVOID)DISKREADBUFFER);
+            DiskReadBuffer);
         if (!ret)
             break;
 
@@ -142,7 +144,7 @@
         if (Length > N)
             Length = N;
 
-        RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
+        RtlCopyMemory(Ptr, DiskReadBuffer, Length);
 
         Ptr += Length;
         N -= Length;
@@ -197,14 +199,14 @@
     PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80];
 
     /* Read the MBR */
-    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
+    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
     {
         ERR("Reading MBR failed\n");
         return;
     }
 
-    Buffer = (ULONG*)DISKREADBUFFER;
-    Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
+    Buffer = (ULONG*)DiskReadBuffer;
+    Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
 
     Signature =  Mbr->Signature;
     TRACE("Signature: %x\n", Signature);
@@ -288,13 +290,13 @@
         * harddisks. So, we set the buffer to known contents first, then try to
         * read. If the BIOS reports success but the buffer contents haven't
         * changed then we fail anyway */
-    memset((PVOID) DISKREADBUFFER, 0xcd, 512);
-    while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
+    memset(DiskReadBuffer, 0xcd, 512);
+    while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
     {
         Changed = FALSE;
         for (i = 0; ! Changed && i < 512; i++)
         {
-            Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
+            Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
         }
         if (! Changed)
         {
@@ -310,7 +312,7 @@
 
         DiskCount++;
         DriveNumber++;
-        memset((PVOID) DISKREADBUFFER, 0xcd, 512);
+        memset(DiskReadBuffer, 0xcd, 512);
     }
     DiskReportError(TRUE);
 
@@ -326,13 +328,13 @@
         ULONG Checksum = 0;
 
         /* Read the MBR */
-        if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER))
+        if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))
         {
           ERR("Reading MBR failed\n");
           return FALSE;
         }
 
-        Buffer = (ULONG*)DISKREADBUFFER;
+        Buffer = (ULONG*)DiskReadBuffer;
 
         /* Calculate the MBR checksum */
         for (i = 0; i < 2048 / sizeof(ULONG); i++) Checksum += Buffer[i];

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -29,32 +29,11 @@
 
 #define MAX_BIOS_DESCRIPTORS 32
 
-#define STACK_BASE_PAGE    (STACKLOW / PAGE_SIZE)
-#define FREELDR_BASE_PAGE  (FREELDR_BASE / PAGE_SIZE)
-#define DISKBUF_BASE_PAGE  (DISKREADBUFFER / PAGE_SIZE)
-
-#define STACK_PAGE_COUNT   (FREELDR_BASE_PAGE - STACK_BASE_PAGE)
-#define FREELDR_PAGE_COUNT (DISKBUF_BASE_PAGE - FREELDR_BASE_PAGE)
-#define DISKBUF_PAGE_COUNT (0x10)
-#define BIOSBUF_PAGE_COUNT (1)
-
 BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS];
 ULONG PcBiosMapCount;
-ULONG PcDiskReadBufferSize;
-
-FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] =
-{
-    { LoaderFirmwarePermanent, 0x00,               1 }, // realmode int vectors
-    { LoaderFirmwareTemporary, 0x01,               STACK_BASE_PAGE - 1 }, // freeldr stack, cmdline, BIOS call buffer
-    { LoaderOsloaderStack,     STACK_BASE_PAGE,    FREELDR_BASE_PAGE - STACK_BASE_PAGE }, // prot mode stack.
-    { LoaderLoadedProgram,     FREELDR_BASE_PAGE,  FREELDR_PAGE_COUNT }, // freeldr image
-    { LoaderFirmwareTemporary, DISKBUF_BASE_PAGE,  DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER
-    { LoaderFirmwarePermanent, 0x9F,               0x1 },  // EBDA
-    { LoaderFirmwarePermanent, 0xA0,               0x50 }, // ROM / Video
-    { LoaderSpecialMemory,     0xF0,               0x10 }, // ROM / Video
-    { LoaderSpecialMemory,     0xFFF,              1 }, // unusable memory
-    { 0, 0, 0 }, // end of map
-};
+
+FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1];
+ULONG PcMapCount;
 
 ULONG
 AddMemoryDescriptor(
@@ -186,38 +165,12 @@
 }
 
 static
-ULONG
-PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
+BOOLEAN
+GetEbdaLocation(
+    PULONG BaseAddress,
+    PULONG Size)
 {
     REGS Regs;
-    ULONG MapCount = 0;
-    ULONGLONG RealBaseAddress, RealSize;
-    TYPE_OF_MEMORY MemoryType;
-    ULONG Size;
-    ASSERT(PcBiosMapCount == 0);
-
-    TRACE("GetBiosMemoryMap()\n");
-
-    /* Make sure the usable memory is large enough. To do this we check the 16
-       bit value at address 0x413 inside the BDA, which gives us the usable size
-       in KB */
-    Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
-    if (Size < DISKREADBUFFER || Size - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE)
-    {
-        FrLdrBugCheckWithMessage(
-            MEMORY_INIT_FAILURE,
-            __FILE__,
-            __LINE__,
-            "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n"
-            "If you see this, please report to the ReactOS team!",
-            Size);
-    }
-    PcDiskReadBufferSize = (Size - DISKREADBUFFER) & ~0xfff;
-    if (PcDiskReadBufferSize > MAX_DISKREADBUFFER_SIZE)
-    {
-        PcDiskReadBufferSize = MAX_DISKREADBUFFER_SIZE;
-    }
-    TRACE("PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize);
 
     /* Get the address of the Extended BIOS Data Area (EBDA).
      * Int 15h, AH=C1h
@@ -232,36 +185,44 @@
     Int386(0x15, &Regs, &Regs);
 
     /* If the function fails, there is no EBDA */
-    if (INT386_SUCCESS(Regs))
-    {
-        /* Check if this is high enough */
-        ULONG EbdaBase = (ULONG)Regs.w.es << 4;
-        if (EbdaBase < DISKREADBUFFER || EbdaBase - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE)
-        {
-            FrLdrBugCheckWithMessage(
-                MEMORY_INIT_FAILURE,
-                __FILE__,
-                __LINE__,
-                "The location of your EBDA is 0x%lx, which is too low!\n\n"
-                "If you see this, please report to the ReactOS team!",
-                EbdaBase);
-        }
-        if (((EbdaBase - DISKREADBUFFER) & ~0xfff) < PcDiskReadBufferSize)
-        {
-            PcDiskReadBufferSize = (EbdaBase - DISKREADBUFFER) & ~0xfff;
-            TRACE("After EBDA check, PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize);
-        }
-
-        /* Calculate the (max) size of the EBDA */
-        Size = 0xA0000 - EbdaBase;
-
-        /* Add the descriptor */
-        MapCount = AddMemoryDescriptor(PcMemoryMap,
-                                       MAX_BIOS_DESCRIPTORS,
-                                       (EbdaBase / MM_PAGE_SIZE),
-                                       (Size / MM_PAGE_SIZE),
-                                       LoaderFirmwarePermanent);
-    }
+    if (!INT386_SUCCESS(Regs))
+    {
+        return FALSE;
+    }
+
+    /* Get Base address and (maximum) size */
+    *BaseAddress = (ULONG)Regs.w.es << 4;
+    *Size = 0xA0000 - *BaseAddress;
+    return TRUE;
+}
+
+static
+ULONG
+PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
+{
+    REGS Regs;
+    ULONGLONG RealBaseAddress, EndAddress, RealSize;
+    TYPE_OF_MEMORY MemoryType;
+    ULONG Size;
+    ASSERT(PcBiosMapCount == 0);
+
+    TRACE("GetBiosMemoryMap()\n");
+
+    /* Make sure the usable memory is large enough. To do this we check the 16
+       bit value at address 0x413 inside the BDA, which gives us the usable size
+       in KB */
+    Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
+    if (Size < MEMORY_MARGIN)
+    {
+        FrLdrBugCheckWithMessage(
+            MEMORY_INIT_FAILURE,
+            __FILE__,
+            __LINE__,
+            "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n"
+            "If you see this, please report to the ReactOS team!",
+            Size);
+    }
+
 
     /* Int 15h AX=E820h
      * Newer BIOSes - GET SYSTEM MEMORY MAP
@@ -322,13 +283,24 @@
         {
             MemoryType = LoaderFree;
 
-            /* Align up base of memory area */
-            RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL);
-
-            /* Calculate the length after aligning the base */
-            RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
-                       PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
-            RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL);
+            /* Align up base of memory range */
+            RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
+                                          PAGE_SIZE);
+
+            /* Calculate aligned EndAddress */
+            EndAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
+                         PcBiosMemoryMap[PcBiosMapCount].Length;
+            EndAddress = ALIGN_DOWN_BY(EndAddress, PAGE_SIZE);
+
+            /* Check if there is anything left */
+            if (EndAddress <= RealBaseAddress)
+            {
+                /* This doesn't span any page, so continue with next range */
+                continue;
+            }
+
+            /* Calculate the length of the aligned range */
+            RealSize = EndAddress - RealBaseAddress;
         }
         else
         {
@@ -338,18 +310,20 @@
                 MemoryType = LoaderSpecialMemory;
 
             /* Align down base of memory area */
-            RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL);
+            RealBaseAddress = ALIGN_DOWN_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
+                                            PAGE_SIZE);
+
             /* Calculate the length after aligning the base */
             RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
                        PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
-            RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL);
+            RealSize = ALIGN_UP_BY(RealSize, PAGE_SIZE);
         }
 
         /* Check if we can add this descriptor */
-        if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize))
+        if ((RealSize >= MM_PAGE_SIZE) && (PcMapCount < MaxMemoryMapSize))
         {
             /* Add the descriptor */
-            MapCount = AddMemoryDescriptor(PcMemoryMap,
+            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                            MAX_BIOS_DESCRIPTORS,
                                            (PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE),
                                            (PFN_NUMBER)(RealSize / MM_PAGE_SIZE),
@@ -366,12 +340,72 @@
             TRACE("End Of System Memory Map!\n\n");
             break;
         }
-
-    }
-
-    return MapCount;
-}
-
+    }
+
+    TRACE("GetBiosMemoryMap end, PcBiosMapCount = %ld\n", PcBiosMapCount);
+    return PcBiosMapCount;
+}
+
+VOID
+ReserveMemory(
+    ULONG_PTR BaseAddress,
+    SIZE_T Size,
+    TYPE_OF_MEMORY MemoryType,
+    PCHAR Usage)
+{
+    ULONG_PTR BasePage, PageCount;
+    ULONG i;
+
+    BasePage = BaseAddress / PAGE_SIZE;
+    PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
+
+    for (i = 0; i < PcMapCount; i++)
+    {
+        /* Check for conflicting descriptor */
+        if ((PcMemoryMap[i].BasePage < BasePage + PageCount) &&
+            (PcMemoryMap[i].BasePage + PcMemoryMap[i].PageCount > BasePage))
+        {
+            /* Check if the memory is free */
+            if (PcMemoryMap[i].MemoryType != LoaderFree)
+            {
+                FrLdrBugCheckWithMessage(
+                    MEMORY_INIT_FAILURE,
+                    __FILE__,
+                    __LINE__,
+                    "Failed to reserve memory in the range 0x%Ix - 0x%Ix for %s",
+                    BaseAddress,
+                    Size,
+                    Usage);
+            }
+        }
+    }
+
+    /* Add the memory descriptor */
+    PcMapCount = AddMemoryDescriptor(PcMemoryMap,
+                                     MAX_BIOS_DESCRIPTORS,
+                                     BasePage,
+                                     PageCount,
+                                     MemoryType);
+}
+
+VOID
+SetMemory(
+    ULONG_PTR BaseAddress,
+    SIZE_T Size,
+    TYPE_OF_MEMORY MemoryType)
+{
+    ULONG_PTR BasePage, PageCount;
+
+    BasePage = BaseAddress / PAGE_SIZE;
+    PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
+
+    /* Add the memory descriptor */
+    PcMapCount = AddMemoryDescriptor(PcMemoryMap,
+                                     MAX_BIOS_DESCRIPTORS,
+                                     BasePage,
+                                     PageCount,
+                                     MemoryType);
+}
 
 PFREELDR_MEMORY_DESCRIPTOR
 PcMemGetMemoryMap(ULONG *MemoryMapSize)
@@ -379,13 +413,16 @@
     ULONG i, EntryCount;
     ULONG ExtendedMemorySizeAtOneMB;
     ULONG ExtendedMemorySizeAtSixteenMB;
+    ULONG EbdaBase, EbdaSize;
+    TRACE("PcMemGetMemoryMap()\n");
 
     EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS);
 
     /* If the BIOS didn't provide a memory map, synthesize one */
-    if (0 == EntryCount)
-    {
-        GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB);
+    if (EntryCount == 0)
+    {
+        GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB,
+                                       &ExtendedMemorySizeAtSixteenMB);
 
         /* Conventional memory */
         AddMemoryDescriptor(PcMemoryMap,
@@ -395,7 +432,7 @@
                             LoaderFree);
 
         /* Extended memory */
-        EntryCount = AddMemoryDescriptor(PcMemoryMap,
+        PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                          MAX_BIOS_DESCRIPTORS,
                                          1024 * 1024 / PAGE_SIZE,
                                          ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE,
@@ -404,16 +441,65 @@
         if (ExtendedMemorySizeAtSixteenMB != 0)
         {
             /* Extended memory at 16MB */
-            EntryCount = AddMemoryDescriptor(PcMemoryMap,
+            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                              MAX_BIOS_DESCRIPTORS,
                                              0x1000000 / PAGE_SIZE,
                                              ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE,
                                              LoaderFree);
         }
-    }
+
+        /* Check if we have an EBDA and get it's location */
+        if (GetEbdaLocation(&EbdaBase, &EbdaSize))
+        {
+            /* Add the descriptor */
+            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
+                                             MAX_BIOS_DESCRIPTORS,
+                                             (EbdaBase / PAGE_SIZE),
+                                             ADDRESS_AND_SIZE_TO_SPAN_PAGES(EbdaBase, EbdaSize),
+                                             LoaderFirmwarePermanent);
+        }
+    }
+
+    /* Setup some protected ranges */
+    SetMemory(0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA
+    SetMemory(0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory
+    SetMemory(0x0F0000, 0x10000, LoaderSpecialMemory); // ROM
+    SetMemory(0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?)
+
+    /* Reserve some static ranges for freeldr */
+    ReserveMemory(0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area");
+    ReserveMemory(STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack");
+    ReserveMemory(FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image");
+
+    /* Default to 1 page above freeldr for the disk read buffer */
+    DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE);
+    DiskReadBufferSize = PAGE_SIZE;
+
+    /* Scan for free range above freeldr image */
+    for (i = 0; i < PcMapCount; i++)
+    {
+        if ((PcMemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) &&
+            (PcMemoryMap[i].MemoryType == LoaderFree))
+        {
+            /* Use this range for the disk read buffer */
+            DiskReadBuffer = (PVOID)(PcMemoryMap[i].BasePage * PAGE_SIZE);
+            DiskReadBufferSize = min(PcMemoryMap[i].PageCount * PAGE_SIZE,
+                                     MAX_DISKREADBUFFER_SIZE);
+            break;
+        }
+    }
+
+    TRACE("DiskReadBuffer=%p, DiskReadBufferSize=%lx\n",
+          DiskReadBuffer, DiskReadBufferSize);
+
+    /* Now reserve the range for the disk read buffer */
+    ReserveMemory((ULONG_PTR)DiskReadBuffer,
+                  DiskReadBufferSize,
+                  LoaderFirmwareTemporary,
+                  "Disk read buffer");
 
     TRACE("Dumping resulting memory map:\n");
-    for (i = 0; i < EntryCount; i++)
+    for (i = 0; i < PcMapCount; i++)
     {
         TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
               PcMemoryMap[i].BasePage,
@@ -421,9 +507,9 @@
               MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
     }
 
-    *MemoryMapSize = EntryCount;
-
+    *MemoryMapSize = PcMapCount;
     return PcMemoryMap;
 }
 
+
 /* EOF */

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -198,17 +198,17 @@
     while (N > 0)
     {
         Length = N;
-        if (Length > PcDiskReadBufferSize)
-            Length = PcDiskReadBufferSize;
+        if (Length > DiskReadBufferSize)
+            Length = DiskReadBufferSize;
         Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
         ret = MachDiskReadLogicalSectors(
                   Context->DriveNumber,
                   Context->SectorNumber + Context->SectorOffset + i,
                   Sectors,
-                  (PVOID)DISKREADBUFFER);
+                  DiskReadBuffer);
         if (!ret)
             return EIO;
-        RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
+        RtlCopyMemory(Ptr, DiskReadBuffer, Length);
         Ptr += Length;
         *Count += Length;
         N -= Length;
@@ -257,14 +257,14 @@
     PARTITION_TABLE_ENTRY PartitionTableEntry;
 
     /* Read the MBR */
-    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
+    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
     {
         ERR("Reading MBR failed\n");
         return;
     }
 
-    Buffer = (ULONG*)DISKREADBUFFER;
-    Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
+    Buffer = (ULONG*)DiskReadBuffer;
+    Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
 
     Signature =  Mbr->Signature;
     TRACE("Signature: %x\n", Signature);
@@ -351,13 +351,13 @@
         * harddisks. So, we set the buffer to known contents first, then try to
         * read. If the BIOS reports success but the buffer contents haven't
         * changed then we fail anyway */
-    memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
-    while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
+    memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
+    while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
     {
         Changed = FALSE;
-        for (i = 0; ! Changed && i < PcDiskReadBufferSize; i++)
+        for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
         {
-            Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
+            Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
         }
         if (! Changed)
         {
@@ -366,7 +366,7 @@
             break;
         }
         DiskCount++;
-        memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
+        memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
     }
     DiskReportError(TRUE);
     TRACE("BIOS reports %d harddisk%s\n",

Modified: trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -119,13 +119,13 @@
     }
 
     // Now try to read in the block
-    if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
+    if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer))
     {
         FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA);
         FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
         return NULL;
     }
-    RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
+    RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
 
     // Add it to our list of blocks managed by the cache
     InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);

Modified: trunk/reactos/boot/freeldr/freeldr/disk/partition.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/partition.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/disk/partition.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/disk/partition.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -202,11 +202,11 @@
     ULONG        Index;
 
     // Read master boot record
-    if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
-    {
-        return FALSE;
-    }
-    RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD));
+    if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
+    {
+        return FALSE;
+    }
+    RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD));
 
 
     TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);

Modified: trunk/reactos/boot/freeldr/freeldr/fs/ext2.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/fs/ext2.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/fs/ext2.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/fs/ext2.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -569,8 +569,8 @@
     //{
     //    return FALSE;
     //}
-    //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER);
-    //RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
+    //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, DiskReadBuffer);
+    //RtlCopyMemory(Buffer, DiskReadBuffer, SectorCount * DiskGeometry.BytesPerSector);
     //return ReturnValue;
 
     return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
@@ -607,11 +607,11 @@
 
     // Now try to read the super block
     // If this fails then abort
-    if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER))
-    {
-        return FALSE;
-    }
-    RtlCopyMemory(Ext2SuperBlock, (PVOID)((ULONG_PTR)DISKREADBUFFER + 1024), 1024);
+    if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer))
+    {
+        return FALSE;
+    }
+    RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024);
 
     TRACE("Dumping super block:\n");
     TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -35,4 +35,4 @@
 extern ULONG SecondLevelIcacheFillSize;
 
 extern ULONG gDiskReadBuffer, gFileSysBuffer;
-#define DISKREADBUFFER gDiskReadBuffer
+#define DiskReadBuffer gDiskReadBuffer

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -63,6 +63,5 @@
 
 extern BIOS_MEMORY_MAP PcBiosMemoryMap[];
 extern ULONG PcBiosMapCount;
-extern ULONG PcDiskReadBufferSize;
 
 /* EOF */

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -4,11 +4,11 @@
 #endif
 
 /* Memory layout */
-//#ifdef _M_AMD64
+#ifdef _M_AMD64
 #define PML4_ADDRESS        HEX(1000) /* One page PML4 page table */
 #define PDP_ADDRESS         HEX(2000) /* One page PDP page table */
 #define PD_ADDRESS          HEX(3000) /* One page PD page table */
-//#endif
+#endif
 #define BIOSCALLBUFFER      HEX(4000) /* Buffer to store temporary data for any Int386() call */
 #define STACK16ADDR         HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
 #define BSS_START           HEX(6F00)
@@ -16,15 +16,13 @@
 #define STACKADDR           HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or 0xF000 */
 #define FREELDR_BASE        HEX(F800)
 #define FREELDR_PE_BASE    HEX(10000)
-#define DISKREADBUFFER     HEX(8E000) /* Buffer to store data read in from the disk via the BIOS */
-/* 9F000- 9FFFF is reserved for the EBDA */
+#define MEMORY_MARGIN      HEX(90000) /* We need this much memory */
 
 #define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
 #define BIOSCALLBUFOFFSET   HEX(0000) /* Buffer to store temporary data for any Int386() call */
 #define BIOSCALLBUFSIZE     PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */
-#define MAX_FREELDR_PE_SIZE (DISKREADBUFFER - FREELDR_PE_BASE)
-#define MIN_DISKREADBUFFER_SIZE HEX(1000)
-#define MAX_DISKREADBUFFER_SIZE HEX(C000)
+#define MAX_FREELDR_PE_SIZE (MEMORY_MARGIN - FREELDR_PE_BASE - PAGE_SIZE)
+#define MAX_DISKREADBUFFER_SIZE HEX(10000)
 
 /* These addresses specify the realmode "BSS section" layout */
 #define BSS_RealModeEntry        (BSS_START +  0)

Modified: trunk/reactos/boot/freeldr/freeldr/include/disk.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/disk.h?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/disk.h	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/disk.h	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -125,6 +125,8 @@
 VOID    DiskStopFloppyMotor(VOID);    // Implemented in i386disk.c
 extern UCHAR FrldrBootDrive;
 extern ULONG FrldrBootPartition;
+extern PVOID DiskReadBuffer;
+extern SIZE_T DiskReadBufferSize;
 
 BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size);
 

Modified: trunk/reactos/boot/freeldr/freeldr/include/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/mm.h?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/mm.h	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/mm.h	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -123,6 +123,7 @@
 
 extern PVOID FrLdrDefaultHeap;
 extern PVOID FrLdrTempHeap;
+extern SIZE_T FrLdrImageSize;
 
 PVOID
 FrLdrHeapCreate(

Modified: trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/mm/meminit.c?rev=66087&r1=66086&r2=66087&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/mm/meminit.c	[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/mm/meminit.c	[iso-8859-1] Sun Jan 25 23:24:27 2015
@@ -23,6 +23,17 @@
 
 DBG_DEFAULT_CHANNEL(MEMORY);
 
+PVOID    PageLookupTableAddress = NULL;
+PFN_NUMBER TotalPagesInLookupTable = 0;
+PFN_NUMBER FreePagesInLookupTable = 0;
+PFN_NUMBER LastFreePageHint = 0;
+PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
+PFN_NUMBER MmHighestPhysicalPage = 0;
+
+PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
+ULONG BiosMemoryMapEntryCount;
+SIZE_T FrLdrImageSize;
+
 #if DBG
 typedef struct
 {
@@ -50,17 +61,42 @@
     { LoaderReserve, "Reserve" },
 };
 ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
+
+PCSTR
+MmGetSystemMemoryMapTypeString(
+    TYPE_OF_MEMORY Type)
+{
+    ULONG Index;
+
+    for (Index = 1; Index < MemoryTypeCount; Index++)
+    {
+        if (MemoryTypeArray[Index].Type == Type)
+        {
+            return MemoryTypeArray[Index].TypeString;
+        }
+    }
+
+    return MemoryTypeArray[0].TypeString;
+}
+
+VOID
+DbgDumpMemoryMap(
+    PFREELDR_MEMORY_DESCRIPTOR List)
+{
+    ULONG i;
+
+    DbgPrint("Dumping Memory map:\n");
+    for (i = 0; List[i].PageCount != 0; i++)
+    {
+        DbgPrint("%02d %08x - %08x: %s\n",
+                 i,
+                 List[i].BasePage * PAGE_SIZE,
+                 (List[i].BasePage + List[i].PageCount) * PAGE_SIZE,
+                 MmGetSystemMemoryMapTypeString(List[i].MemoryType));
+    }
+    DbgPrint("\n");
+}
 #endif
-
-PVOID    PageLookupTableAddress = NULL;
-PFN_NUMBER TotalPagesInLookupTable = 0;
-PFN_NUMBER FreePagesInLookupTable = 0;
-PFN_NUMBER LastFreePageHint = 0;
-PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
-PFN_NUMBER MmHighestPhysicalPage = 0;
-
-PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
-ULONG BiosMemoryMapEntryCount;
 
 ULONG
 AddMemoryDescriptor(
@@ -70,78 +106,117 @@
     IN PFN_NUMBER PageCount,
     IN TYPE_OF_MEMORY MemoryType)
 {
-    ULONG i, c;
-    PFN_NUMBER NextBase;
-    TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
-          BasePage, BasePage + PageCount, PageCount);
-
-    /* Scan through all existing descriptors */
-    for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
-    {
-        /* Count entries completely below the new range */
-        if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
-    }
-
-    /* Check if the list is full */
-    if (c >= MaxCount) return c;
-
-    /* Is there an existing descriptor starting before the new range */
-    while ((i < c) && (List[i].BasePage <= BasePage))
-    {
-        /* The end of the existing one is the minimum for the new range */
-        NextBase = List[i].BasePage + List[i].PageCount;
-
-        /* Bail out, if everything is trimmed away */
-        if ((BasePage + PageCount) <= NextBase) return c;
-
-        /* Trim the naew range at the lower end */
-        PageCount -= (NextBase - BasePage);
-        BasePage = NextBase;
-
-        /* Go to the next entry and repeat */
-        i++;
-    }
-
-    ASSERT(PageCount > 0);
-
-    /* Are there still entries above? */
-    if (i < c)
-    {
-        /* Shift the following entries one up */
-        RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0]));
-
-        /* Insert the new range */
-        List[i].BasePage = BasePage;
-        List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage);
-        List[i].MemoryType = MemoryType;
-        c++;
-
-        TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n",
-              i, List[i].BasePage, List[i].PageCount);
-
-        /* Check if the range was trimmed */
-        if (PageCount > List[i].PageCount)
-        {
-            /* Recursively process the trimmed part */
-            c = AddMemoryDescriptor(List,
-                                    MaxCount,
-                                    BasePage + List[i].PageCount,
-                                    PageCount - List[i].PageCount,
-                                    MemoryType);
-        }
-    }
-    else
-    {
-        /* We can simply add the range here */
-        TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount);
-        List[i].BasePage = BasePage;
-        List[i].PageCount = PageCount;
-        List[i].MemoryType = MemoryType;
-        c++;
-    }
-
-    /* Return the new count */
-    return c;
+    ULONG Index, DescriptCount;
+    PFN_NUMBER EndPage;
+    TRACE("AddMemoryDescriptor(0x%Ix, 0x%Ix, %u)\n",
+          BasePage, PageCount, MemoryType);
+
+    EndPage = BasePage + PageCount;
+
+    /* Skip over all descriptor below the new range */
+    Index = 0;
+    while ((List[Index].PageCount != 0) &&
+           ((List[Index].BasePage + List[Index].PageCount) <= BasePage))
+    {
+        Index++;
+    }
+
+    /* Count the descriptors */
+    DescriptCount = Index;
+    while (List[DescriptCount].PageCount != 0)
+    {
+        DescriptCount++;
+    }
+
+    /* Check if the existing range conflicts with the new range */
+    while ((List[Index].PageCount != 0) &&
+           (List[Index].BasePage < EndPage))
+    {
+        TRACE("AddMemoryDescriptor conflict @%lu: new=[%lx:%lx], existing=[%lx,%lx]\n",
+              Index, BasePage, PageCount, List[Index].BasePage, List[Index].PageCount);
+
+        /*
+         * We have 4 overlapping cases:
+         *
+         * Case              (a)       (b)       (c)       (d)
+         * Existing range  |---|     |-----|    |---|      |---|
+         * New range         |---|    |---|    |-----|   |---|
+         *
+         */
+
+        /* Check if the existing range starts before the new range (a)/(b) */
+        if (List[Index].BasePage < BasePage)
+        {
+            /* Check if the existing range extends beyond the new range (b) */
+            if (List[Index].BasePage + List[Index].PageCount > EndPage)
+            {
+                /* Split the descriptor */
+                RtlMoveMemory(&List[Index + 1],
+                              &List[Index],
+                              (DescriptCount - Index) * sizeof(List[0]));
+                List[Index + 1].BasePage = EndPage;
+                List[Index + 1].PageCount = List[Index].BasePage +
+                                            List[Index].PageCount -
+                                            List[Index + 1].BasePage;
+                List[Index].PageCount = BasePage - List[Index].BasePage;
+                Index++;
+                DescriptCount++;
+                break;
+            }
+            else
+            {
+                /* Crop the existing range and continue with the next range */
+                List[Index].PageCount = BasePage - List[Index].BasePage;
+                Index++;
+            }
+        }
+        /* Check if the existing range is fully covered by the new range (c) */
+        else if ((List[Index].BasePage + List[Index].PageCount) <=
+                 EndPage)
+        {
+            /* Delete this descriptor */
+            RtlMoveMemory(&List[Index],
+                          &List[Index + 1],
+                          (DescriptCount - Index) * sizeof(List[0]));
+            DescriptCount--;
+        }
+        /* Otherwise the existing range ends after the new range (d) */
+        else
+        {
+            /* Crop the existing range at the start and bail out */
+            List[Index].PageCount -= EndPage - List[Index].BasePage;
+            List[Index].BasePage = EndPage;
+            break;
+        }
+    }
+
+    /* Make sure we can still add a new descriptor */
+    if (DescriptCount >= MaxCount)
+    {
+        FrLdrBugCheckWithMessage(
+            MEMORY_INIT_FAILURE,
+            __FILE__,
+            __LINE__,
+            "Ran out of static memory descriptors!");
+    }
+
+    /* Insert the new descriptor */
+    if (Index < DescriptCount)
+    {
+        RtlMoveMemory(&List[Index + 1],
+                      &List[Index],
+                      (DescriptCount - Index) * sizeof(List[0]));
+    }
+
+    List[Index].BasePage = BasePage;
+    List[Index].PageCount = PageCount;
+    List[Index].MemoryType = MemoryType;
+    DescriptCount++;
+
+#ifdef DBG
+    DbgDumpMemoryMap(List);
+#endif
+    return DescriptCount;
 }
 
 const FREELDR_MEMORY_DESCRIPTOR*
@@ -230,6 +305,9 @@
             OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE,
             OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment);
     }
+
+    /* Calculate the full image size */
+    FrLdrImageSize = (ULONG_PTR)&__ImageBase + OptionalHeader->SizeOfImage - FREELDR_BASE;
 }
 
 BOOLEAN MmInitializeMemoryManager(VOID)
@@ -287,22 +365,6 @@
     return TRUE;
 }
 
-#if DBG
-PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
-{
-    ULONG        Index;
-
-    for (Index=1; Index<MemoryTypeCount; Index++)
-    {
-        if (MemoryTypeArray[Index].Type == Type)
-        {
-            return MemoryTypeArray[Index].TypeString;
-        }
-    }
-
-    return MemoryTypeArray[0].TypeString;
-}
-#endif
 
 PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
 {




More information about the Ros-diffs mailing list