[ros-diffs] [ros-arm-bringup] 32369: 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.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Fri Feb 15 01:31:19 CET 2008


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=32369&r1=32368&r2=32369&view=diff
==============================================================================
--- 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=32369&r1=32368&r2=32369&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list