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 extern ULONG MmBootImageSize
;
58 BOOLEAN MiDbgEnableMdDump
=
65 /* PRIVATE FUNCTIONS *********************************************************/
70 MiInitSystemMemoryAreas()
73 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
76 BoundaryAddressMultiple
.QuadPart
= 0;
79 // Create the memory area to define the PTE base
81 BaseAddress
= (PVOID
)PTE_BASE
;
82 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
83 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
90 BoundaryAddressMultiple
);
91 ASSERT(Status
== STATUS_SUCCESS
);
94 // Create the memory area to define Hyperspace
96 BaseAddress
= (PVOID
)HYPER_SPACE
;
97 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
98 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
105 BoundaryAddressMultiple
);
106 ASSERT(Status
== STATUS_SUCCESS
);
109 // Protect the PFN database
111 BaseAddress
= MmPfnDatabase
;
112 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
113 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
115 (MxPfnAllocation
<< PAGE_SHIFT
),
120 BoundaryAddressMultiple
);
121 ASSERT(Status
== STATUS_SUCCESS
);
124 // ReactOS requires a memory area to keep the initial NP area off-bounds
126 BaseAddress
= MmNonPagedPoolStart
;
127 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
128 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
130 MmSizeOfNonPagedPoolInBytes
,
135 BoundaryAddressMultiple
);
136 ASSERT(Status
== STATUS_SUCCESS
);
139 // And we need one more for the system NP
141 BaseAddress
= MmNonPagedSystemStart
;
142 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
143 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
145 (ULONG_PTR
)MmNonPagedPoolEnd
-
146 (ULONG_PTR
)MmNonPagedSystemStart
,
151 BoundaryAddressMultiple
);
152 ASSERT(Status
== STATUS_SUCCESS
);
155 // We also need one for system view space
157 BaseAddress
= MiSystemViewStart
;
158 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
159 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
166 BoundaryAddressMultiple
);
167 ASSERT(Status
== STATUS_SUCCESS
);
170 // And another for session space
172 BaseAddress
= MmSessionBase
;
173 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
174 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
176 (ULONG_PTR
)MiSessionSpaceEnd
-
177 (ULONG_PTR
)MmSessionBase
,
182 BoundaryAddressMultiple
);
183 ASSERT(Status
== STATUS_SUCCESS
);
186 // One more for ARM paged pool
188 BaseAddress
= MmPagedPoolStart
;
189 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
190 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
192 MmSizeOfPagedPoolInBytes
,
197 BoundaryAddressMultiple
);
198 ASSERT(Status
== STATUS_SUCCESS
);
201 // And now, ReactOS paged pool
203 BaseAddress
= MmPagedPoolBase
;
204 MmCreateMemoryArea(MmGetKernelAddressSpace(),
205 MEMORY_AREA_PAGED_POOL
| MEMORY_AREA_STATIC
,
212 BoundaryAddressMultiple
);
217 BaseAddress
= (PVOID
)PCR
;
218 MmCreateMemoryArea(MmGetKernelAddressSpace(),
219 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
221 PAGE_SIZE
* KeNumberProcessors
,
226 BoundaryAddressMultiple
);
229 // Now the KUSER_SHARED_DATA
231 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
232 MmCreateMemoryArea(MmGetKernelAddressSpace(),
233 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
240 BoundaryAddressMultiple
);
245 MiDbgDumpAddressSpace(VOID
)
248 // Print the memory layout
250 DPRINT1(" 0x%p - 0x%p\t%s\n",
252 (ULONG_PTR
)MmSystemRangeStart
+ MmBootImageSize
,
253 "Boot Loaded Image");
254 DPRINT1(" 0x%p - 0x%p\t%s\n",
256 (ULONG_PTR
)MmPagedPoolBase
+ MmPagedPoolSize
,
258 DPRINT1(" 0x%p - 0x%p\t%s\n",
260 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
262 DPRINT1(" 0x%p - 0x%p\t%s\n",
264 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
265 "ARM³ Non Paged Pool");
266 DPRINT1(" 0x%p - 0x%p\t%s\n",
268 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
269 "System View Space");
270 DPRINT1(" 0x%p - 0x%p\t%s\n",
274 DPRINT1(" 0x%p - 0x%p\t%s\n",
277 DPRINT1(" 0x%p - 0x%p\t%s\n",
278 PDE_BASE
, HYPER_SPACE
,
280 DPRINT1(" 0x%p - 0x%p\t%s\n",
281 HYPER_SPACE
, HYPER_SPACE
+ (4 * 1024 * 1024),
283 DPRINT1(" 0x%p - 0x%p\t%s\n",
285 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
287 DPRINT1(" 0x%p - 0x%p\t%s\n",
288 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
290 DPRINT1(" 0x%p - 0x%p\t%s\n",
291 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
292 "Non Paged Pool Expansion PTE Space");
297 MiDbgDumpMemoryDescriptors(VOID
)
299 PLIST_ENTRY NextEntry
;
300 PMEMORY_ALLOCATION_DESCRIPTOR Md
;
301 ULONG TotalPages
= 0;
303 DPRINT1("Base\t\tLength\t\tType\n");
304 for (NextEntry
= KeLoaderBlock
->MemoryDescriptorListHead
.Flink
;
305 NextEntry
!= &KeLoaderBlock
->MemoryDescriptorListHead
;
306 NextEntry
= NextEntry
->Flink
)
308 Md
= CONTAINING_RECORD(NextEntry
, MEMORY_ALLOCATION_DESCRIPTOR
, ListEntry
);
309 DPRINT1("%08lX\t%08lX\t%s\n", Md
->BasePage
, Md
->PageCount
, MemType
[Md
->MemoryType
]);
310 TotalPages
+= Md
->PageCount
;
313 DPRINT1("Total: %08lX (%d MB)\n", TotalPages
, (TotalPages
* PAGE_SIZE
) / 1024 / 1024);
318 MmArmInitSystem(IN ULONG Phase
,
319 IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
326 /* Initialize the kernel address space */
327 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock
);
328 MmKernelAddressSpace
= MmGetCurrentAddressSpace();
329 MmInitGlobalKernelPageDirectory();
331 /* Dump memory descriptors */
332 if (MiDbgEnableMdDump
) MiDbgDumpMemoryDescriptors();
335 // Initialize ARM³ in phase 0
337 MmArmInitSystem(0, KeLoaderBlock
);
339 /* Initialize the page list */
340 MmInitializePageList();
343 // Initialize ARM³ in phase 1
345 MmArmInitSystem(1, KeLoaderBlock
);
347 /* Put the paged pool after the loaded modules */
348 MmPagedPoolBase
= (PVOID
)PAGE_ROUND_UP((ULONG_PTR
)MmSystemRangeStart
+
350 MmPagedPoolSize
= MM_PAGED_POOL_SIZE
;
352 /* Intialize system memory areas */
353 MiInitSystemMemoryAreas();
355 /* Dump the address space */
356 MiDbgDumpAddressSpace();
358 /* Initialize paged pool */
359 MmInitializePagedPool();
361 /* Initialize working sets */
362 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
367 MmInitSystem(IN ULONG Phase
,
368 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
370 extern MMPTE HyperTemplatePte
;
372 MMPTE TempPte
= HyperTemplatePte
;
373 PFN_NUMBER PageFrameNumber
;
377 /* Initialize Mm bootstrap */
380 /* Initialize the Loader Lock */
381 KeInitializeMutant(&MmSystemLoadLock
, FALSE
);
383 /* Reload boot drivers */
384 MiReloadBootLoadedDrivers(LoaderBlock
);
386 /* Initialize the loaded module list */
387 MiInitializeLoadedModuleList(LoaderBlock
);
389 /* Setup shared user data settings that NT does as well */
390 ASSERT(SharedUserData
->NumberOfPhysicalPages
== 0);
391 SharedUserData
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
392 SharedUserData
->LargePageMinimum
= 0;
394 /* For now, we assume that we're always Server */
395 SharedUserData
->NtProductType
= NtProductServer
;
399 MmInitializeRmapList();
400 MmInitializePageOp();
401 MmInitSectionImplementation();
405 // Create a PTE to double-map the shared data section. We allocate it
406 // from paged pool so that we can't fault when trying to touch the PTE
407 // itself (to map it), since paged pool addresses will already be mapped
408 // by the fault handler.
410 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
413 if (!MmSharedUserDataPte
) return FALSE
;
416 // Now get the PTE for shared data, and read the PFN that holds it
418 PointerPte
= MiAddressToPte(KI_USER_SHARED_DATA
);
419 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
420 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
423 // Now write a copy of it
425 TempPte
.u
.Hard
.Owner
= 1;
426 TempPte
.u
.Hard
.PageFrameNumber
= PageFrameNumber
;
427 *MmSharedUserDataPte
= TempPte
;
432 MiInitBalancerThread();
435 * Initialise the modified page writer.
439 /* Initialize the balance set manager */