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=3... ============================================================================== --- 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=... ============================================================================== --- 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); }