- 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.

svn path=/trunk/; revision=32386
This commit is contained in:
Aleksey Bragin
2008-02-16 14:56:56 +00:00
parent 6fc7a4d3a5
commit d9fead36b6
2 changed files with 203 additions and 5 deletions
+4
View File
@@ -21,6 +21,8 @@
#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
#endif
ULONG MmFreeLdrPageDirectoryEnd;
typedef struct _BIOS_MEMORY_DESCRIPTOR
{
ULONG BlockBase;
@@ -920,6 +922,8 @@ 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;
+199 -5
View File
@@ -251,6 +251,7 @@ MmAllocEarlyPage(VOID)
return Pfn;
}
#if 0
VOID
NTAPI
MmInitializePageList(VOID)
@@ -312,8 +313,8 @@ MmInitializePageList(VOID)
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 @@ MmInitializePageList(VOID)
Md = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
/* Skip bad memory */
if ((Md->MemoryType == LoaderFirmwarePermanent) ||
(Md->MemoryType == LoaderBBTMemory) ||
@@ -354,7 +355,7 @@ MmInitializePageList(VOID)
InsertTailList(&FreeUnzeroedPageListHead,
&MmPageArray[Md->BasePage + i].ListEntry);
UnzeroedPageCount++;
MmStats.NrFreePages++;
MmStats.NrFreePages++;
}
}
else
@@ -380,11 +381,204 @@ MmInitializePageList(VOID)
}
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);
}
VOID
NTAPI