Author: tkreuzer
Date: Sun Apr 14 18:41:54 2013
New Revision: 58760
URL: http://svn.reactos.org/svn/reactos?rev=58760&view=rev
Log:
[FREELDR]
When generating the memory descriptor list, do not map the pages at the same time, since that requires allocating page tables, which will alter the state of pages, that might already have been processed. Instead map everything beforehand. This has not had any impact on x86, since the pfn database initialization code mindlessly adds all mapped pages as valid, even if they were reported as free by the OS loader. But proper Mm code does not necessarily do this.
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/amd64/winldr.c
trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/amd64/winldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/amd64/winldr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/amd64/winldr.c [iso-8859-1] Sun Apr 14 18:41:54 2013
@@ -183,13 +183,16 @@
}
/* Kernel mapping */
- if (MempMapRangeOfPages(StartPage * PAGE_SIZE + KSEG0_BASE,
- StartPage * PAGE_SIZE,
- NumberOfPages) != NumberOfPages)
+ if (KernelMapping)
{
- ERR("Failed to map pages %ld, %ld\n",
- StartPage, NumberOfPages);
- return FALSE;
+ if (MempMapRangeOfPages(StartPage * PAGE_SIZE + KSEG0_BASE,
+ StartPage * PAGE_SIZE,
+ NumberOfPages) != NumberOfPages)
+ {
+ ERR("Failed to map pages %ld, %ld\n",
+ StartPage, NumberOfPages);
+ return FALSE;
+ }
}
return TRUE;
@@ -343,7 +346,7 @@
/* Disable Interrupts */
_disable();
- /* Re-initialize EFLAGS */
+ /* Re-initalize EFLAGS */
__writeeflags(0);
/* Set the new PML4 */
Modified: trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c [iso-8859-1] Sun Apr 14 18:41:54 2013
@@ -67,30 +67,21 @@
PFN_NUMBER PageCount,
ULONG Type)
{
- BOOLEAN Status = TRUE;
-
TRACE("MempAddMemoryBlock(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
BasePage, PageCount, Type);
- //
- // Check for memory block after 4GB - we don't support it yet
- // Note: Even last page before 4GB limit is not supported
- //
+
+ /* Check for memory block after 4GB - we don't support it yet
+ Note: Even last page before 4GB limit is not supported */
if (BasePage >= MM_MAX_PAGE)
{
- //
- // Just skip this, without even adding to MAD list
- //
+ /* Just skip this, without even adding to MAD list */
return;
}
- //
- // Check if last page is after 4GB limit and shorten this block if needed
- //
+ /* Check if last page is after 4GB limit and shorten this block if needed */
if (BasePage + PageCount > MM_MAX_PAGE)
{
- //
- // shorten this block
- //
+ /* Shorten this block */
PageCount = MM_MAX_PAGE - BasePage;
}
@@ -101,35 +92,29 @@
return;
}
- /* Get rid of the loader heap */
- //if (Type == LoaderOsloaderHeap) Type = LoaderFirmwareTemporary;
-
- //
- // Set Base page, page count and type
- //
+ /* Set Base page, page count and type */
Mad[MadCount].BasePage = BasePage;
Mad[MadCount].PageCount = PageCount;
Mad[MadCount].MemoryType = Type;
- //
- // Add descriptor
- //
+ /* Add descriptor */
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
+}
+
+VOID
+MempSetupPagingForRegion(
+ PFN_NUMBER BasePage,
+ PFN_NUMBER PageCount,
+ ULONG Type)
+{
+ BOOLEAN Status = TRUE;
+
+ TRACE("MempSetupPagingForRegion(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
+ BasePage, PageCount, Type);
/* Make sure we don't map too high */
if (BasePage + PageCount > LoaderPagesSpanned) return;
-
- /* Special handling for page 0 */
- if (BasePage == 0)
- {
- /* If its only one page, ignore it! */
- if (PageCount == 1) return;
-
- /* Otherwise, skip first page */
- BasePage++;
- PageCount--;
- }
switch (Type)
{
@@ -253,6 +238,21 @@
return FALSE;
}
#endif
+
+ /* Before creating the map, we need to map pages to kernel mode */
+ LastPageIndex = 1;
+ LastPageType = MemoryMap[1].PageAllocated;
+ for (i = 2; i < NoEntries; i++)
+ {
+ if ((MemoryMap[i].PageAllocated != LastPageType) ||
+ (i == NoEntries - 1))
+ {
+ MempSetupPagingForRegion(LastPageIndex, i - LastPageIndex, LastPageType);
+ LastPageIndex = i;
+ LastPageType = MemoryMap[i].PageAllocated;
+ }
+ }
+
// Construct a good memory map from what we've got,
// but mark entries which the memory allocation bitmap takes
// as free entries (this is done in order to have the ability