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