[NTOSKRNL]

- Session space address layout is architecture specific, move its initialization into MiInitializeSesseionSpaceLayout() in architecture specific file
- Use dedicated constants for setting MmSystemRangeStart, MmUserProbeAddress and MmHighestUserAddress isnetad of making assumptions.

svn path=/trunk/; revision=53825
This commit is contained in:
Timo Kreuzer 2011-09-24 08:52:26 +00:00
parent bf4b896e65
commit 0ce2f14276
5 changed files with 148 additions and 286 deletions

View file

@ -11,6 +11,9 @@
#define PAE_PAGE_MASK(x) ((x)&(~0xfffLL))
/* Memory layout base addresses */
#define MI_HIGHEST_USER_ADDRESS (PVOID)0x000007FFFFFEFFFFULL
#define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL
#define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL
#define HYPER_SPACE 0xFFFFF70000000000ULL
#define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
#define MI_SESSION_SPACE_MINIMUM (PVOID)0xFFFFF90000000000ULL

View file

@ -29,10 +29,83 @@ MMPTE DemandZeroPte = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}};
MMPTE PrototypePte = {{(MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) |
PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << PAGE_SHIFT)}};
extern PFN_NUMBER MiNumberOfFreePages;
/* PRIVATE FUNCTIONS **********************************************************/
VOID
NTAPI
INIT_FUNCTION
MiInitializeSessionSpaceLayout()
{
//
// Set the size of session view, pool, and image
//
MmSessionSize = MI_SESSION_SIZE;
MmSessionViewSize = MI_SESSION_VIEW_SIZE;
MmSessionPoolSize = MI_SESSION_POOL_SIZE;
MmSessionImageSize = MI_SESSION_IMAGE_SIZE;
//
// Set the size of system view
//
MmSystemViewSize = MI_SYSTEM_VIEW_SIZE;
//
// This is where it all ends
//
MiSessionImageEnd = (PVOID)PTE_BASE;
//
// This is where we will load Win32k.sys and the video driver
//
MiSessionImageStart = (PVOID)((ULONG_PTR)MiSessionImageEnd -
MmSessionImageSize);
//
// So the view starts right below the session working set (itself below
// the image area)
//
MiSessionViewStart = (PVOID)((ULONG_PTR)MiSessionImageEnd -
MmSessionImageSize -
MI_SESSION_WORKING_SET_SIZE -
MmSessionViewSize);
//
// Session pool follows
//
MiSessionPoolEnd = MiSessionViewStart;
MiSessionPoolStart = (PVOID)((ULONG_PTR)MiSessionPoolEnd -
MmSessionPoolSize);
//
// And it all begins here
//
MmSessionBase = MiSessionPoolStart;
//
// Sanity check that our math is correct
//
ASSERT((ULONG_PTR)MmSessionBase + MmSessionSize == PTE_BASE);
//
// Session space ends wherever image session space ends
//
MiSessionSpaceEnd = MiSessionImageEnd;
//
// System view space ends at session space, so now that we know where
// this is, we can compute the base address of system view space itself.
//
MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase -
MmSystemViewSize);
/* Compute the PTE addresses for all the addresses we carved out */
MiSessionImagePteStart = MiAddressToPte(MiSessionImageStart);
MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd);
MiSessionBasePte = MiAddressToPte(MmSessionBase);
MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd);
}
VOID
NTAPI
INIT_FUNCTION

View file

@ -28,6 +28,9 @@
#define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
#define MI_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF
#define MI_USER_PROBE_ADDRESS (PVOID)0x7FFF0000
#define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0x80000000
#define MI_SYSTEM_CACHE_WS_START (PVOID)0xC0C00000
#define MI_PAGED_POOL_START (PVOID)0xE1000000
#define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
@ -526,6 +529,14 @@ extern KEVENT MmZeroingPageEvent;
extern ULONG MmSystemPageColor;
extern ULONG MmProcessColorSeed;
extern PMMWSL MmWorkingSetList;
extern PFN_NUMBER MiNumberOfFreePages;
extern SIZE_T MmSessionViewSize;
extern SIZE_T MmSessionPoolSize;
extern SIZE_T MmSessionImageSize;
extern PVOID MiSystemViewStart;
extern PVOID MiSessionPoolEnd; // 0xBE000000
extern PVOID MiSessionPoolStart; // 0xBD000000
extern PVOID MiSessionViewStart; // 0xBE000000
//
// Figures out the hardware bits for a PTE
@ -910,6 +921,10 @@ MmArmInitSystem(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
NTAPI
MiInitializeSessionSpaceLayout();
NTSTATUS
NTAPI
MiInitMachineDependent(

View file

@ -410,7 +410,7 @@ MiScanMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
if (Descriptor->MemoryType != LoaderBad)
{
/* Count this in the total of pages */
MmNumberOfPhysicalPages += Descriptor->PageCount;
MmNumberOfPhysicalPages += (PFN_COUNT)Descriptor->PageCount;
}
/* Check if this is the new lowest page */
@ -1898,9 +1898,9 @@ MmArmInitSystem(IN ULONG Phase,
//
// Define the basic user vs. kernel address space separation
//
MmSystemRangeStart = (PVOID)KSEG0_BASE;
MmUserProbeAddress = (ULONG_PTR)MmSystemRangeStart - 0x10000;
MmHighestUserAddress = (PVOID)(MmUserProbeAddress - 1);
MmSystemRangeStart = (PVOID)MI_DEFAULT_SYSTEM_RANGE_START;
MmUserProbeAddress = (ULONG_PTR)MI_HIGHEST_USER_ADDRESS;
MmHighestUserAddress = (PVOID)MI_HIGHEST_USER_ADDRESS;
/* Highest PTE and PDE based on the addresses above */
MiHighestUserPte = MiAddressToPte(MmHighestUserAddress);
@ -1922,73 +1922,8 @@ MmArmInitSystem(IN ULONG Phase,
MmBootImageSize = (MmBootImageSize + PDE_MAPPED_VA - 1) & ~(PDE_MAPPED_VA - 1);
ASSERT((MmBootImageSize % PDE_MAPPED_VA) == 0);
//
// Set the size of session view, pool, and image
//
MmSessionSize = MI_SESSION_SIZE;
MmSessionViewSize = MI_SESSION_VIEW_SIZE;
MmSessionPoolSize = MI_SESSION_POOL_SIZE;
MmSessionImageSize = MI_SESSION_IMAGE_SIZE;
//
// Set the size of system view
//
MmSystemViewSize = MI_SYSTEM_VIEW_SIZE;
//
// This is where it all ends
//
MiSessionImageEnd = (PVOID)PTE_BASE;
//
// This is where we will load Win32k.sys and the video driver
//
MiSessionImageStart = (PVOID)((ULONG_PTR)MiSessionImageEnd -
MmSessionImageSize);
//
// So the view starts right below the session working set (itself below
// the image area)
//
MiSessionViewStart = (PVOID)((ULONG_PTR)MiSessionImageEnd -
MmSessionImageSize -
MI_SESSION_WORKING_SET_SIZE -
MmSessionViewSize);
//
// Session pool follows
//
MiSessionPoolEnd = MiSessionViewStart;
MiSessionPoolStart = (PVOID)((ULONG_PTR)MiSessionPoolEnd -
MmSessionPoolSize);
//
// And it all begins here
//
MmSessionBase = MiSessionPoolStart;
//
// Sanity check that our math is correct
//
ASSERT((ULONG_PTR)MmSessionBase + MmSessionSize == PTE_BASE);
//
// Session space ends wherever image session space ends
//
MiSessionSpaceEnd = MiSessionImageEnd;
//
// System view space ends at session space, so now that we know where
// this is, we can compute the base address of system view space itself.
//
MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase -
MmSystemViewSize);
/* Compute the PTE addresses for all the addresses we carved out */
MiSessionImagePteStart = MiAddressToPte(MiSessionImageStart);
MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd);
MiSessionBasePte = MiAddressToPte(MmSessionBase);
MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd);
/* Initialize session space address layout */
MiInitializeSessionSpaceLayout();
/* Initialize the user mode image list */
InitializeListHead(&MmLoadedUserImageList);

View file

@ -40,16 +40,16 @@ MMPTE PrototypePte = {{(MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) |
/* Sizes */
///SIZE_T MmSessionSize = MI_SESSION_SIZE;
SIZE_T MmSessionViewSize = MI_SESSION_VIEW_SIZE;
SIZE_T MmSessionPoolSize = MI_SESSION_POOL_SIZE;
SIZE_T MmSessionImageSize = MI_SESSION_IMAGE_SIZE;
SIZE_T MmSystemViewSize = MI_SYSTEM_VIEW_SIZE;
extern SIZE_T MmSessionViewSize;
extern SIZE_T MmSessionPoolSize;
extern SIZE_T MmSessionImageSize;
extern SIZE_T MmSystemViewSize;
SIZE_T MiNonPagedSystemSize;
/* Address ranges */
ULONG64 MmUserProbeAddress = 0x7FFFFFF0000ULL;
PVOID MmHighestUserAddress = (PVOID)0x7FFFFFEFFFFULL;
PVOID MmSystemRangeStart = (PVOID)0xFFFF080000000000ULL;
//ULONG64 MmUserProbeAddress = 0x7FFFFFF0000ULL;
//PVOID MmHighestUserAddress = (PVOID)0x7FFFFFEFFFFULL;
//PVOID MmSystemRangeStart = (PVOID)0xFFFF080000000000ULL;
PVOID MmSessionBase; // FFFFF90000000000 = MiSessionPoolStart
PVOID MiSessionPoolStart; // FFFFF90000000000 = MiSessionPoolEnd - MmSessionPoolSize
PVOID MiSessionPoolEnd; // = MiSessionViewStart
@ -75,7 +75,6 @@ ULONG64 MxPfnSizeInBytes;
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
ULONG MiNumberDescriptors = 0;
PFN_NUMBER MiSystemPages = 0;
BOOLEAN MiIncludeType[LoaderMaximum];
@ -88,92 +87,53 @@ BOOLEAN MiPfnsInitialized = FALSE;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
INIT_FUNCTION
MiInitializeSessionSpaceLayout()
{
MmSessionViewSize = MI_SESSION_VIEW_SIZE;
MmSessionPoolSize = MI_SESSION_POOL_SIZE;
MmSessionImageSize = MI_SESSION_IMAGE_SIZE;
MmSystemViewSize = MI_SYSTEM_VIEW_SIZE;
/* Set up session space */
MiSessionSpaceEnd = (PVOID)MI_SESSION_SPACE_END;
/* This is where we will load Win32k.sys and the video driver */
MiSessionImageEnd = MiSessionSpaceEnd;
MiSessionImageStart = (PCHAR)MiSessionImageEnd - MmSessionImageSize;
/* The view starts right below the session working set (itself below
* the image area) */
MiSessionViewEnd = MI_SESSION_VIEW_END;
MiSessionViewStart = (PCHAR)MiSessionViewEnd - MmSessionViewSize;
ASSERT(IS_PAGE_ALIGNED(MiSessionViewStart));
/* Session pool follows */
MiSessionPoolEnd = MiSessionViewStart;
MiSessionPoolStart = (PCHAR)MiSessionPoolEnd - MmSessionPoolSize;
ASSERT(IS_PAGE_ALIGNED(MiSessionPoolStart));
/* And it all begins here */
MmSessionBase = MiSessionPoolStart;
/* System view space ends at session space, so now that we know where
* this is, we can compute the base address of system view space itself. */
MiSystemViewStart = (PCHAR)MmSessionBase - MmSystemViewSize;
ASSERT(IS_PAGE_ALIGNED(MiSystemViewStart));
/* Sanity checks */
ASSERT(MiSessionViewEnd <= MiSessionImageStart);
ASSERT(MmSessionBase <= MiSessionPoolStart);
}
ULONG
NoDbgPrint(const char *Format, ...)
{
return 0;
}
VOID
NTAPI
MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry;
PFN_NUMBER LastPage;
ULONG i;
/* Get the size of the boot loader's image allocations */
MmBootImageSize = KeLoaderBlock->Extension->LoaderPagesSpanned * PAGE_SIZE;
MmBootImageSize = ROUND_UP(MmBootImageSize, 4 * 1024 * 1024);
/* Instantiate memory that we don't consider RAM/usable */
for (i = 0; i < LoaderMaximum; i++) MiIncludeType[i] = TRUE;
MiIncludeType[LoaderBad] = FALSE;
MiIncludeType[LoaderFirmwarePermanent] = FALSE;
MiIncludeType[LoaderSpecialMemory] = FALSE;
MiIncludeType[LoaderBBTMemory] = FALSE;
/* Loop the memory descriptors */
for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
ListEntry != &LoaderBlock->MemoryDescriptorListHead;
ListEntry = ListEntry->Flink)
{
/* Get the memory descriptor */
Descriptor = CONTAINING_RECORD(ListEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
/* Count it */
MiNumberDescriptors++;
/* Skip pages that are not part of the PFN database */
if (!MiIncludeType[Descriptor->MemoryType])
{
continue;
}
/* Add this to the total of pages */
MmNumberOfPhysicalPages += (PFN_COUNT)Descriptor->PageCount;
/* Check if this is the new lowest page */
if (Descriptor->BasePage < MmLowestPhysicalPage)
{
/* Update the lowest page */
MmLowestPhysicalPage = Descriptor->BasePage;
}
/* Check if this is the new highest page */
LastPage = Descriptor->BasePage + Descriptor->PageCount - 1;
if (LastPage > MmHighestPhysicalPage)
{
/* Update the highest page */
MmHighestPhysicalPage = LastPage;
}
/* Check if this is currently free memory */
if ((Descriptor->MemoryType == LoaderFree) ||
(Descriptor->MemoryType == LoaderLoadedProgram) ||
(Descriptor->MemoryType == LoaderFirmwareTemporary) ||
(Descriptor->MemoryType == LoaderOsloaderStack))
{
/* Check if this is the largest memory descriptor */
if (Descriptor->PageCount > MxFreePageCount)
{
/* For now, it is */
MxFreeDescriptor = Descriptor;
MxFreePageBase = Descriptor->BasePage;
MxFreePageCount = Descriptor->PageCount;
}
}
else
{
/* Add it to the amount of system used pages */
MiSystemPages += Descriptor->PageCount;
}
}
}
PFN_NUMBER
NTAPI
MiEarlyAllocPage()
@ -341,41 +301,6 @@ MiPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
}
VOID
NTAPI
MiInitializeSessionSpace(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
/* Set up session space */
MiSessionSpaceEnd = (PVOID)MI_SESSION_SPACE_END;
/* This is where we will load Win32k.sys and the video driver */
MiSessionImageEnd = MiSessionSpaceEnd;
MiSessionImageStart = (PCHAR)MiSessionImageEnd - MmSessionImageSize;
/* The view starts right below the session working set (itself below
* the image area) */
MiSessionViewEnd = MI_SESSION_VIEW_END;
MiSessionViewStart = (PCHAR)MiSessionViewEnd - MmSessionViewSize;
ASSERT(IS_PAGE_ALIGNED(MiSessionViewStart));
/* Session pool follows */
MiSessionPoolEnd = MiSessionViewStart;
MiSessionPoolStart = (PCHAR)MiSessionPoolEnd - MmSessionPoolSize;
ASSERT(IS_PAGE_ALIGNED(MiSessionPoolStart));
/* And it all begins here */
MmSessionBase = MiSessionPoolStart;
/* System view space ends at session space, so now that we know where
* this is, we can compute the base address of system view space itself. */
MiSystemViewStart = (PCHAR)MmSessionBase - MmSystemViewSize;
ASSERT(IS_PAGE_ALIGNED(MiSystemViewStart));
/* Sanity checks */
ASSERT(MiSessionViewEnd <= MiSessionImageStart);
ASSERT(MmSessionBase <= MiSessionPoolStart);
}
VOID
MiInitializePageTable()
{
@ -605,92 +530,6 @@ MiBuildSystemPteSpace()
MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1;
}
VOID
NTAPI
MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PPHYSICAL_MEMORY_DESCRIPTOR Buffer;
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry;
PFN_NUMBER NextPage = -1;
PULONG Bitmap;
ULONG Runs = 0;
ULONG_PTR Size;
/* Calculate size for the PFN bitmap */
Size = ROUND_UP(MmHighestPhysicalPage + 1, sizeof(ULONG));
/* Allocate the PFN bitmap */
Bitmap = ExAllocatePoolWithTag(NonPagedPool, Size, ' mM');
/* Allocate enough memory for the physical memory block */
Buffer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
sizeof(PHYSICAL_MEMORY_RUN) *
(MiNumberDescriptors - 1),
'lMmM');
if (!Bitmap || !Buffer)
{
/* This is critical */
KeBugCheckEx(INSTALL_MORE_MEMORY,
MmNumberOfPhysicalPages,
MmLowestPhysicalPage,
MmHighestPhysicalPage,
0x101);
}
/* Initialize the bitmap and clear all bits */
RtlInitializeBitMap(&MiPfnBitMap,
Bitmap,
(ULONG)MmHighestPhysicalPage + 1);
RtlClearAllBits(&MiPfnBitMap);
/* Loop the memory descriptors */
for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
ListEntry != &LoaderBlock->MemoryDescriptorListHead;
ListEntry = ListEntry->Flink)
{
/* Get the memory descriptor */
Descriptor = CONTAINING_RECORD(ListEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
/* Skip pages that are not part of the PFN database */
if (!MiIncludeType[Descriptor->MemoryType])
{
continue;
}
/* Does the memory block begin where the last ended? */
if (Descriptor->BasePage == NextPage)
{
/* Add it to the current run */
Buffer->Run[Runs - 1].PageCount += Descriptor->PageCount;
}
else
{
/* Create a new run */
Runs++;
Buffer->Run[Runs - 1].BasePage = Descriptor->BasePage;
Buffer->Run[Runs - 1].PageCount = Descriptor->PageCount;
}
/* Set the bits in the PFN bitmap */
RtlSetBits(&MiPfnBitMap,
(ULONG)Descriptor->BasePage,
(ULONG)Descriptor->PageCount);
/* Set the next page */
NextPage = Descriptor->BasePage + Descriptor->PageCount;
}
// FIXME: allocate a buffer of better size
Buffer->NumberOfRuns = Runs;
Buffer->NumberOfPages = MmNumberOfPhysicalPages;
MmPhysicalMemoryBlock = Buffer;
}
VOID
NTAPI
MiBuildPagedPool_x(VOID)
@ -824,7 +663,7 @@ MmArmInitSystem_x(IN ULONG Phase,
MmBootImageSize = ROUND_UP(MmBootImageSize, PAGE_SIZE);
/* Parse memory descriptors, find free pages */
MiEvaluateMemoryDescriptors(LoaderBlock);
//MiEvaluateMemoryDescriptors(LoaderBlock);
/* Start PFN database at hardcoded address */
MmPfnDatabase = MI_PFN_DATABASE;
@ -832,9 +671,6 @@ MmArmInitSystem_x(IN ULONG Phase,
/* Prepare PFN database mappings */
MiPreparePfnDatabse(LoaderBlock);
/* Initialize the session space */
MiInitializeSessionSpace(LoaderBlock);
/* Initialize some mappings */
MiInitializePageTable();
@ -859,7 +695,7 @@ MmArmInitSystem_x(IN ULONG Phase,
MiBuildSystemPteSpace();
/* Build the physical memory block */
MiBuildPhysicalMemoryBlock(LoaderBlock);
//MiBuildPhysicalMemoryBlock(LoaderBlock);
/* Size up paged pool and build the shadow system page directory */
//MiBuildPagedPool();