1 /* $Id: mminit.c,v 1.39 2002/09/07 15:13:00 chorns Exp $
3 * COPYRIGHT: See COPYING in the top directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/mminit.c
6 * PURPOSE: kernel memory managment initialization functions
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
17 #include <internal/debug.h>
20 /* GLOBALS *****************************************************************/
23 * Size of extended memory (kb) (fixed for now)
25 #define EXTENDED_MEMORY_SIZE (3*1024*1024)
28 * Compiler defined symbols
30 extern unsigned int _text_start__
;
31 extern unsigned int _text_end__
;
33 static BOOLEAN IsThisAnNtAsSystem
= FALSE
;
34 static MM_SYSTEM_SIZE MmSystemSize
= MmSmallSystem
;
36 extern unsigned int _bss_end__
;
38 static MEMORY_AREA
* kernel_text_desc
= NULL
;
39 static MEMORY_AREA
* kernel_data_desc
= NULL
;
40 static MEMORY_AREA
* kernel_param_desc
= NULL
;
41 static MEMORY_AREA
* kernel_pool_desc
= NULL
;
42 static MEMORY_AREA
* kernel_shared_data_desc
= NULL
;
43 static MEMORY_AREA
* MiPagedPoolDescriptor
= NULL
;
45 PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
47 PVOID MiHighestUserAddress
= NULL
;
48 PVOID
* MmHighestUserAddress
= &MiHighestUserAddress
;
49 ULONG MiUserProbeAddress
= 0;
50 ULONG
* MmUserProbeAddress
= &MiUserProbeAddress
;
53 /* FUNCTIONS ****************************************************************/
55 BOOLEAN STDCALL
MmIsThisAnNtAsSystem(VOID
)
57 return(IsThisAnNtAsSystem
);
60 MM_SYSTEM_SIZE STDCALL
MmQuerySystemSize(VOID
)
65 VOID
MiShutdownMemoryManager(VOID
)
69 VOID
MmInitVirtualMemory(ULONG LastKernelAddress
,
72 * FUNCTION: Intialize the memory areas list
74 * bp = Pointer to the boot parameters
75 * kernel_len = Length of the kernel
80 ULONG ParamLength
= KernelLength
;
84 DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress
, KernelLength
);
86 LastKernelAddress
= PAGE_ROUND_UP(LastKernelAddress
);
89 ExInitNonPagedPool(LastKernelAddress
+ PAGE_SIZE
);
92 * Setup the system area descriptor list
94 BaseAddress
= (PVOID
)KERNEL_BASE
;
95 Length
= PAGE_ROUND_UP(((ULONG
)&_text_end__
)) - KERNEL_BASE
;
96 ParamLength
= ParamLength
- Length
;
99 * No need to lock the address space at this point since no
100 * other threads are running.
102 MmCreateMemoryArea(NULL
,
103 MmGetKernelAddressSpace(),
111 Length
= PAGE_ROUND_UP(((ULONG
)&_bss_end__
)) -
112 PAGE_ROUND_UP(((ULONG
)&_text_end__
));
113 ParamLength
= ParamLength
- Length
;
114 DPRINT("Length %x\n",Length
);
115 BaseAddress
= (PVOID
)PAGE_ROUND_UP(((ULONG
)&_text_end__
));
116 DPRINT("BaseAddress %x\n",BaseAddress
);
119 * No need to lock the address space at this point since we are
120 * the only thread running.
122 MmCreateMemoryArea(NULL
,
123 MmGetKernelAddressSpace(),
131 BaseAddress
= (PVOID
)PAGE_ROUND_UP(((ULONG
)&_bss_end__
));
132 // Length = ParamLength;
133 Length
= LastKernelAddress
- (ULONG
)BaseAddress
;
134 MmCreateMemoryArea(NULL
,
135 MmGetKernelAddressSpace(),
143 BaseAddress
= (PVOID
)(LastKernelAddress
+ PAGE_SIZE
);
144 Length
= NONPAGED_POOL_SIZE
;
145 MmCreateMemoryArea(NULL
,
146 MmGetKernelAddressSpace(),
154 MmPagedPoolSize
= MM_PAGED_POOL_SIZE
;
155 BaseAddress
= (PVOID
)(LastKernelAddress
+ PAGE_SIZE
+ NONPAGED_POOL_SIZE
+
157 MmPagedPoolBase
= BaseAddress
;
158 Length
= MM_PAGED_POOL_SIZE
;
159 MmCreateMemoryArea(NULL
,
160 MmGetKernelAddressSpace(),
161 MEMORY_AREA_PAGED_POOL
,
165 &MiPagedPoolDescriptor
,
167 MmInitializePagedPool();
170 * Create the kernel mapping of the user/kernel shared memory.
172 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
174 MmCreateMemoryArea(NULL
,
175 MmGetKernelAddressSpace(),
180 &kernel_shared_data_desc
,
182 Status
= MmRequestPageMemoryConsumer(MC_NPPOOL
, TRUE
,
183 &MmSharedDataPagePhysicalAddress
);
184 Status
= MmCreateVirtualMapping(NULL
,
185 (PVOID
)KI_USER_SHARED_DATA
,
187 MmSharedDataPagePhysicalAddress
,
189 if (!NT_SUCCESS(Status
))
191 DbgPrint("Unable to create virtual mapping\n");
194 RtlZeroMemory(BaseAddress
, Length
);
199 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
202 VOID
MmInit1(ULONG FirstKrnlPhysAddr
,
203 ULONG LastKrnlPhysAddr
,
204 ULONG LastKernelAddress
,
205 PADDRESS_RANGE BIOSMemoryMap
,
206 ULONG AddressRangeCount
)
208 * FUNCTION: Initalize memory managment
214 extern unsigned int unmap_me
, unmap_me2
, unmap_me3
;
217 DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
222 if ((BIOSMemoryMap
!= NULL
) && (AddressRangeCount
> 0))
224 // If we have a bios memory map, recalulate the the memory size
226 for (i
= 0; i
< AddressRangeCount
; i
++)
228 if (BIOSMemoryMap
[i
].Type
== 1
229 && (BIOSMemoryMap
[i
].BaseAddrLow
+ BIOSMemoryMap
[i
].LengthLow
+ PAGE_SIZE
-1) / PAGE_SIZE
> last
)
231 last
= (BIOSMemoryMap
[i
].BaseAddrLow
+ BIOSMemoryMap
[i
].LengthLow
+ PAGE_SIZE
-1) / PAGE_SIZE
;
234 if ((last
- 256) * 4 > KeLoaderBlock
.MemHigher
)
236 KeLoaderBlock
.MemHigher
= (last
- 256) * 4;
241 * FIXME: Set this based on the system command line
243 MiUserProbeAddress
= (ULONG
)0x7fff0000;
244 MiHighestUserAddress
= (PVOID
)0x7ffeffff;
247 * Initialize memory managment statistics
249 MmStats
.NrTotalPages
= 0;
250 MmStats
.NrSystemPages
= 0;
251 MmStats
.NrUserPages
= 0;
252 MmStats
.NrReservedPages
= 0;
253 MmStats
.NrUserPages
= 0;
254 MmStats
.NrFreePages
= 0;
255 MmStats
.NrLockedPages
= 0;
256 MmStats
.PagingRequestsInLastMinute
= 0;
257 MmStats
.PagingRequestsInLastFiveMinutes
= 0;
258 MmStats
.PagingRequestsInLastFifteenMinutes
= 0;
261 * Initialize the kernel address space
263 MmInitializeKernelAddressSpace();
269 /* FIXME: This is broken in SMP mode */
270 MmDeletePageTable(NULL
, 0);
273 * Free all pages not used for kernel memory
274 * (we assume the kernel occupies a continuous range of physical
277 DPRINT("first krnl %x\nlast krnl %x\n",FirstKrnlPhysAddr
,
281 * Free physical memory not used by the kernel
283 MmStats
.NrTotalPages
= KeLoaderBlock
.MemHigher
/4;
284 if (!MmStats
.NrTotalPages
)
286 DbgPrint("Memory not detected, default to 8 MB\n");
287 MmStats
.NrTotalPages
= 2048;
291 /* add 1MB for standard memory (not extended) */
292 MmStats
.NrTotalPages
+= 256;
295 MmStats
.NrTotalPages
+= 16;
297 DbgPrint("Used memory %dKb\n", (MmStats
.NrTotalPages
* PAGE_SIZE
) / 1024);
299 LastKernelAddress
= (ULONG
)MmInitializePageList(
300 (PVOID
)FirstKrnlPhysAddr
,
301 (PVOID
)LastKrnlPhysAddr
,
302 MmStats
.NrTotalPages
,
303 PAGE_ROUND_UP(LastKernelAddress
),
306 kernel_len
= LastKrnlPhysAddr
- FirstKrnlPhysAddr
;
309 * Create a trap for null pointer references and protect text
313 DPRINT("_text_start__ %x _text_end__ %x\n",(int)&_text_start__
,(int)&_text_end__
);
314 for (i
=PAGE_ROUND_UP(((int)&_text_start__
));
315 i
<PAGE_ROUND_DOWN(((int)&_text_end__
));i
=i
+PAGE_SIZE
)
317 MmSetPageProtect(NULL
,
322 DPRINT("Invalidating between %x and %x\n",
324 KERNEL_BASE
+ 2 * PAGE_TABLE_SIZE
);
325 for (i
=(LastKernelAddress
);
326 i
<(KERNEL_BASE
+ 2 * PAGE_TABLE_SIZE
);
329 MmDeleteVirtualMapping(NULL
, (PVOID
)(i
), FALSE
, NULL
, NULL
);
331 DPRINT("Almost done MmInit()\n");
333 /* FIXME: This is broken in SMP mode */
334 MmDeleteVirtualMapping(NULL
, (PVOID
)&unmap_me
, FALSE
, NULL
, NULL
);
335 MmDeleteVirtualMapping(NULL
, (PVOID
)&unmap_me2
, FALSE
, NULL
, NULL
);
336 MmDeleteVirtualMapping(NULL
, (PVOID
)&unmap_me3
, FALSE
, NULL
, NULL
);
339 * Intialize memory areas
341 MmInitVirtualMemory(LastKernelAddress
, kernel_len
);
343 MmInitializeMdlImplementation();
348 MmInitSectionImplementation();
355 MmCreatePhysicalMemorySection();
356 MmInitializeRmapList();
359 * Initialise the modified page writer.
363 /* FIXME: Read parameters from memory */