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 BOOLEAN Mm64BitPhysicalAddress
= FALSE
;
52 ULONG MmReadClusterSize
;
54 // 0 | 1 is on/off paging, 2 is undocumented
56 UCHAR MmDisablePagingExecutive
= 1; // Forced to off
57 PMMPTE MmSharedUserDataPte
;
58 PMMSUPPORT MmKernelAddressSpace
;
59 BOOLEAN MiDbgEnableMdDump
=
66 /* PRIVATE FUNCTIONS *********************************************************/
71 MiInitSystemMemoryAreas()
74 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
77 BoundaryAddressMultiple
.QuadPart
= 0;
80 // Create the memory area to define the loader mappings
82 BaseAddress
= (PVOID
)KSEG0_BASE
;
83 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
84 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
87 PAGE_EXECUTE_READWRITE
,
91 BoundaryAddressMultiple
);
92 ASSERT(Status
== STATUS_SUCCESS
);
95 // Create the memory area to define the PTE base
97 BaseAddress
= (PVOID
)PTE_BASE
;
98 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
99 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
101 PTE_TOP
- PTE_BASE
+ 1,
106 BoundaryAddressMultiple
);
107 ASSERT(Status
== STATUS_SUCCESS
);
110 // Create the memory area to define Hyperspace
112 BaseAddress
= (PVOID
)HYPER_SPACE
;
113 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
114 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
116 HYPER_SPACE_END
- HYPER_SPACE
+ 1,
121 BoundaryAddressMultiple
);
122 ASSERT(Status
== STATUS_SUCCESS
);
125 // Protect the PFN database
127 BaseAddress
= MmPfnDatabase
;
128 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
129 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
131 (MxPfnAllocation
<< PAGE_SHIFT
),
136 BoundaryAddressMultiple
);
137 ASSERT(Status
== STATUS_SUCCESS
);
140 // ReactOS requires a memory area to keep the initial NP area off-bounds
142 BaseAddress
= MmNonPagedPoolStart
;
143 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
144 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
146 MmSizeOfNonPagedPoolInBytes
,
151 BoundaryAddressMultiple
);
152 ASSERT(Status
== STATUS_SUCCESS
);
155 // And we need one more for the system NP
157 BaseAddress
= MmNonPagedSystemStart
;
158 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
159 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
161 (MmNumberOfSystemPtes
+ 1) * PAGE_SIZE
,
166 BoundaryAddressMultiple
);
167 ASSERT(Status
== STATUS_SUCCESS
);
170 // We also need one for system view space
172 BaseAddress
= MiSystemViewStart
;
173 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
174 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
181 BoundaryAddressMultiple
);
182 ASSERT(Status
== STATUS_SUCCESS
);
185 // And another for session space
187 BaseAddress
= MmSessionBase
;
188 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
189 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
191 (ULONG_PTR
)MiSessionSpaceEnd
-
192 (ULONG_PTR
)MmSessionBase
,
197 BoundaryAddressMultiple
);
198 ASSERT(Status
== STATUS_SUCCESS
);
201 // One more for ARM paged pool
203 BaseAddress
= MmPagedPoolStart
;
204 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
205 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
207 MmSizeOfPagedPoolInBytes
,
212 BoundaryAddressMultiple
);
213 ASSERT(Status
== STATUS_SUCCESS
);
216 // And now, ReactOS paged pool
218 BaseAddress
= MmPagedPoolBase
;
219 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
220 MEMORY_AREA_PAGED_POOL
| MEMORY_AREA_STATIC
,
227 BoundaryAddressMultiple
);
228 ASSERT(Status
== STATUS_SUCCESS
);
234 BaseAddress
= (PVOID
)PCR
;
235 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
236 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
238 PAGE_SIZE
* KeNumberProcessors
,
243 BoundaryAddressMultiple
);
244 ASSERT(Status
== STATUS_SUCCESS
);
248 // Now the KUSER_SHARED_DATA
250 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
251 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
252 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
259 BoundaryAddressMultiple
);
260 ASSERT(Status
== STATUS_SUCCESS
);
263 // And the debugger mapping
265 BaseAddress
= MI_DEBUG_MAPPING
;
266 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
267 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
274 BoundaryAddressMultiple
);
275 ASSERT(Status
== STATUS_SUCCESS
);
279 // Finally, reserve the 2 pages we currently make use of for HAL mappings
281 BaseAddress
= (PVOID
)0xFFC00000;
282 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
283 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
290 BoundaryAddressMultiple
);
291 ASSERT(Status
== STATUS_SUCCESS
);
297 MiDbgDumpAddressSpace(VOID
)
300 // Print the memory layout
302 DPRINT1(" 0x%p - 0x%p\t%s\n",
304 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
305 "Boot Loaded Image");
306 DPRINT1(" 0x%p - 0x%p\t%s\n",
308 (ULONG_PTR
)MmPagedPoolBase
+ MmPagedPoolSize
,
310 DPRINT1(" 0x%p - 0x%p\t%s\n",
312 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
314 DPRINT1(" 0x%p - 0x%p\t%s\n",
316 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
317 "ARM³ Non Paged Pool");
318 DPRINT1(" 0x%p - 0x%p\t%s\n",
320 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
321 "System View Space");
322 DPRINT1(" 0x%p - 0x%p\t%s\n",
326 DPRINT1(" 0x%p - 0x%p\t%s\n",
329 DPRINT1(" 0x%p - 0x%p\t%s\n",
332 DPRINT1(" 0x%p - 0x%p\t%s\n",
333 HYPER_SPACE
, HYPER_SPACE_END
,
335 DPRINT1(" 0x%p - 0x%p\t%s\n",
337 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
339 DPRINT1(" 0x%p - 0x%p\t%s\n",
340 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
342 DPRINT1(" 0x%p - 0x%p\t%s\n",
343 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
344 "Non Paged Pool Expansion PTE Space");
349 MiDbgDumpMemoryDescriptors(VOID
)
351 PLIST_ENTRY NextEntry
;
352 PMEMORY_ALLOCATION_DESCRIPTOR Md
;
353 ULONG TotalPages
= 0;
355 DPRINT1("Base\t\tLength\t\tType\n");
356 for (NextEntry
= KeLoaderBlock
->MemoryDescriptorListHead
.Flink
;
357 NextEntry
!= &KeLoaderBlock
->MemoryDescriptorListHead
;
358 NextEntry
= NextEntry
->Flink
)
360 Md
= CONTAINING_RECORD(NextEntry
, MEMORY_ALLOCATION_DESCRIPTOR
, ListEntry
);
361 DPRINT1("%08lX\t%08lX\t%s\n", Md
->BasePage
, Md
->PageCount
, MemType
[Md
->MemoryType
]);
362 TotalPages
+= Md
->PageCount
;
365 DPRINT1("Total: %08lX (%d MB)\n", TotalPages
, (TotalPages
* PAGE_SIZE
) / 1024 / 1024);
370 MmInitSystem(IN ULONG Phase
,
371 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
373 extern MMPTE HyperTemplatePte
;
375 MMPTE TempPte
= HyperTemplatePte
;
376 PFN_NUMBER PageFrameNumber
;
380 /* Initialize the kernel address space */
381 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock
);
382 MmKernelAddressSpace
= MmGetCurrentAddressSpace();
383 MmInitGlobalKernelPageDirectory();
385 /* Dump memory descriptors */
386 if (MiDbgEnableMdDump
) MiDbgDumpMemoryDescriptors();
389 // Initialize ARM³ in phase 0
391 MmArmInitSystem(0, KeLoaderBlock
);
393 /* Initialize the page list */
394 MmInitializePageList();
397 // Initialize ARM³ in phase 1
399 MmArmInitSystem(1, KeLoaderBlock
);
403 // Everything required for the debugger to read and write
404 // physical memory is now set up
406 MmDebugPte
= MiAddressToPte(MiDebugMapping
);
409 /* Put the paged pool after the loaded modules */
410 MmPagedPoolBase
= (PVOID
)PAGE_ROUND_UP((ULONG_PTR
)MmSystemRangeStart
+
412 MmPagedPoolSize
= MM_PAGED_POOL_SIZE
;
414 /* Intialize system memory areas */
415 MiInitSystemMemoryAreas();
417 /* Dump the address space */
418 MiDbgDumpAddressSpace();
420 #ifndef _M_AMD64 // skip old paged pool
421 /* Initialize paged pool */
422 MmInitializePagedPool();
425 /* Initialize working sets */
426 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
428 /* Initialize the user mode image list */
429 InitializeListHead(&MmLoadedUserImageList
);
431 /* Initialize the Loader Lock */
432 KeInitializeMutant(&MmSystemLoadLock
, FALSE
);
434 /* Reload boot drivers */
435 MiReloadBootLoadedDrivers(LoaderBlock
);
437 /* Initialize the loaded module list */
438 MiInitializeLoadedModuleList(LoaderBlock
);
440 /* Setup shared user data settings that NT does as well */
441 ASSERT(SharedUserData
->NumberOfPhysicalPages
== 0);
442 SharedUserData
->NumberOfPhysicalPages
= MmNumberOfPhysicalPages
;
443 SharedUserData
->LargePageMinimum
= 0;
445 /* For now, we assume that we're always Server */
446 SharedUserData
->NtProductType
= NtProductServer
;
450 MmInitializeRmapList();
451 MmInitializePageOp();
452 MmInitSectionImplementation();
456 // Create a PTE to double-map the shared data section. We allocate it
457 // from paged pool so that we can't fault when trying to touch the PTE
458 // itself (to map it), since paged pool addresses will already be mapped
459 // by the fault handler.
461 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
464 if (!MmSharedUserDataPte
) return FALSE
;
467 // Now get the PTE for shared data, and read the PFN that holds it
469 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
470 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
471 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
474 // Now write a copy of it
476 MI_MAKE_OWNER_PAGE(&TempPte
);
477 TempPte
.u
.Hard
.PageFrameNumber
= PageFrameNumber
;
478 *MmSharedUserDataPte
= TempPte
;
483 MiInitBalancerThread();
486 * Initialise the modified page writer.
490 /* Initialize the balance set manager */