mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 14:45:06 +00:00
Review and fix the buildingg and mapping of boot-time kernel address space.
The selection of the non-paged pool base address was broken (ion's comment was correct, but his implementation was not) -- NP pool now follows the PFN, or end of FreeLDR mapping area. There was no reason to put paged pool at a 4MB boundary away from NP pool -- it now follows it immediately. Got rid of multiple values which were calculated 3, even 4 times in a row, or even values that were calculated but never used (such as kernel_len). Got rid of the shuffling back and forth of kernel and virtual start/end addresses. A global now keeps track of this, and MmInit1 is now solely responsible for assigning addresses to each kernel region. Added new debug routine to show the kernel regions mapped -- enabled by default for now to visually detect any problems (once ReactOS's drivers go over 6MB, there may be). svn path=/trunk/; revision=32368
This commit is contained in:
parent
6b9215e607
commit
131f74225c
|
@ -18,6 +18,11 @@ extern ULONG MmNumberOfPhysicalPages;
|
||||||
extern PVOID MmPagedPoolBase;
|
extern PVOID MmPagedPoolBase;
|
||||||
extern ULONG MmPagedPoolSize;
|
extern ULONG MmPagedPoolSize;
|
||||||
|
|
||||||
|
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
||||||
|
extern ULONG MmHighestPhysicalPage;
|
||||||
|
extern PVOID MmPfnDatabase;
|
||||||
|
extern ULONG_PTR MiKSeg0Start, MiKSeg0End;
|
||||||
|
|
||||||
struct _KTRAP_FRAME;
|
struct _KTRAP_FRAME;
|
||||||
struct _EPROCESS;
|
struct _EPROCESS;
|
||||||
struct _MM_RMAP_ENTRY;
|
struct _MM_RMAP_ENTRY;
|
||||||
|
@ -261,6 +266,29 @@ typedef struct
|
||||||
ULONG PagingRequestsInLastFifteenMinutes;
|
ULONG PagingRequestsInLastFifteenMinutes;
|
||||||
} MM_STATS;
|
} MM_STATS;
|
||||||
|
|
||||||
|
typedef struct _PHYSICAL_PAGE
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG Type: 2;
|
||||||
|
ULONG Consumer: 3;
|
||||||
|
ULONG Zero: 1;
|
||||||
|
}
|
||||||
|
Flags;
|
||||||
|
ULONG AllFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
SWAPENTRY SavedSwapEntry;
|
||||||
|
ULONG LockCount;
|
||||||
|
ULONG MapCount;
|
||||||
|
struct _MM_RMAP_ENTRY* RmapListHead;
|
||||||
|
}
|
||||||
|
PHYSICAL_PAGE, *PPHYSICAL_PAGE;
|
||||||
|
|
||||||
extern MM_STATS MmStats;
|
extern MM_STATS MmStats;
|
||||||
|
|
||||||
typedef struct _MM_PAGEOP
|
typedef struct _MM_PAGEOP
|
||||||
|
@ -532,12 +560,8 @@ MiShutdownMemoryManager(VOID);
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInit1(
|
MmInit1(
|
||||||
ULONG_PTR FirstKernelPhysAddress,
|
|
||||||
ULONG_PTR LastKernelPhysAddress,
|
|
||||||
ULONG_PTR LastKernelAddress,
|
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
PADDRESS_RANGE BIOSMemoryMap,
|
||||||
ULONG AddressRangeCount,
|
ULONG AddressRangeCount
|
||||||
ULONG MaxMemInMeg
|
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -941,13 +965,9 @@ ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
MmGetLockCountPage(PFN_TYPE Page);
|
MmGetLockCountPage(PFN_TYPE Page);
|
||||||
|
|
||||||
PVOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInitializePageList(
|
MmInitializePageList(
|
||||||
ULONG_PTR FirstPhysKernelAddress,
|
|
||||||
ULONG_PTR LastPhysKernelAddress,
|
|
||||||
ULONG MemorySizeInPages,
|
|
||||||
ULONG_PTR LastKernelBase,
|
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
PADDRESS_RANGE BIOSMemoryMap,
|
||||||
ULONG AddressRangeCount
|
ULONG AddressRangeCount
|
||||||
);
|
);
|
||||||
|
|
|
@ -537,12 +537,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
|
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
|
||||||
|
|
||||||
/* Initialize Kernel Memory Address Space */
|
/* Initialize Kernel Memory Address Space */
|
||||||
MmInit1(MmFreeLdrFirstKrnlPhysAddr,
|
MmInit1(KeMemoryMap, KeMemoryMapRangeCount);
|
||||||
MmFreeLdrLastKrnlPhysAddr,
|
|
||||||
MmFreeLdrLastKernelAddress,
|
|
||||||
KeMemoryMap,
|
|
||||||
KeMemoryMapRangeCount,
|
|
||||||
4096);
|
|
||||||
|
|
||||||
/* Set basic CPU Features that user mode can read */
|
/* Set basic CPU Features that user mode can read */
|
||||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||||
|
|
|
@ -26,29 +26,6 @@
|
||||||
#define MM_PHYSICAL_PAGE_USED (0x2)
|
#define MM_PHYSICAL_PAGE_USED (0x2)
|
||||||
#define MM_PHYSICAL_PAGE_BIOS (0x3)
|
#define MM_PHYSICAL_PAGE_BIOS (0x3)
|
||||||
|
|
||||||
typedef struct _PHYSICAL_PAGE
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
ULONG Type: 2;
|
|
||||||
ULONG Consumer: 3;
|
|
||||||
ULONG Zero: 1;
|
|
||||||
}
|
|
||||||
Flags;
|
|
||||||
ULONG AllFlags;
|
|
||||||
};
|
|
||||||
|
|
||||||
LIST_ENTRY ListEntry;
|
|
||||||
ULONG ReferenceCount;
|
|
||||||
SWAPENTRY SavedSwapEntry;
|
|
||||||
ULONG LockCount;
|
|
||||||
ULONG MapCount;
|
|
||||||
struct _MM_RMAP_ENTRY* RmapListHead;
|
|
||||||
}
|
|
||||||
PHYSICAL_PAGE, *PPHYSICAL_PAGE;
|
|
||||||
|
|
||||||
|
|
||||||
#define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0)
|
#define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0)
|
||||||
|
|
||||||
|
@ -302,15 +279,9 @@ MiIsPfnRam(PADDRESS_RANGE BIOSMemoryMap,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
PVOID
|
|
||||||
INIT_FUNCTION
|
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInitializePageList(IN ULONG_PTR FirstPhysKernelAddress,
|
MmInitializePageList(IN PADDRESS_RANGE BIOSMemoryMap,
|
||||||
IN ULONG_PTR LastPhysKernelAddress,
|
|
||||||
IN ULONG HighestPage,
|
|
||||||
IN ULONG_PTR LastKernelAddress,
|
|
||||||
IN PADDRESS_RANGE BIOSMemoryMap,
|
|
||||||
IN ULONG AddressRangeCount)
|
IN ULONG AddressRangeCount)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -318,11 +289,11 @@ MmInitializePageList(IN ULONG_PTR FirstPhysKernelAddress,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFN_TYPE Pfn = 0;
|
PFN_TYPE Pfn = 0;
|
||||||
PHYSICAL_PAGE UsedPage;
|
PHYSICAL_PAGE UsedPage;
|
||||||
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
|
||||||
ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
|
ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
|
||||||
ULONG PdePageStart, PdePageEnd;
|
ULONG PdePageStart, PdePageEnd;
|
||||||
ULONG VideoPageStart, VideoPageEnd;
|
ULONG VideoPageStart, VideoPageEnd;
|
||||||
ULONG KernelPageStart, KernelPageEnd;
|
ULONG KernelPageStart, KernelPageEnd;
|
||||||
|
ULONG_PTR KernelStart, KernelEnd;
|
||||||
|
|
||||||
/* Initialize the page lists */
|
/* Initialize the page lists */
|
||||||
KeInitializeSpinLock(&PageListLock);
|
KeInitializeSpinLock(&PageListLock);
|
||||||
|
@ -331,13 +302,9 @@ MmInitializePageList(IN ULONG_PTR FirstPhysKernelAddress,
|
||||||
InitializeListHead(&FreeZeroedPageListHead);
|
InitializeListHead(&FreeZeroedPageListHead);
|
||||||
|
|
||||||
/* Set the size and start of the PFN Database */
|
/* Set the size and start of the PFN Database */
|
||||||
MmPageArraySize = HighestPage;
|
MmPageArray = (PHYSICAL_PAGE *)MmPfnDatabase;
|
||||||
MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress;
|
MmPageArraySize = MmHighestPhysicalPage;
|
||||||
Reserved = PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE;
|
Reserved = PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE;
|
||||||
|
|
||||||
/* Update the last kernel address pointers */
|
|
||||||
LastKernelAddress = ((ULONG_PTR)LastKernelAddress + (Reserved * PAGE_SIZE));
|
|
||||||
LastPhysKernelAddress = (ULONG_PTR)LastPhysKernelAddress + (Reserved * PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Loop every page required to hold the PFN database */
|
/* Loop every page required to hold the PFN database */
|
||||||
for (i = 0; i < Reserved; i++)
|
for (i = 0; i < Reserved; i++)
|
||||||
|
@ -380,12 +347,14 @@ MmInitializePageList(IN ULONG_PTR FirstPhysKernelAddress,
|
||||||
UsedPage.MapCount = 1;
|
UsedPage.MapCount = 1;
|
||||||
|
|
||||||
/* We'll be applying a bunch of hacks -- precompute some static values */
|
/* We'll be applying a bunch of hacks -- precompute some static values */
|
||||||
|
KernelStart = MiKSeg0Start - KSEG0_BASE;
|
||||||
|
KernelEnd = MiKSeg0End - KSEG0_BASE;
|
||||||
PdePageStart = PdeStart / PAGE_SIZE;
|
PdePageStart = PdeStart / PAGE_SIZE;
|
||||||
PdePageEnd = MmFreeLdrPageDirectoryEnd / PAGE_SIZE;
|
PdePageEnd = MmFreeLdrPageDirectoryEnd / PAGE_SIZE;
|
||||||
VideoPageStart = 0xA0000 / PAGE_SIZE;
|
VideoPageStart = 0xA0000 / PAGE_SIZE;
|
||||||
VideoPageEnd = 0x100000 / PAGE_SIZE;
|
VideoPageEnd = 0x100000 / PAGE_SIZE;
|
||||||
KernelPageStart = FirstPhysKernelAddress / PAGE_SIZE;
|
KernelPageStart = KernelStart / PAGE_SIZE;
|
||||||
KernelPageEnd = LastPhysKernelAddress / PAGE_SIZE;
|
KernelPageEnd = KernelEnd / PAGE_SIZE;
|
||||||
|
|
||||||
/* Loop every page on the system */
|
/* Loop every page on the system */
|
||||||
for (i = 0; i <= MmPageArraySize; i++)
|
for (i = 0; i <= MmPageArraySize; i++)
|
||||||
|
@ -470,7 +439,6 @@ MmInitializePageList(IN ULONG_PTR FirstPhysKernelAddress,
|
||||||
|
|
||||||
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
|
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
|
||||||
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
|
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
|
||||||
return((PVOID)LastKernelAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -49,7 +49,10 @@ MM_SYSTEMSIZE MmSystemSize = MmSmallSystem;
|
||||||
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
||||||
PVOID MiNonPagedPoolStart;
|
PVOID MiNonPagedPoolStart;
|
||||||
ULONG MiNonPagedPoolLength;
|
ULONG MiNonPagedPoolLength;
|
||||||
|
ULONG MmBootImageSize;
|
||||||
ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage;
|
ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage;
|
||||||
|
ULONG_PTR MiKSeg0Start, MiKSeg0End;
|
||||||
|
PVOID MmPfnDatabase;
|
||||||
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
|
||||||
extern KMUTANT MmSystemLoadLock;
|
extern KMUTANT MmSystemLoadLock;
|
||||||
BOOLEAN MiDbgEnableMdDump =
|
BOOLEAN MiDbgEnableMdDump =
|
||||||
|
@ -71,8 +74,7 @@ MiShutdownMemoryManager(VOID)
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
|
MmInitVirtualMemory()
|
||||||
ULONG KernelLength)
|
|
||||||
{
|
{
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -80,25 +82,10 @@ MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
PMEMORY_AREA MArea;
|
PMEMORY_AREA MArea;
|
||||||
|
|
||||||
DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
|
|
||||||
|
|
||||||
BoundaryAddressMultiple.QuadPart = 0;
|
BoundaryAddressMultiple.QuadPart = 0;
|
||||||
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
|
|
||||||
|
|
||||||
MmInitMemoryAreas();
|
MmInitMemoryAreas();
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeLDR Marks 6MB "in use" at the start of the kernel base,
|
|
||||||
* so start the non-paged pool at a boundary of 6MB from where
|
|
||||||
* the last driver was loaded. This should be the end of the
|
|
||||||
* FreeLDR-marked region.
|
|
||||||
*/
|
|
||||||
MiNonPagedPoolStart = (PVOID)ROUND_UP((ULONG_PTR)LastKernelAddress + PAGE_SIZE, 0x600000);
|
|
||||||
MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE;
|
|
||||||
|
|
||||||
MmPagedPoolBase = (PVOID)ROUND_UP((ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE, 0x400000);
|
|
||||||
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
|
|
||||||
|
|
||||||
DPRINT("NonPagedPool %x - %x, PagedPool %x - %x\n", MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength - 1,
|
DPRINT("NonPagedPool %x - %x, PagedPool %x - %x\n", MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength - 1,
|
||||||
MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize - 1);
|
MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize - 1);
|
||||||
|
|
||||||
|
@ -261,6 +248,32 @@ MiCountFreePagesInLoaderBlock(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiDbgKernelLayout(VOID)
|
||||||
|
{
|
||||||
|
DPRINT1("%8s%12s\t\t%s\n", "Start", "End", "Type");
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
KSEG0_BASE, MiKSeg0Start,
|
||||||
|
"Undefined region");
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
MiKSeg0Start, MmPfnDatabase,
|
||||||
|
"FreeLDR Kernel mapping region");
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
MmPfnDatabase, MiKSeg0End,
|
||||||
|
"PFN Database region");
|
||||||
|
if (MiKSeg0End != (ULONG_PTR)MiNonPagedPoolStart)
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
MiKSeg0End, MiNonPagedPoolStart,
|
||||||
|
"Remaining FreeLDR mapping");
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength,
|
||||||
|
"Non paged pool region");
|
||||||
|
DPRINT1("0x%p - 0x%p\t%s\n",
|
||||||
|
MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
|
||||||
|
"Paged pool region");
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiDbgDumpBiosMap(IN PADDRESS_RANGE BIOSMemoryMap,
|
MiDbgDumpBiosMap(IN PADDRESS_RANGE BIOSMemoryMap,
|
||||||
|
@ -306,7 +319,7 @@ MiGetLastKernelAddress(VOID)
|
||||||
PLIST_ENTRY NextEntry;
|
PLIST_ENTRY NextEntry;
|
||||||
PMEMORY_ALLOCATION_DESCRIPTOR Md;
|
PMEMORY_ALLOCATION_DESCRIPTOR Md;
|
||||||
ULONG_PTR LastKrnlPhysAddr = 0;
|
ULONG_PTR LastKrnlPhysAddr = 0;
|
||||||
|
|
||||||
for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
|
for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
|
||||||
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
|
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
|
||||||
NextEntry = NextEntry->Flink)
|
NextEntry = NextEntry->Flink)
|
||||||
|
@ -320,7 +333,7 @@ MiGetLastKernelAddress(VOID)
|
||||||
LastKrnlPhysAddr = Md->BasePage+Md->PageCount;
|
LastKrnlPhysAddr = Md->BasePage+Md->PageCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to a physical address */
|
/* Convert to a physical address */
|
||||||
return LastKrnlPhysAddr << PAGE_SHIFT;
|
return LastKrnlPhysAddr << PAGE_SHIFT;
|
||||||
}
|
}
|
||||||
|
@ -328,16 +341,11 @@ MiGetLastKernelAddress(VOID)
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInit1(ULONG_PTR FirstKrnlPhysAddr,
|
MmInit1(IN PADDRESS_RANGE BIOSMemoryMap,
|
||||||
ULONG_PTR LastKrnlPhysAddr,
|
IN ULONG AddressRangeCount)
|
||||||
ULONG_PTR LastKernelAddress,
|
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
|
||||||
ULONG AddressRangeCount,
|
|
||||||
ULONG MaxMem)
|
|
||||||
{
|
{
|
||||||
ULONG kernel_len;
|
|
||||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||||
|
|
||||||
/* Dump memory descriptors */
|
/* Dump memory descriptors */
|
||||||
if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
|
if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
|
||||||
if (MiDbgEnableMdDump) MiDbgDumpBiosMap(BIOSMemoryMap, AddressRangeCount);
|
if (MiDbgEnableMdDump) MiDbgDumpBiosMap(BIOSMemoryMap, AddressRangeCount);
|
||||||
|
@ -345,18 +353,9 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
|
||||||
/* Set the page directory */
|
/* Set the page directory */
|
||||||
PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory();
|
PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory();
|
||||||
|
|
||||||
/* NTLDR Hacks */
|
/* Get the size of FreeLDR's image allocations */
|
||||||
if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000;
|
MmBootImageSize = KeLoaderBlock->Extension->LoaderPagesSpanned;
|
||||||
|
MmBootImageSize *= PAGE_SIZE;
|
||||||
/* Get the first physical address */
|
|
||||||
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink,
|
|
||||||
LDR_DATA_TABLE_ENTRY,
|
|
||||||
InLoadOrderLinks);
|
|
||||||
FirstKrnlPhysAddr = (ULONG_PTR)LdrEntry->DllBase - KSEG0_BASE;
|
|
||||||
|
|
||||||
/* Get the last kernel address */
|
|
||||||
LastKrnlPhysAddr = PAGE_ROUND_UP(MiGetLastKernelAddress());
|
|
||||||
LastKernelAddress = LastKrnlPhysAddr | KSEG0_BASE;
|
|
||||||
|
|
||||||
/* Set memory limits */
|
/* Set memory limits */
|
||||||
MmSystemRangeStart = (PVOID)KSEG0_BASE;
|
MmSystemRangeStart = (PVOID)KSEG0_BASE;
|
||||||
|
@ -377,21 +376,55 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
|
||||||
/* Initialize the kernel address space */
|
/* Initialize the kernel address space */
|
||||||
MmInitializeKernelAddressSpace();
|
MmInitializeKernelAddressSpace();
|
||||||
MmInitGlobalKernelPageDirectory();
|
MmInitGlobalKernelPageDirectory();
|
||||||
|
|
||||||
|
/* Get kernel address boundaries */
|
||||||
|
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink,
|
||||||
|
LDR_DATA_TABLE_ENTRY,
|
||||||
|
InLoadOrderLinks);
|
||||||
|
MiKSeg0Start = (ULONG_PTR)LdrEntry->DllBase | KSEG0_BASE;
|
||||||
|
MiKSeg0End = PAGE_ROUND_UP(MiGetLastKernelAddress() | KSEG0_BASE);
|
||||||
|
|
||||||
|
/* We'll put the PFN array right after the loaded modules */
|
||||||
|
MmPfnDatabase = (PVOID)MiKSeg0End;
|
||||||
|
MiKSeg0End += MmHighestPhysicalPage * sizeof(PHYSICAL_PAGE);
|
||||||
|
MiKSeg0End = PAGE_ROUND_UP(MiKSeg0End);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeLDR maps 6MB starting at the kernel base address, followed by the
|
||||||
|
* PFN database. If the PFN database doesn't go over the FreeLDR allocation
|
||||||
|
* then choose the end of the FreeLDR block. If it does go past the FreeLDR
|
||||||
|
* allocation, then choose the next PAGE_SIZE boundary.
|
||||||
|
*/
|
||||||
|
if (MiKSeg0End < (MiKSeg0Start + 0x600000))
|
||||||
|
{
|
||||||
|
/* Use the first memory following FreeLDR's 6MB mapping */
|
||||||
|
MiNonPagedPoolStart = (PVOID)PAGE_ROUND_UP(MiKSeg0Start + 0x600000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use the next free available page */
|
||||||
|
MiNonPagedPoolStart = (PVOID)MiKSeg0End;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Length of non-paged pool */
|
||||||
|
MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE;
|
||||||
|
|
||||||
|
/* Put the paged pool after the non-paged pool */
|
||||||
|
MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MiNonPagedPoolStart +
|
||||||
|
MiNonPagedPoolLength);
|
||||||
|
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
|
||||||
|
|
||||||
|
/* Dump kernel memory layout */
|
||||||
|
MiDbgKernelLayout();
|
||||||
|
|
||||||
/* Initialize the page list */
|
/* Initialize the page list */
|
||||||
LastKernelAddress = (ULONG_PTR)MmInitializePageList(FirstKrnlPhysAddr,
|
MmInitializePageList(BIOSMemoryMap, AddressRangeCount);
|
||||||
LastKrnlPhysAddr,
|
|
||||||
MmHighestPhysicalPage,
|
|
||||||
PAGE_ROUND_UP(LastKernelAddress),
|
|
||||||
BIOSMemoryMap,
|
|
||||||
AddressRangeCount);
|
|
||||||
kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
|
|
||||||
|
|
||||||
/* Unmap low memory */
|
/* Unmap low memory */
|
||||||
MmDeletePageTable(NULL, 0);
|
MmDeletePageTable(NULL, 0);
|
||||||
|
|
||||||
/* Intialize memory areas */
|
/* Intialize memory areas */
|
||||||
MmInitVirtualMemory(LastKernelAddress, kernel_len);
|
MmInitVirtualMemory();
|
||||||
|
|
||||||
/* Initialize MDLs */
|
/* Initialize MDLs */
|
||||||
MmInitializeMdlImplementation();
|
MmInitializeMdlImplementation();
|
||||||
|
|
Loading…
Reference in a new issue