2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/mm/mminit.c
5 * PURPOSE: Memory Manager Initialization
9 /* INCLUDES ******************************************************************/
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "ARM3/miarm.h"
18 /* GLOBALS *******************************************************************/
51 PBOOLEAN Mm64BitPhysicalAddress
= FALSE
;
52 ULONG MmReadClusterSize
;
54 PMMPTE MmSharedUserDataPte
;
55 PMMSUPPORT MmKernelAddressSpace
;
56 extern KMUTANT MmSystemLoadLock
;
57 BOOLEAN MiDbgEnableMdDump
=
64 /* PRIVATE FUNCTIONS *********************************************************/
69 MiInitSystemMemoryAreas()
72 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
75 BoundaryAddressMultiple
.QuadPart
= 0;
78 // Create the memory area to define the PTE base
80 BaseAddress
= (PVOID
)PTE_BASE
;
81 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
82 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
89 BoundaryAddressMultiple
);
90 ASSERT(Status
== STATUS_SUCCESS
);
93 // Create the memory area to define Hyperspace
95 BaseAddress
= (PVOID
)HYPER_SPACE
;
96 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
97 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
104 BoundaryAddressMultiple
);
105 ASSERT(Status
== STATUS_SUCCESS
);
108 // Protect the PFN database
110 BaseAddress
= MmPfnDatabase
;
111 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
112 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
114 (MxPfnAllocation
<< PAGE_SHIFT
),
119 BoundaryAddressMultiple
);
120 ASSERT(Status
== STATUS_SUCCESS
);
123 // ReactOS requires a memory area to keep the initial NP area off-bounds
125 BaseAddress
= MmNonPagedPoolStart
;
126 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
127 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
129 MmSizeOfNonPagedPoolInBytes
,
134 BoundaryAddressMultiple
);
135 ASSERT(Status
== STATUS_SUCCESS
);
138 // And we need one more for the system NP
140 BaseAddress
= MmNonPagedSystemStart
;
141 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
142 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
144 (ULONG_PTR
)MmNonPagedPoolEnd
-
145 (ULONG_PTR
)MmNonPagedSystemStart
,
150 BoundaryAddressMultiple
);
151 ASSERT(Status
== STATUS_SUCCESS
);
154 // We also need one for system view space
156 BaseAddress
= MiSystemViewStart
;
157 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
158 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
165 BoundaryAddressMultiple
);
166 ASSERT(Status
== STATUS_SUCCESS
);
169 // And another for session space
171 BaseAddress
= MmSessionBase
;
172 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
173 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
175 (ULONG_PTR
)MiSessionSpaceEnd
-
176 (ULONG_PTR
)MmSessionBase
,
181 BoundaryAddressMultiple
);
182 ASSERT(Status
== STATUS_SUCCESS
);
185 // One more for ARM paged pool
187 BaseAddress
= MmPagedPoolStart
;
188 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
189 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
191 MmSizeOfPagedPoolInBytes
,
196 BoundaryAddressMultiple
);
197 ASSERT(Status
== STATUS_SUCCESS
);
200 // And now, ReactOS paged pool
202 BaseAddress
= MmPagedPoolBase
;
203 MmCreateMemoryArea(MmGetKernelAddressSpace(),
204 MEMORY_AREA_PAGED_POOL
| MEMORY_AREA_STATIC
,
211 BoundaryAddressMultiple
);
216 BaseAddress
= (PVOID
)PCR
;
217 MmCreateMemoryArea(MmGetKernelAddressSpace(),
218 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
220 PAGE_SIZE
* KeNumberProcessors
,
225 BoundaryAddressMultiple
);
228 // Now the KUSER_SHARED_DATA
230 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
231 MmCreateMemoryArea(MmGetKernelAddressSpace(),
232 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
239 BoundaryAddressMultiple
);
244 MiDbgDumpAddressSpace(VOID
)
247 // Print the memory layout
249 DPRINT1(" 0x%p - 0x%p\t%s\n",
251 (ULONG_PTR
)MmSystemRangeStart
+ MmBootImageSize
,
252 "Boot Loaded Image");
253 DPRINT1(" 0x%p - 0x%p\t%s\n",
255 (ULONG_PTR
)MmPagedPoolBase
+ MmPagedPoolSize
,
257 DPRINT1(" 0x%p - 0x%p\t%s\n",
259 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
261 DPRINT1(" 0x%p - 0x%p\t%s\n",
263 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
264 "ARM³ Non Paged Pool");
265 DPRINT1(" 0x%p - 0x%p\t%s\n",
267 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
268 "System View Space");
269 DPRINT1(" 0x%p - 0x%p\t%s\n",
273 DPRINT1(" 0x%p - 0x%p\t%s\n",
276 DPRINT1(" 0x%p - 0x%p\t%s\n",
277 PDE_BASE
, HYPER_SPACE
,
279 DPRINT1(" 0x%p - 0x%p\t%s\n",
280 HYPER_SPACE
, HYPER_SPACE
+ (4 * 1024 * 1024),
282 DPRINT1(" 0x%p - 0x%p\t%s\n",
284 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
286 DPRINT1(" 0x%p - 0x%p\t%s\n",
287 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
289 DPRINT1(" 0x%p - 0x%p\t%s\n",
290 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
291 "Non Paged Pool Expansion PTE Space");
296 MiDbgDumpMemoryDescriptors(VOID
)
298 PLIST_ENTRY NextEntry
;
299 PMEMORY_ALLOCATION_DESCRIPTOR Md
;
300 ULONG TotalPages
= 0;
302 DPRINT1("Base\t\tLength\t\tType\n");
303 for (NextEntry
= KeLoaderBlock
->MemoryDescriptorListHead
.Flink
;
304 NextEntry
!= &KeLoaderBlock
->MemoryDescriptorListHead
;
305 NextEntry
= NextEntry
->Flink
)
307 Md
= CONTAINING_RECORD(NextEntry
, MEMORY_ALLOCATION_DESCRIPTOR
, ListEntry
);
308 DPRINT1("%08lX\t%08lX\t%s\n", Md
->BasePage
, Md
->PageCount
, MemType
[Md
->MemoryType
]);
309 TotalPages
+= Md
->PageCount
;
312 DPRINT1("Total: %08lX (%d MB)\n", TotalPages
, (TotalPages
* PAGE_SIZE
) / 1024 / 1024);
317 MmInitSystem(IN ULONG Phase
,
318 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
320 extern MMPTE HyperTemplatePte
;
322 MMPTE TempPte
= HyperTemplatePte
;
323 PFN_NUMBER PageFrameNumber
;
327 /* Initialize the kernel address space */
328 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock
);
329 MmKernelAddressSpace
= MmGetCurrentAddressSpace();
330 MmInitGlobalKernelPageDirectory();
332 /* Dump memory descriptors */
333 if (MiDbgEnableMdDump
) MiDbgDumpMemoryDescriptors();
336 // Initialize ARM³ in phase 0
338 MmArmInitSystem(0, KeLoaderBlock
);
340 /* Initialize the page list */
341 MmInitializePageList();
344 // Initialize ARM³ in phase 1
346 MmArmInitSystem(1, KeLoaderBlock
);
348 /* Put the paged pool after the loaded modules */
349 MmPagedPoolBase
= (PVOID
)PAGE_ROUND_UP((ULONG_PTR
)MmSystemRangeStart
+
351 MmPagedPoolSize
= MM_PAGED_POOL_SIZE
;
353 /* Intialize system memory areas */
354 MiInitSystemMemoryAreas();
356 /* Dump the address space */
357 MiDbgDumpAddressSpace();
359 /* Initialize paged pool */
360 MmInitializePagedPool();
362 /* Initialize working sets */
363 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
365 /* Initialize the Loader Lock */
366 KeInitializeMutant(&MmSystemLoadLock
, FALSE
);
368 /* Reload boot drivers */
369 MiReloadBootLoadedDrivers(LoaderBlock
);
371 /* Initialize the loaded module list */
372 MiInitializeLoadedModuleList(LoaderBlock
);
374 /* Setup shared user data settings that NT does as well */
375 ASSERT(SharedUserData
->NumberOfPhysicalPages
== 0);
376 SharedUserData
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
377 SharedUserData
->LargePageMinimum
= 0;
379 /* For now, we assume that we're always Server */
380 SharedUserData
->NtProductType
= NtProductServer
;
384 MmInitializeRmapList();
385 MmInitializePageOp();
386 MmInitSectionImplementation();
390 // Create a PTE to double-map the shared data section. We allocate it
391 // from paged pool so that we can't fault when trying to touch the PTE
392 // itself (to map it), since paged pool addresses will already be mapped
393 // by the fault handler.
395 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
398 if (!MmSharedUserDataPte
) return FALSE
;
401 // Now get the PTE for shared data, and read the PFN that holds it
403 PointerPte
= MiAddressToPte(KI_USER_SHARED_DATA
);
404 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
405 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
408 // Now write a copy of it
410 MI_MAKE_OWNER_PAGE(&TempPte
);
411 TempPte
.u
.Hard
.PageFrameNumber
= PageFrameNumber
;
412 *MmSharedUserDataPte
= TempPte
;
417 MiInitBalancerThread();
420 * Initialise the modified page writer.
424 /* Initialize the balance set manager */