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=32... ============================================================================== --- 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 */