include/csrss/csrss.h: Include a define for the size of the common
[reactos.git] / reactos / ntoskrnl / mm / mminit.c
1 /* $Id: mminit.c,v 1.26 2001/11/25 15:21:11 dwelch Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * Created 9/4/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <roscfg.h>
16 #include <internal/i386/segment.h>
17 #include <internal/mm.h>
18 #include <internal/ntoskrnl.h>
19 #include <internal/bitops.h>
20 #include <internal/io.h>
21 #include <internal/ps.h>
22 #include <napi/shared_data.h>
23
24 #define NDEBUG
25 #include <internal/debug.h>
26
27 /* GLOBALS *****************************************************************/
28
29 /*
30 * Size of extended memory (kb) (fixed for now)
31 */
32 #define EXTENDED_MEMORY_SIZE (3*1024*1024)
33
34 /*
35 * Compiler defined symbols
36 */
37 extern unsigned int _text_start__;
38 extern unsigned int _text_end__;
39
40 static BOOLEAN IsThisAnNtAsSystem = FALSE;
41 static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
42
43 extern unsigned int _bss_end__;
44
45 static MEMORY_AREA* kernel_text_desc = NULL;
46 static MEMORY_AREA* kernel_data_desc = NULL;
47 static MEMORY_AREA* kernel_param_desc = NULL;
48 static MEMORY_AREA* kernel_pool_desc = NULL;
49 static MEMORY_AREA* kernel_shared_data_desc = NULL;
50
51 PVOID MmSharedDataPagePhysicalAddress = NULL;
52
53 /* FUNCTIONS ****************************************************************/
54
55 BOOLEAN STDCALL MmIsThisAnNtAsSystem(VOID)
56 {
57 return(IsThisAnNtAsSystem);
58 }
59
60 MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID)
61 {
62 return(MmSystemSize);
63 }
64
65 VOID MiShutdownMemoryManager(VOID)
66 {
67 }
68
69 VOID MmInitVirtualMemory(ULONG LastKernelAddress,
70 ULONG KernelLength)
71 /*
72 * FUNCTION: Intialize the memory areas list
73 * ARGUMENTS:
74 * bp = Pointer to the boot parameters
75 * kernel_len = Length of the kernel
76 */
77 {
78 PVOID BaseAddress;
79 ULONG Length;
80 ULONG ParamLength = KernelLength;
81 NTSTATUS Status;
82 //ULONG i;
83
84 DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
85
86 LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
87
88 MmInitMemoryAreas();
89 // ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
90 ExInitNonPagedPool(LastKernelAddress + PAGESIZE);
91
92
93 /*
94 * Setup the system area descriptor list
95 */
96 BaseAddress = (PVOID)KERNEL_BASE;
97 Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE;
98 ParamLength = ParamLength - Length;
99
100 /*
101 * No need to lock the address space at this point since no
102 * other threads are running.
103 */
104 MmCreateMemoryArea(NULL,
105 MmGetKernelAddressSpace(),
106 MEMORY_AREA_SYSTEM,
107 &BaseAddress,
108 Length,
109 0,
110 &kernel_text_desc,
111 FALSE);
112
113 Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
114 PAGE_ROUND_UP(((ULONG)&_text_end__));
115 ParamLength = ParamLength - Length;
116 DPRINT("Length %x\n",Length);
117 BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_text_end__));
118 DPRINT("BaseAddress %x\n",BaseAddress);
119
120 /*
121 * No need to lock the address space at this point since we are
122 * the only thread running.
123 */
124 MmCreateMemoryArea(NULL,
125 MmGetKernelAddressSpace(),
126 MEMORY_AREA_SYSTEM,
127 &BaseAddress,
128 Length,
129 0,
130 &kernel_data_desc,
131 FALSE);
132
133 BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
134 // Length = ParamLength;
135 Length = LastKernelAddress - (ULONG)BaseAddress;
136 MmCreateMemoryArea(NULL,
137 MmGetKernelAddressSpace(),
138 MEMORY_AREA_SYSTEM,
139 &BaseAddress,
140 Length,
141 0,
142 &kernel_param_desc,
143 FALSE);
144
145 BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE);
146 Length = NONPAGED_POOL_SIZE;
147 MmCreateMemoryArea(NULL,
148 MmGetKernelAddressSpace(),
149 MEMORY_AREA_SYSTEM,
150 &BaseAddress,
151 Length,
152 0,
153 &kernel_pool_desc,
154 FALSE);
155
156 /*
157 * Create the kernel mapping of the user/kernel shared memory.
158 */
159 BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE;
160 Length = PAGESIZE;
161 MmCreateMemoryArea(NULL,
162 MmGetKernelAddressSpace(),
163 MEMORY_AREA_SYSTEM,
164 &BaseAddress,
165 Length,
166 0,
167 &kernel_shared_data_desc,
168 FALSE);
169 MmSharedDataPagePhysicalAddress = MmAllocPage(0);
170 Status = MmCreateVirtualMapping(NULL,
171 (PVOID)KERNEL_SHARED_DATA_BASE,
172 PAGE_READWRITE,
173 (ULONG)MmSharedDataPagePhysicalAddress);
174 if (!NT_SUCCESS(Status))
175 {
176 DbgPrint("Unable to create virtual mapping\n");
177 KeBugCheck(0);
178 }
179 ((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
180 }
181
182 VOID MmInit1(ULONG FirstKrnlPhysAddr,
183 ULONG LastKrnlPhysAddr,
184 ULONG LastKernelAddress,
185 PADDRESS_RANGE BIOSMemoryMap,
186 ULONG AddressRangeCount)
187 /*
188 * FUNCTION: Initalize memory managment
189 */
190 {
191 ULONG i;
192 ULONG kernel_len;
193 #ifndef MP
194 extern unsigned int unmap_me, unmap_me2, unmap_me3;
195 #endif
196
197 DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
198 FirstKrnlPhysAddr,
199 LastKrnlPhysAddr,
200 LastKernelAddress);
201
202 if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0))
203 {
204 // If we have a bios memory map, recalulate the the memory size
205 ULONG last = 0;
206 for (i = 0; i < AddressRangeCount; i++)
207 {
208 if (BIOSMemoryMap[i].Type == 1
209 && (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGESIZE -1) / PAGESIZE > last)
210 {
211 last = (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGESIZE -1) / PAGESIZE;
212 }
213 }
214 if ((last - 256) * 4 > KeLoaderBlock.MemHigher)
215 {
216 KeLoaderBlock.MemHigher = (last - 256) * 4;
217 }
218 }
219
220 /*
221 * FIXME: Set this based on the system command line
222 */
223 MmUserProbeAddress = (PVOID)0x7fff0000;
224 MmHighestUserAddress = (PVOID)0x7ffeffff;
225
226 /*
227 * Initialize memory managment statistics
228 */
229 MmStats.NrTotalPages = 0;
230 MmStats.NrSystemPages = 0;
231 MmStats.NrUserPages = 0;
232 MmStats.NrReservedPages = 0;
233 MmStats.NrUserPages = 0;
234 MmStats.NrFreePages = 0;
235 MmStats.NrLockedPages = 0;
236 MmStats.PagingRequestsInLastMinute = 0;
237 MmStats.PagingRequestsInLastFiveMinutes = 0;
238 MmStats.PagingRequestsInLastFifteenMinutes = 0;
239
240 /*
241 * Initialize the kernel address space
242 */
243 MmInitializeKernelAddressSpace();
244
245 /*
246 * Unmap low memory
247 */
248 #ifndef MP
249 /* FIXME: This is broken in SMP mode */
250 //MmDeletePageTable(NULL, 0);
251 #endif
252 /*
253 * Free all pages not used for kernel memory
254 * (we assume the kernel occupies a continuous range of physical
255 * memory)
256 */
257 DPRINT("first krnl %x\nlast krnl %x\n",FirstKrnlPhysAddr,
258 LastKrnlPhysAddr);
259
260 /*
261 * Free physical memory not used by the kernel
262 */
263 MmStats.NrTotalPages = KeLoaderBlock.MemHigher/4;
264 if (!MmStats.NrTotalPages)
265 {
266 DbgPrint("Memory not detected, default to 8 MB\n");
267 MmStats.NrTotalPages = 2048;
268 }
269 else
270 {
271 /* add 1MB for standard memory (not extended) */
272 MmStats.NrTotalPages += 256;
273 }
274 #ifdef BIOS_MEM_FIX
275 MmStats.NrTotalPages += 16;
276 #endif
277 DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024);
278
279 LastKernelAddress = (ULONG)MmInitializePageList(
280 (PVOID)FirstKrnlPhysAddr,
281 (PVOID)LastKrnlPhysAddr,
282 MmStats.NrTotalPages,
283 PAGE_ROUND_UP(LastKernelAddress),
284 BIOSMemoryMap,
285 AddressRangeCount);
286 kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
287
288 /*
289 * Create a trap for null pointer references and protect text
290 * segment
291 */
292 CHECKPOINT;
293 DPRINT("_text_start__ %x _text_end__ %x\n",(int)&_text_start__,(int)&_text_end__);
294 for (i=PAGE_ROUND_UP(((int)&_text_start__));
295 i<PAGE_ROUND_DOWN(((int)&_text_end__));i=i+PAGESIZE)
296 {
297 MmSetPageProtect(NULL,
298 (PVOID)i,
299 PAGE_EXECUTE_READ);
300 }
301
302 DPRINT("Invalidating between %x and %x\n",
303 LastKernelAddress,
304 KERNEL_BASE + PAGE_TABLE_SIZE);
305 for (i=(LastKernelAddress);
306 i<(KERNEL_BASE + PAGE_TABLE_SIZE);
307 i=i+PAGESIZE)
308 {
309 MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL);
310 }
311 DPRINT("Almost done MmInit()\n");
312 #ifndef MP
313 /* FIXME: This is broken in SMP mode */
314 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, FALSE, NULL, NULL);
315 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, FALSE, NULL, NULL);
316 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, FALSE, NULL, NULL);
317 #endif
318 /*
319 * Intialize memory areas
320 */
321 MmInitVirtualMemory(LastKernelAddress, kernel_len);
322 }
323
324 VOID MmInit2(VOID)
325 {
326 MmInitSectionImplementation();
327 MmInitPagingFile();
328 }
329
330 VOID MmInit3(VOID)
331 {
332 MmInitPagerThread();
333 MmCreatePhysicalMemorySection();
334
335 /* FIXME: Read parameters from memory */
336 }
337