We were looping the memory descriptors in order to find the number of pages that are available to the system, that is to say, your RAM, minus pages that the BIOS said belong to it. This part is good. Next up, we were creating the page array for these pages, up to the highest entry, which we called, the number of pages on the system. This is the problem. Suppose we had 1000 pages somewhere in low memory that were used by the BIOS, we'd now call the total pages RAM - 1000 (correct). However, we'd also set the highest page array entry to RAM - 1000, which is wrong, because esssentially this eats up 10MB of memory, since the top 10MB (which are FREE, usable memory) are never entered into the database. So really, what we want to do is differentiate the TOTAL amount of usable RAM, versus the HIGHEST page that is usable (which is actually what should be the highest entry in the page array). This will reclaim the lost RAM ReactOS has been eating up all these days. But it gets better: eventually, someone noticed ReactOS was eating memory, and added 1MB more to the "total", making the highest entry "1mb higher". This ...kind of... fixes the problem above by giving you one more MB, but what if ReactOS was only eating up 150KB, as was more the case? Then ReactOS would believe that the other 850KB of memory are "Free physical memory", when actually, they're pages that don't even exist. Wow!

Fixed these bugs.

svn path=/trunk/; revision=32359
This commit is contained in:
ReactOS Portable Systems Group 2008-02-14 18:33:38 +00:00
parent 4f337a6db1
commit 7ca0ac88f8
2 changed files with 50 additions and 29 deletions

View file

@ -290,7 +290,7 @@ MmInitializePageList(ULONG_PTR FirstPhysKernelAddress,
ULONG i; ULONG i;
ULONG Reserved; ULONG Reserved;
NTSTATUS Status; NTSTATUS Status;
PFN_TYPE LastPage, Pfn; PFN_TYPE LastPage, Pfn = 0;
ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart; ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
ULONG PdePageStart, PdePageEnd; ULONG PdePageStart, PdePageEnd;
ULONG VideoPageStart, VideoPageEnd; ULONG VideoPageStart, VideoPageEnd;

View file

@ -49,7 +49,7 @@ MM_SYSTEMSIZE MmSystemSize = MmSmallSystem;
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress; PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
PVOID MiNonPagedPoolStart; PVOID MiNonPagedPoolStart;
ULONG MiNonPagedPoolLength; ULONG MiNonPagedPoolLength;
ULONG MmNumberOfPhysicalPages; ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage;
extern KMUTANT MmSystemLoadLock; extern KMUTANT MmSystemLoadLock;
BOOLEAN MiDbgEnableMdDump = BOOLEAN MiDbgEnableMdDump =
#ifdef _ARM_ #ifdef _ARM_
@ -201,13 +201,12 @@ MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
} }
ULONG VOID
NTAPI NTAPI
MiCountFreePagesInLoaderBlock(PLOADER_PARAMETER_BLOCK LoaderBlock) MiCountFreePagesInLoaderBlock(PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PLIST_ENTRY NextEntry; PLIST_ENTRY NextEntry;
PMEMORY_ALLOCATION_DESCRIPTOR Md; PMEMORY_ALLOCATION_DESCRIPTOR Md;
ULONG TotalPages = 0;
for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
@ -215,19 +214,51 @@ MiCountFreePagesInLoaderBlock(PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
if (Md->MemoryType == LoaderBad || /* Skip invisible memory */
Md->MemoryType == LoaderFirmwarePermanent || if ((Md->MemoryType != LoaderFirmwarePermanent) &&
Md->MemoryType == LoaderSpecialMemory || (Md->MemoryType != LoaderSpecialMemory) &&
Md->MemoryType == LoaderBBTMemory) (Md->MemoryType != LoaderHALCachedMemory) &&
(Md->MemoryType != LoaderBBTMemory))
{ {
/* Don't count these blocks */ /* Check if BURNMEM was used */
continue; if (Md->MemoryType != LoaderBad)
{
/* Count this in the total of pages */
MmNumberOfPhysicalPages += Md->PageCount;
}
/* Check if this is the new lowest page */
if (Md->BasePage < MmLowestPhysicalPage)
{
/* Update the lowest page */
MmLowestPhysicalPage = Md->BasePage;
}
/* Check if this is the new highest page */
if ((Md->BasePage + Md->PageCount) > MmHighestPhysicalPage)
{
/* Update the highest page */
MmHighestPhysicalPage = Md->BasePage + Md->PageCount - 1;
}
} }
TotalPages += Md->PageCount;
} }
}
return TotalPages; 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 VOID
@ -269,8 +300,7 @@ MiGetLastKernelAddress(VOID)
Md->MemoryType == LoaderHalCode) Md->MemoryType == LoaderHalCode)
{ {
if (Md->BasePage+Md->PageCount > LastKrnlPhysAddr) if (Md->BasePage+Md->PageCount > LastKrnlPhysAddr)
LastKrnlPhysAddr = Md->BasePage+Md->PageCount; LastKrnlPhysAddr = Md->BasePage+Md->PageCount;
} }
} }
@ -293,6 +323,7 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
/* Dump memory descriptors */ /* Dump memory descriptors */
if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
if (MiDbgEnableMdDump) MiDbgDumpBiosMap(BIOSMemoryMap, AddressRangeCount);
/* Set the page directory */ /* Set the page directory */
PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory(); PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory();
@ -322,19 +353,9 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
RtlZeroMemory(&MmStats, sizeof(MmStats)); RtlZeroMemory(&MmStats, sizeof(MmStats));
/* Count RAM */ /* Count RAM */
MmStats.NrTotalPages = MiCountFreePagesInLoaderBlock(KeLoaderBlock); MiCountFreePagesInLoaderBlock(KeLoaderBlock);
MmNumberOfPhysicalPages = MmStats.NrTotalPages; MmStats.NrTotalPages = MmNumberOfPhysicalPages;
if (!MmStats.NrTotalPages) DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024);
{
DbgPrint("Memory not detected, default to 8 MB\n");
MmStats.NrTotalPages = 2048;
}
else
{
/* HACK: add 1MB for standard memory (not extended). Why? */
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024);
MmStats.NrTotalPages += 256;
}
/* Initialize the kernel address space */ /* Initialize the kernel address space */
MmInitializeKernelAddressSpace(); MmInitializeKernelAddressSpace();
@ -343,7 +364,7 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
/* Initialize the page list */ /* Initialize the page list */
LastKernelAddress = (ULONG_PTR)MmInitializePageList(FirstKrnlPhysAddr, LastKernelAddress = (ULONG_PTR)MmInitializePageList(FirstKrnlPhysAddr,
LastKrnlPhysAddr, LastKrnlPhysAddr,
MmStats.NrTotalPages, MmHighestPhysicalPage,
PAGE_ROUND_UP(LastKernelAddress), PAGE_ROUND_UP(LastKernelAddress),
BIOSMemoryMap, BIOSMemoryMap,
AddressRangeCount); AddressRangeCount);