Author: ros-arm-bringup
Date: Fri Feb 15 03:31:18 2008
New Revision: 32369
URL:
http://svn.reactos.org/svn/reactos?rev=32369&view=rev
Log:
Fixed some bugs we introduced by incorrectly double-accounting the PFN database. The
database is *virtually* continous and follows the kernel address region, but not
physically -- physically, it is at the very far end of memory.
Unfortunately, fixing this bug now caused any unused memory in the FreeLDR-mapped region
of 6MB to appear...well...unused. This would normally be a good thing, except ReactOS
started crashing.
We fixed it by applying the Glorious Hack. See freelist.c:359.
Modified:
trunk/reactos/ntoskrnl/mm/freelist.c
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c Fri Feb 15 03:31:18 2008
@@ -356,6 +356,22 @@
KernelPageStart = KernelStart / PAGE_SIZE;
KernelPageEnd = KernelEnd / PAGE_SIZE;
+ // Glorious Hack:
+ // The kernel seems to crash if the region of memory that FreeLDR maps
+ // (those evil 6MB) is not *entirely* marked "in use", even though only
+ // 3 or 4MB of it may actually be in use.
+ // This wasn't noticed before, because the PFN database pages which are
+ // *VIRTUALLY* continous after the kernel end were also marked as
+ // *PHYSICALLY* continous (even though they were allocated at the very far
+ // end of physical memory).
+ //
+ // So we'll simply gobble up whatever is left of what FreeLDR mapped.
+ //
+ // PS. This is really sinister
+ //
+ KernelEnd += (KernelStart + 0x600000) - KernelEnd;
+ KernelPageEnd = KernelEnd / PAGE_SIZE;
+
/* Loop every page on the system */
for (i = 0; i <= MmPageArraySize; i++)
{
@@ -437,6 +453,7 @@
KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
+ DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages);
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages +
MmStats.NrUserPages;
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
}
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=3…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c Fri Feb 15 03:31:18 2008
@@ -53,6 +53,7 @@
ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage;
ULONG_PTR MiKSeg0Start, MiKSeg0End;
PVOID MmPfnDatabase;
+ULONG_PTR MmPfnDatabaseEnd;
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
extern KMUTANT MmSystemLoadLock;
BOOLEAN MiDbgEnableMdDump =
@@ -257,14 +258,14 @@
KSEG0_BASE, MiKSeg0Start,
"Undefined region");
DPRINT1("0x%p - 0x%p\t%s\n",
- MiKSeg0Start, MmPfnDatabase,
+ MiKSeg0Start, MiKSeg0End,
"FreeLDR Kernel mapping region");
DPRINT1("0x%p - 0x%p\t%s\n",
- MmPfnDatabase, MiKSeg0End,
+ MmPfnDatabase, MmPfnDatabaseEnd,
"PFN Database region");
- if (MiKSeg0End != (ULONG_PTR)MiNonPagedPoolStart)
+ if (MmPfnDatabaseEnd != (ULONG_PTR)MiNonPagedPoolStart)
DPRINT1("0x%p - 0x%p\t%s\n",
- MiKSeg0End, MiNonPagedPoolStart,
+ MmPfnDatabaseEnd, MiNonPagedPoolStart,
"Remaining FreeLDR mapping");
DPRINT1("0x%p - 0x%p\t%s\n",
MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength,
@@ -347,7 +348,7 @@
PLDR_DATA_TABLE_ENTRY LdrEntry;
/* Dump memory descriptors */
- if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
+ if (TRUE) MiDbgDumpMemoryDescriptors();
if (MiDbgEnableMdDump) MiDbgDumpBiosMap(BIOSMemoryMap, AddressRangeCount);
/* Set the page directory */
@@ -386,8 +387,8 @@
/* We'll put the PFN array right after the loaded modules */
MmPfnDatabase = (PVOID)MiKSeg0End;
- MiKSeg0End += MmHighestPhysicalPage * sizeof(PHYSICAL_PAGE);
- MiKSeg0End = PAGE_ROUND_UP(MiKSeg0End);
+ MmPfnDatabaseEnd = (ULONG_PTR)MmPfnDatabase + (MmHighestPhysicalPage *
sizeof(PHYSICAL_PAGE));
+ MmPfnDatabaseEnd = PAGE_ROUND_UP(MmPfnDatabaseEnd);
/*
* FreeLDR maps 6MB starting at the kernel base address, followed by the
@@ -395,15 +396,15 @@
* then choose the end of the FreeLDR block. If it does go past the FreeLDR
* allocation, then choose the next PAGE_SIZE boundary.
*/
- if (MiKSeg0End < (MiKSeg0Start + 0x600000))
+ if ((ULONG_PTR)MmPfnDatabaseEnd < (MiKSeg0Start + 0x600000))
{
/* Use the first memory following FreeLDR's 6MB mapping */
- MiNonPagedPoolStart = (PVOID)PAGE_ROUND_UP(MiKSeg0Start + 0x600000);
+ MiNonPagedPoolStart = (PVOID)((ULONG_PTR)MiKSeg0Start + 0x600000);
}
else
{
/* Use the next free available page */
- MiNonPagedPoolStart = (PVOID)MiKSeg0End;
+ MiNonPagedPoolStart = (PVOID)MmPfnDatabaseEnd;
}
/* Length of non-paged pool */