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.

svn path=/trunk/; revision=32369
This commit is contained in:
ReactOS Portable Systems Group 2008-02-15 00:31:18 +00:00
parent 131f74225c
commit cb5d314ff3
2 changed files with 28 additions and 10 deletions

View file

@ -356,6 +356,22 @@ MmInitializePageList(IN PADDRESS_RANGE BIOSMemoryMap,
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 @@ MmInitializePageList(IN PADDRESS_RANGE BIOSMemoryMap,
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);
}

View file

@ -53,6 +53,7 @@ ULONG MmBootImageSize;
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 @@ MiDbgKernelLayout(VOID)
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 @@ MmInit1(IN PADDRESS_RANGE BIOSMemoryMap,
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 @@ MmInit1(IN PADDRESS_RANGE BIOSMemoryMap,
/* 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 @@ MmInit1(IN PADDRESS_RANGE BIOSMemoryMap,
* 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 */