Implemented /Device/PhysicalMemory
[reactos.git] / reactos / ntoskrnl / mm / mminit.c
1 /* $Id: mminit.c,v 1.12 2000/12/28 03:38:07 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 <internal/mmhal.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 symbol s
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
83 DPRINT("MmInitVirtualMemory(%x)\n",bp);
84
85 LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
86
87 MmInitMemoryAreas();
88 // ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
89 ExInitNonPagedPool(LastKernelAddress + PAGESIZE);
90
91
92 /*
93 * Setup the system area descriptor list
94 */
95 BaseAddress = (PVOID)KERNEL_BASE;
96 Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE;
97 ParamLength = ParamLength - Length;
98 MmCreateMemoryArea(NULL,
99 MmGetKernelAddressSpace(),
100 MEMORY_AREA_SYSTEM,
101 &BaseAddress,
102 Length,
103 0,
104 &kernel_text_desc);
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
120 BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
121 // Length = ParamLength;
122 Length = LastKernelAddress - (ULONG)BaseAddress;
123 MmCreateMemoryArea(NULL,
124 MmGetKernelAddressSpace(),
125 MEMORY_AREA_SYSTEM,
126 &BaseAddress,
127 Length,
128 0,
129 &kernel_param_desc);
130
131 BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE);
132 Length = NONPAGED_POOL_SIZE;
133 MmCreateMemoryArea(NULL,
134 MmGetKernelAddressSpace(),
135 MEMORY_AREA_SYSTEM,
136 &BaseAddress,
137 Length,
138 0,
139 &kernel_pool_desc);
140
141 BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE;
142 Length = PAGESIZE;
143 MmCreateMemoryArea(NULL,
144 MmGetKernelAddressSpace(),
145 MEMORY_AREA_SYSTEM,
146 &BaseAddress,
147 Length,
148 0,
149 &kernel_shared_data_desc);
150 MmSharedDataPagePhysicalAddress = MmAllocPage(0);
151 Status = MmCreateVirtualMapping(NULL,
152 (PVOID)KERNEL_SHARED_DATA_BASE,
153 PAGE_READWRITE,
154 (ULONG)MmSharedDataPagePhysicalAddress);
155 if (!NT_SUCCESS(Status))
156 {
157 DbgPrint("Unable to create virtual mapping\n");
158 KeBugCheck(0);
159 }
160 ((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
161
162 // MmDumpMemoryAreas();
163 DPRINT("MmInitVirtualMemory() done\n");
164 }
165
166 VOID MmInit1(ULONG FirstKrnlPhysAddr,
167 ULONG LastKrnlPhysAddr,
168 ULONG LastKernelAddress)
169 /*
170 * FUNCTION: Initalize memory managment
171 */
172 {
173 ULONG i;
174 ULONG kernel_len;
175
176 DPRINT("MmInit1(bp %x, LastKernelAddress %x)\n", bp,
177 LastKernelAddress);
178
179 /*
180 * FIXME: Set this based on the system command line
181 */
182 MmUserProbeAddress = (PVOID)0x7fff0000;
183 MmHighestUserAddress = (PVOID)0x7ffeffff;
184
185 /*
186 * Initialize memory managment statistics
187 */
188 MmStats.NrTotalPages = 0;
189 MmStats.NrSystemPages = 0;
190 MmStats.NrUserPages = 0;
191 MmStats.NrReservedPages = 0;
192 MmStats.NrUserPages = 0;
193 MmStats.NrFreePages = 0;
194 MmStats.NrLockedPages = 0;
195 MmStats.PagingRequestsInLastMinute = 0;
196 MmStats.PagingRequestsInLastFiveMinutes = 0;
197 MmStats.PagingRequestsInLastFifteenMinutes = 0;
198
199 /*
200 * Initialize the kernel address space
201 */
202 MmInitializeKernelAddressSpace();
203
204 /*
205 * Unmap low memory
206 */
207 MmDeletePageTable(NULL, 0);
208
209 /*
210 * Free all pages not used for kernel memory
211 * (we assume the kernel occupies a continuous range of physical
212 * memory)
213 */
214 DPRINT("first krnl %x\nlast krnl %x\n",FirstKrnlPhysAddr,
215 LastKrnlPhysAddr);
216
217 /*
218 * Free physical memory not used by the kernel
219 */
220 MmStats.NrTotalPages = KeLoaderBlock.MemLower/4;
221 if ( !MmStats.NrTotalPages )
222 {
223 DbgPrint("Memory not detected, default to 8 MB\n");
224 MmStats.NrTotalPages = 2048;
225 }
226 else
227 MmStats.NrTotalPages += 256;// add 1MB for standard memory (not extended)
228 LastKernelAddress = (ULONG)MmInitializePageList(
229 (PVOID)FirstKrnlPhysAddr,
230 (PVOID)LastKrnlPhysAddr,
231 // 1024,
232 MmStats.NrTotalPages ,
233 PAGE_ROUND_UP(LastKernelAddress));
234 kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
235
236 /*
237 * Create a trap for null pointer references and protect text
238 * segment
239 */
240 CHECKPOINT;
241 DPRINT("stext %x etext %x\n",(int)&stext,(int)&etext);
242 for (i=PAGE_ROUND_UP(((int)&_text_start__));
243 i<PAGE_ROUND_DOWN(((int)&_text_end__));i=i+PAGESIZE)
244 {
245 MmSetPageProtect(NULL,
246 (PVOID)i,
247 PAGE_EXECUTE_READ);
248 }
249
250 DPRINT("Invalidating between %x and %x\n",
251 LastKernelAddress,
252 KERNEL_BASE + PAGE_TABLE_SIZE);
253 for (i=(LastKernelAddress);
254 i<(KERNEL_BASE + PAGE_TABLE_SIZE);
255 i=i+PAGESIZE)
256 {
257 MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE);
258 }
259 DPRINT("Almost done MmInit()\n");
260
261 /*
262 * Intialize memory areas
263 */
264 MmInitVirtualMemory(LastKernelAddress, kernel_len);
265 }
266
267 VOID MmInit2(VOID)
268 {
269 MmInitSectionImplementation();
270 MmInitPagingFile();
271 }
272
273 VOID MmInit3(VOID)
274 {
275 MmInitPagerThread();
276 MmCreatePhysicalMemorySection();
277
278 /* FIXME: Read parameters from memory */
279 }
280