[ros-diffs] [fireball] 32386: - Add a hacked and incorrect (due to absence of checking for BIOS-reserved memory areas) MiInitializePageList from 32371. This allows 1st stage to work, and 2nd stage to work from the first power up. - Real, new, [bugless] MiInitializePageList is #if0-#endif'ed until a problem in it is identified and fixed.

fireball at svn.reactos.org fireball at svn.reactos.org
Sat Feb 16 15:56:57 CET 2008


Author: fireball
Date: Sat Feb 16 17:56:56 2008
New Revision: 32386

URL: http://svn.reactos.org/svn/reactos?rev=32386&view=rev
Log:
- Add a hacked and incorrect (due to absence of checking for BIOS-reserved memory areas) MiInitializePageList from 32371. This allows 1st stage to work, and 2nd stage to work from the first power up.
- Real, new, [bugless] MiInitializePageList is #if0-#endif'ed until a problem in it is identified and fixed.

Modified:
    trunk/reactos/ntoskrnl/ke/freeldr.c
    trunk/reactos/ntoskrnl/mm/freelist.c

Modified: trunk/reactos/ntoskrnl/ke/freeldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/freeldr.c?rev=32386&r1=32385&r2=32386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/freeldr.c (original)
+++ trunk/reactos/ntoskrnl/ke/freeldr.c Sat Feb 16 17:56:56 2008
@@ -20,6 +20,8 @@
 #define KERNEL_RVA(x) RVA(x,KSEG0_BASE)
 #define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
 #endif
+
+ULONG MmFreeLdrPageDirectoryEnd;
 
 typedef struct _BIOS_MEMORY_DESCRIPTOR
 {
@@ -920,6 +922,8 @@
 
     /* First get some kernel-loader globals */
     AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
+    MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd;
+    if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000;
 
     /* Set the NT Loader block and initialize it */
     *NtLoaderBlock = KeLoaderBlock = LoaderBlock = &BldrLoaderBlock;

Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev=32386&r1=32385&r2=32386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c Sat Feb 16 17:56:56 2008
@@ -251,6 +251,7 @@
     return Pfn;
 }
 
+#if 0
 VOID
 NTAPI
 MmInitializePageList(VOID)
@@ -312,8 +313,8 @@
     UsedPage.Flags.Consumer = MC_NPPOOL;
     UsedPage.ReferenceCount = 2;
     UsedPage.MapCount = 1;
-    
-    /* Loop the memory descriptors */   
+
+    /* Loop the memory descriptors */
     for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
          NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
          NextEntry = NextEntry->Flink)
@@ -322,7 +323,7 @@
         Md = CONTAINING_RECORD(NextEntry,
                                MEMORY_ALLOCATION_DESCRIPTOR,
                                ListEntry);
-        
+
         /* Skip bad memory */
         if ((Md->MemoryType == LoaderFirmwarePermanent) ||
             (Md->MemoryType == LoaderBBTMemory) ||
@@ -354,7 +355,7 @@
                 InsertTailList(&FreeUnzeroedPageListHead,
                                &MmPageArray[Md->BasePage + i].ListEntry);
                 UnzeroedPageCount++;
-                MmStats.NrFreePages++;   
+                MmStats.NrFreePages++;
             }
         }
         else
@@ -380,8 +381,201 @@
     }
 
     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);
+}
+#endif
+
+VOID
+NTAPI
+MmInitializePageList()
+{
+    ULONG i;
+    ULONG Reserved;
+    NTSTATUS Status;
+    PFN_TYPE Pfn = 0;
+    PHYSICAL_PAGE UsedPage;
+    ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
+    ULONG PdePageStart, PdePageEnd;
+    ULONG VideoPageStart, VideoPageEnd;
+    ULONG KernelPageStart, KernelPageEnd;
+    ULONG_PTR KernelStart, KernelEnd;
+    extern ULONG MiKSeg0Start, MiKSeg0End, MmFreeLdrPageDirectoryEnd;
+
+    /* Initialize the page lists */
+    KeInitializeSpinLock(&PageListLock);
+    InitializeListHead(&UserPageListHead);
+    InitializeListHead(&FreeUnzeroedPageListHead);
+    InitializeListHead(&FreeZeroedPageListHead);
+
+    DPRINT1("HACK: Using old incorrect MmInitializePageList(). "
+        "Please bugfix the new version and delete this one\n");
+
+    /* Set the size and start of the PFN Database */
+    MmPageArray = (PHYSICAL_PAGE *)MmPfnDatabase;
+    MmPageArraySize = MmHighestPhysicalPage;
+    Reserved = PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE;
+
+    /* Loop every page required to hold the PFN database */
+    for (i = 0; i < Reserved; i++)
+    {
+        PVOID Address = (char*)MmPageArray + (i * PAGE_SIZE);
+
+        /* Check if FreeLDR has already allocated it for us */
+        if (!MmIsPagePresent(NULL, Address))
+        {
+            /* Use one of our highest usable pages */
+            Pfn = MiFreeDescriptor->BasePage + MiFreeDescriptor->PageCount - 1;
+            MiFreeDescriptor->PageCount--;
+            
+            /* Set the PFN */
+            Status = MmCreateVirtualMappingForKernel(Address,
+                                                     PAGE_READWRITE,
+                                                     &Pfn,
+                                                     1);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Unable to create virtual mapping\n");
+                KEBUGCHECK(0);
+            }
+        }
+        else
+        {
+            /* Setting the page protection is necessary to set the global bit */
+            MmSetPageProtect(NULL, Address, PAGE_READWRITE);
+        }
+    }
+
+    /* Clear the PFN database */
+    RtlZeroMemory(MmPageArray, (MmPageArraySize + 1) * sizeof(PHYSICAL_PAGE));
+
+    /* This is what a used page looks like */
+    RtlZeroMemory(&UsedPage, sizeof(UsedPage));
+    UsedPage.Flags.Type = MM_PHYSICAL_PAGE_USED;
+    UsedPage.Flags.Consumer = MC_NPPOOL;
+    UsedPage.ReferenceCount = 2;
+    UsedPage.MapCount = 1;
+
+    /* We'll be applying a bunch of hacks -- precompute some static values */
+    KernelStart = MiKSeg0Start - KSEG0_BASE;
+    KernelEnd = MiKSeg0End - KSEG0_BASE;
+    PdePageStart = PdeStart / PAGE_SIZE;
+    PdePageEnd = MmFreeLdrPageDirectoryEnd / PAGE_SIZE;
+    VideoPageStart = 0xA0000 / PAGE_SIZE;
+    VideoPageEnd = 0x100000 / PAGE_SIZE;
+    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++)
+    {
+        /* Check if it's part of RAM */
+        if (/*MiIsPfnRam(BIOSMemoryMap, AddressRangeCount, i)*/TRUE)
+        {
+            /* Apply assumptions that all computers are built the same way */
+            if (i == 0)
+            {
+                /* Page 0 is reserved for the IVT */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else if (i == 1)
+            {
+                /* Page 1 is reserved for the PCR */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else if (i == 2)
+            {
+                /* Page 2 is reserved for the KUSER_SHARED_DATA */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else if ((i >= PdePageStart) && (i < PdePageEnd))
+            {
+                /* These pages contain the initial FreeLDR PDEs */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else if ((i >= VideoPageStart) && (i < VideoPageEnd))
+            {
+                /*
+                 * These pages are usually for the Video ROM BIOS.
+                 * Supposedly anyway. We'll simply ignore the fact that
+                 * many systems have this area somewhere else entirely
+                 * (which we'll assume to be "free" a couple of lines below)
+                 */
+                MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS;
+                MmPageArray[i].Flags.Consumer = MC_NPPOOL;
+                MmStats.NrSystemPages++;
+            }
+            else if ((i >= KernelPageStart) && (i < KernelPageEnd))
+            {
+                /* These are pages beloning to the kernel */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else if (i >= (MiFreeDescriptor->BasePage + MiFreeDescriptor->PageCount))
+            {
+                /* These are pages we allocated above to hold the PFN DB */
+                MmPageArray[i] = UsedPage;
+                MmStats.NrSystemPages++;
+            }
+            else
+            {
+                /*
+                 * These are supposedly free pages.
+                 * By the way, not all of them are, some contain vital
+                 * FreeLDR data, but since we choose to ignore the Memory
+                 * Descriptor List, why bother, right?
+                 */
+                MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
+                MmPageArray[i].ReferenceCount = 0;
+                InsertTailList(&FreeUnzeroedPageListHead,
+                               &MmPageArray[i].ListEntry);
+                UnzeroedPageCount++;
+                MmStats.NrFreePages++;
+            }
+        }
+        else
+        {
+            /* These are pages reserved by the BIOS/ROMs */
+            MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS;
+            MmPageArray[i].Flags.Consumer = MC_NPPOOL;
+            MmStats.NrSystemPages++;
+        }
+    }
+
+    KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
     DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages);
+    /*
+    DPRINT1("Unzeroed pages: %x\n", UnzeroedPageCount);
+    {
+        ULONG j = 0;
+        for (j=0; j<=MmPageArraySize; j++)
+        {
+            if (j % 0x10 == 0) DbgPrint ("\n0x%x\t", j);
+            DbgPrint("0x%x\t", MmPageArray[j].AllFlags);
+        }
+    }*/
     MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
     MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
 }




More information about the Ros-diffs mailing list