From 63cd339c0c50bee7ed5b10195a495ec36839967f Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Fri, 15 Feb 2008 01:19:46 +0000 Subject: [PATCH] Get rid of complete hack that MmInitializePageList was, and use the ARC Memory Descriptor Tree instead. No more magical assumptions about page numbers. No more BIOS Memory Map from FreeLDR. No more hard-coded/static addresses being pased from the bowels of FreeLDR to the kernel. "Oh my God, I can't believe this is real." We can now continue the ARM port since the ARM port uses real ARC memory descriptors and not the completely hacked up pages the kernel was previously crossing its fingers to get. As a side effect, this probably unblocks the final hurdle to get ReactOS booted by NTLDR. svn path=/trunk/; revision=32372 --- reactos/ntoskrnl/include/internal/mm.h | 7 +- reactos/ntoskrnl/ke/freeldr.c | 23 --- reactos/ntoskrnl/ke/i386/kiinit.c | 2 +- reactos/ntoskrnl/mm/freelist.c | 196 +++++++------------------ reactos/ntoskrnl/mm/mminit.c | 23 +-- 5 files changed, 60 insertions(+), 191 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 576e58c63a4..b034db263f3 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -21,7 +21,6 @@ extern ULONG MmPagedPoolSize; extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor; extern ULONG MmHighestPhysicalPage; extern PVOID MmPfnDatabase; -extern ULONG_PTR MiKSeg0Start, MiKSeg0End; struct _KTRAP_FRAME; struct _EPROCESS; @@ -560,8 +559,7 @@ MiShutdownMemoryManager(VOID); VOID NTAPI MmInit1( - PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount + VOID ); BOOLEAN @@ -968,8 +966,7 @@ MmGetLockCountPage(PFN_TYPE Page); VOID NTAPI MmInitializePageList( - PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount + VOID ); PFN_TYPE diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 13a04df35a1..1558700629f 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -29,11 +29,6 @@ typedef struct _BIOS_MEMORY_DESCRIPTOR /* GLOBALS *******************************************************************/ -/* FreeLDR Memory Data */ -ULONG_PTR MmFreeLdrFirstKrnlPhysAddr, MmFreeLdrLastKrnlPhysAddr; -ULONG_PTR MmFreeLdrLastKernelAddress; -ULONG MmFreeLdrPageDirectoryEnd; - /* FreeLDR Loader Data */ PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock; BOOLEAN AcpiTableDetected; @@ -925,8 +920,6 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* 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; @@ -1288,22 +1281,6 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Save pointer to ROS Block */ KeRosLoaderBlock = LoaderBlock; - MmFreeLdrLastKernelAddress = PAGE_ROUND_UP(KeRosLoaderBlock-> - ModsAddr[KeRosLoaderBlock-> - ModsCount - 1]. - ModEnd); -#if defined(_M_PPC) - MmFreeLdrFirstKrnlPhysAddr = KeRosLoaderBlock->ModsAddr[0].ModStart; - MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress; - MmFreeLdrLastKernelAddress = 0x80800000 + KeRosLoaderBlock->ModsAddr[KeRosLoaderBlock->ModsCount - 1].ModEnd - MmFreeLdrFirstKrnlPhysAddr; - DbgPrint("kernel phys = %08x-%08x\n", - MmFreeLdrFirstKrnlPhysAddr, - MmFreeLdrLastKrnlPhysAddr); -#else - MmFreeLdrFirstKrnlPhysAddr = KeRosLoaderBlock->ModsAddr[0].ModStart - - KSEG0_BASE; - MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - KSEG0_BASE; -#endif /* Save memory manager data */ KeMemoryMapRangeCount = 0; diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index d47c43cb512..393904022f9 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -537,7 +537,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess; /* Initialize Kernel Memory Address Space */ - MmInit1(KeMemoryMap, KeMemoryMapRangeCount); + MmInit1(); /* Set basic CPU Features that user mode can read */ SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 40535d29a36..4725ceaf91f 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -237,63 +237,17 @@ MmGetContinuousPages(ULONG NumberOfBytes, return 0; } - -BOOLEAN -NTAPI -MiIsPfnRam(PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount, - PFN_TYPE Pfn) -{ - BOOLEAN IsUsable; - LARGE_INTEGER BaseAddress; - LARGE_INTEGER EndAddress; - ULONG i; - if (BIOSMemoryMap != NULL && AddressRangeCount > 0) - { - IsUsable = FALSE; - for (i = 0; i < AddressRangeCount; i++) - { - BaseAddress.u.LowPart = BIOSMemoryMap[i].BaseAddrLow; - BaseAddress.u.HighPart = BIOSMemoryMap[i].BaseAddrHigh; - EndAddress.u.LowPart = BIOSMemoryMap[i].LengthLow; - EndAddress.u.HighPart = BIOSMemoryMap[i].LengthHigh; - EndAddress.QuadPart += BaseAddress.QuadPart; - BaseAddress.QuadPart = PAGE_ROUND_DOWN(BaseAddress.QuadPart); - EndAddress.QuadPart = PAGE_ROUND_UP(EndAddress.QuadPart); - - if ((BaseAddress.QuadPart >> PAGE_SHIFT) <= Pfn && - Pfn < (EndAddress.QuadPart >> PAGE_SHIFT)) - { - if (BIOSMemoryMap[i].Type == 1) - { - IsUsable = TRUE; - } - else - { - return FALSE; - } - } - } - return IsUsable; - } - return TRUE; -} - VOID NTAPI -MmInitializePageList(IN PADDRESS_RANGE BIOSMemoryMap, - IN ULONG AddressRangeCount) +MmInitializePageList(VOID) { 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; + PLIST_ENTRY NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR Md; /* Initialize the page lists */ KeInitializeSpinLock(&PageListLock); @@ -345,113 +299,73 @@ MmInitializePageList(IN PADDRESS_RANGE BIOSMemoryMap, 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)) + /* Loop the memory descriptors */ + for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; + NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; + NextEntry = NextEntry->Flink) + { + /* Get the descriptor */ + Md = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Skip bad memory */ + if ((Md->MemoryType == LoaderFirmwarePermanent) || + (Md->MemoryType == LoaderBBTMemory) || + (Md->MemoryType == LoaderSpecialMemory) || + (Md->MemoryType == LoaderBad)) { - /* Apply assumptions that all computers are built the same way */ - if (i == 0) + /* Loop every page part of the block but valid in the database */ + for (i = 0; i < Md->PageCount; i++) { - /* Page 0 is reserved for the IVT */ - MmPageArray[i] = UsedPage; + /* Skip memory we ignore completely */ + if ((Md->BasePage + i) > MmPageArraySize) break; + + /* These are pages reserved by the BIOS/ROMs */ + MmPageArray[Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; + MmPageArray[Md->BasePage + i].Flags.Consumer = MC_NPPOOL; MmStats.NrSystemPages++; } - else if (i == 1) + } + else if ((Md->MemoryType == LoaderFree) || + (Md->MemoryType == LoaderLoadedProgram) || + (Md->MemoryType == LoaderFirmwareTemporary) || + (Md->MemoryType == LoaderOsloaderStack)) + { + /* Loop every page part of the block */ + for (i = 0; i < Md->PageCount; i++) { - /* 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; + /* Mark it as a free page */ + MmPageArray[Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE; InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); + &MmPageArray[Md->BasePage + i].ListEntry); UnzeroedPageCount++; - MmStats.NrFreePages++; + 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++; + /* Loop every page part of the block */ + for (i = 0; i < Md->PageCount; i++) + { + /* Everything else is used memory */ + MmPageArray[Md->BasePage + i] = UsedPage; + MmStats.NrSystemPages++; + } } } + /* Finally handle the pages describing the PFN database themselves */ + for (i = (MiFreeDescriptor->BasePage + MiFreeDescriptor->PageCount); + i <= MmPageArraySize; + i++) + { + /* Mark them as used kernel memory */ + MmPageArray[i] = UsedPage; + MmStats.NrSystemPages++; + } + KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 976dc0b5e71..5274c41e1b5 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -275,23 +275,6 @@ MiDbgKernelLayout(VOID) "Paged pool region"); } -VOID -NTAPI -MiDbgDumpBiosMap(IN PADDRESS_RANGE BIOSMemoryMap, - IN ULONG AddressRangeCount) -{ - ULONG i; - - DPRINT1("Base\t\tLength\t\tType\n"); - for (i = 0; i < AddressRangeCount; i++) - { - DPRINT1("%08lX\t%08lX\t%d\n", - BIOSMemoryMap[i].BaseAddrLow, - BIOSMemoryMap[i].LengthLow, - BIOSMemoryMap[i].Type); - } -} - VOID NTAPI MiDbgDumpMemoryDescriptors(VOID) @@ -342,14 +325,12 @@ MiGetLastKernelAddress(VOID) VOID INIT_FUNCTION NTAPI -MmInit1(IN PADDRESS_RANGE BIOSMemoryMap, - IN ULONG AddressRangeCount) +MmInit1(VOID) { PLDR_DATA_TABLE_ENTRY LdrEntry; /* Dump memory descriptors */ if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); - if (MiDbgEnableMdDump) MiDbgDumpBiosMap(BIOSMemoryMap, AddressRangeCount); /* Set the page directory */ PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory(); @@ -419,7 +400,7 @@ MmInit1(IN PADDRESS_RANGE BIOSMemoryMap, MiDbgKernelLayout(); /* Initialize the page list */ - MmInitializePageList(BIOSMemoryMap, AddressRangeCount); + MmInitializePageList(); /* Unmap low memory */ MmDeletePageTable(NULL, 0);