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 *******************************************************************/
20 VOID NTAPI
MiInitializeUserPfnBitmap(VOID
);
22 BOOLEAN Mm64BitPhysicalAddress
= FALSE
;
23 ULONG MmReadClusterSize
;
25 // 0 | 1 is on/off paging, 2 is undocumented
27 UCHAR MmDisablePagingExecutive
= 1; // Forced to off
28 PMMPTE MmSharedUserDataPte
;
29 PMMSUPPORT MmKernelAddressSpace
;
31 extern KEVENT MmWaitPageEvent
;
32 extern FAST_MUTEX MiGlobalPageOperation
;
33 extern LIST_ENTRY MiSegmentList
;
34 extern NTSTATUS
MiRosTrimCache(ULONG Target
, ULONG Priority
, PULONG NrFreed
);
36 /* PRIVATE FUNCTIONS *********************************************************/
39 // Helper function to create initial memory areas.
40 // The created area is always read/write.
45 MiCreateArm3StaticMemoryArea(PVOID BaseAddress
, SIZE_T Size
, BOOLEAN Executable
)
47 const ULONG Protection
= Executable
? PAGE_EXECUTE_READWRITE
: PAGE_READWRITE
;
48 PVOID pBaseAddress
= BaseAddress
;
52 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
53 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
60 ASSERT(Status
== STATUS_SUCCESS
);
61 // TODO: Perhaps it would be prudent to bugcheck here, not only assert?
67 MiInitSystemMemoryAreas(VOID
)
70 // Create all the static memory areas.
73 // The loader mappings. The only Executable area.
74 MiCreateArm3StaticMemoryArea((PVOID
)KSEG0_BASE
, MmBootImageSize
, TRUE
);
77 MiCreateArm3StaticMemoryArea((PVOID
)PTE_BASE
, PTE_TOP
- PTE_BASE
+ 1, FALSE
);
80 MiCreateArm3StaticMemoryArea((PVOID
)HYPER_SPACE
, HYPER_SPACE_END
- HYPER_SPACE
+ 1, FALSE
);
82 // Protect the PFN database
83 MiCreateArm3StaticMemoryArea(MmPfnDatabase
, (MxPfnAllocation
<< PAGE_SHIFT
), FALSE
);
85 // ReactOS requires a memory area to keep the initial NP area off-bounds
86 MiCreateArm3StaticMemoryArea(MmNonPagedPoolStart
, MmSizeOfNonPagedPoolInBytes
, FALSE
);
89 MiCreateArm3StaticMemoryArea(MmNonPagedSystemStart
, (MmNumberOfSystemPtes
+ 1) * PAGE_SIZE
, FALSE
);
91 // Nonpaged pool expansion space
92 MiCreateArm3StaticMemoryArea(MmNonPagedPoolExpansionStart
, (ULONG_PTR
)MmNonPagedPoolEnd
- (ULONG_PTR
)MmNonPagedPoolExpansionStart
, FALSE
);
95 MiCreateArm3StaticMemoryArea(MiSystemViewStart
, MmSystemViewSize
, FALSE
);
98 MiCreateArm3StaticMemoryArea(MmSessionBase
, (ULONG_PTR
)MiSessionSpaceEnd
- (ULONG_PTR
)MmSessionBase
, FALSE
);
101 MiCreateArm3StaticMemoryArea(MmPagedPoolStart
, MmSizeOfPagedPoolInBytes
, FALSE
);
104 MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING
, PAGE_SIZE
, FALSE
);
107 // Reserved HAL area (includes KUSER_SHARED_DATA and KPCR)
108 MiCreateArm3StaticMemoryArea((PVOID
)MM_HAL_VA_START
, MM_HAL_VA_END
- MM_HAL_VA_START
+ 1, FALSE
);
111 // KPCR, one page per CPU. Only for 32-bit kernel.
112 MiCreateArm3StaticMemoryArea(PCR
, PAGE_SIZE
* KeNumberProcessors
, FALSE
);
113 #endif /* _M_AMD64 */
116 MiCreateArm3StaticMemoryArea((PVOID
)KI_USER_SHARED_DATA
, PAGE_SIZE
, FALSE
);
123 MiDbgDumpAddressSpace(VOID
)
126 // Print the memory layout
128 DPRINT1(" 0x%p - 0x%p\t%s\n",
130 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
131 "Boot Loaded Image");
132 DPRINT1(" 0x%p - 0x%p\t%s\n",
134 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
136 DPRINT1(" 0x%p - 0x%p\t%s\n",
138 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
139 "ARM3 Non Paged Pool");
140 DPRINT1(" 0x%p - 0x%p\t%s\n",
142 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
143 "System View Space");
144 DPRINT1(" 0x%p - 0x%p\t%s\n",
148 DPRINT1(" 0x%p - 0x%p\t%s\n",
151 DPRINT1(" 0x%p - 0x%p\t%s\n",
154 DPRINT1(" 0x%p - 0x%p\t%s\n",
155 HYPER_SPACE
, HYPER_SPACE_END
,
157 DPRINT1(" 0x%p - 0x%p\t%s\n",
159 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
161 DPRINT1(" 0x%p - 0x%p\t%s\n",
162 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
164 DPRINT1(" 0x%p - 0x%p\t%s\n",
165 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
166 "Non Paged Pool Expansion PTE Space");
172 MmInitBsmThread(VOID
)
175 OBJECT_ATTRIBUTES ObjectAttributes
;
178 /* Create the thread */
179 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
180 Status
= PsCreateSystemThread(&ThreadHandle
,
188 /* Close the handle and return status */
189 ZwClose(ThreadHandle
);
196 MmInitSystem(IN ULONG Phase
,
197 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
199 extern MMPTE ValidKernelPte
;
201 MMPTE TempPte
= ValidKernelPte
;
202 PFN_NUMBER PageFrameNumber
;
204 /* Initialize the kernel address space */
207 InitializeListHead(&MiSegmentList
);
208 ExInitializeFastMutex(&MiGlobalPageOperation
);
209 KeInitializeEvent(&MmWaitPageEvent
, SynchronizationEvent
, FALSE
);
210 // Until we're fully demand paged, we can do things the old way through
211 // the balance manager
212 MmInitializeMemoryConsumer(MC_CACHE
, MiRosTrimCache
);
214 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
216 /* Intialize system memory areas */
217 MiInitSystemMemoryAreas();
219 /* Dump the address space */
220 MiDbgDumpAddressSpace();
222 MmInitGlobalKernelPageDirectory();
223 MiInitializeUserPfnBitmap();
224 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
225 MmInitializeRmapList();
226 MmInitSectionImplementation();
230 // Create a PTE to double-map the shared data section. We allocate it
231 // from paged pool so that we can't fault when trying to touch the PTE
232 // itself (to map it), since paged pool addresses will already be mapped
233 // by the fault handler.
235 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
238 if (!MmSharedUserDataPte
) return FALSE
;
241 // Now get the PTE for shared data, and read the PFN that holds it
243 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
244 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
245 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
247 /* Build the PTE and write it */
248 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
252 *MmSharedUserDataPte
= TempPte
;
254 /* Initialize session working set support */
255 MiInitializeSessionWsSupport();
257 /* Setup session IDs */
258 MiInitializeSessionIds();
260 /* Setup the memory threshold events */
261 if (!MiInitializeMemoryEvents()) return FALSE
;
266 MiInitBalancerThread();
268 /* Initialize the balance set manager */