1 /* $Id: mm.c,v 1.30 2000/05/24 22:29:36 dwelch Exp $
3 * COPYRIGHT: See COPYING in the top directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/mm.c
6 * PURPOSE: kernel memory managment functions
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/hal/io.h>
16 #include <internal/i386/segment.h>
17 #include <internal/stddef.h>
18 #include <internal/mm.h>
20 #include <internal/string.h>
21 #include <internal/ntoskrnl.h>
22 #include <internal/bitops.h>
23 #include <internal/string.h>
24 #include <internal/io.h>
26 #include <internal/mmhal.h>
29 #include <internal/debug.h>
31 /* GLOBALS *****************************************************************/
34 * Size of extended memory (kb) (fixed for now)
36 #define EXTENDED_MEMORY_SIZE (3*1024*1024)
39 * Compiler defined symbol
41 extern unsigned int stext
;
42 extern unsigned int etext
;
43 extern unsigned int end
;
45 static BOOLEAN IsThisAnNtAsSystem
= FALSE
;
46 static MM_SYSTEM_SIZE MmSystemSize
= MmSmallSystem
;
48 extern unsigned int etext
;
49 extern unsigned int _bss_end__
;
51 static MEMORY_AREA
* kernel_text_desc
= NULL
;
52 static MEMORY_AREA
* kernel_data_desc
= NULL
;
53 static MEMORY_AREA
* kernel_param_desc
= NULL
;
54 static MEMORY_AREA
* kernel_pool_desc
= NULL
;
56 ULONG EXPORTED MmUserProbeAddress
[PAGESIZE
] = {0,}; /* FIXME */
57 PVOID EXPORTED MmHighestUserAddress
= NULL
; /* FIXME */
59 /* FUNCTIONS ****************************************************************/
61 VOID
MiShutdownMemoryManager(VOID
)
65 VOID
MmInitVirtualMemory(boot_param
* bp
)
67 * FUNCTION: Intialize the memory areas list
69 * bp = Pointer to the boot parameters
70 * kernel_len = Length of the kernel
73 unsigned int kernel_len
= bp
->end_mem
- bp
->start_mem
;
76 ULONG ParamLength
= kernel_len
;
78 DPRINT("MmInitVirtualMemory(%x)\n",bp
);
81 ExInitNonPagedPool(KERNEL_BASE
+ PAGE_ROUND_UP(kernel_len
) + PAGESIZE
);
85 * Setup the system area descriptor list
87 BaseAddress
= (PVOID
)KERNEL_BASE
;
88 Length
= PAGE_ROUND_UP(((ULONG
)&etext
)) - KERNEL_BASE
;
89 ParamLength
= ParamLength
- Length
;
90 MmCreateMemoryArea(NULL
,
91 MmGetKernelAddressSpace(),
98 Length
= PAGE_ROUND_UP(((ULONG
)&_bss_end__
)) -
99 PAGE_ROUND_UP(((ULONG
)&etext
));
100 ParamLength
= ParamLength
- Length
;
101 DPRINT("Length %x\n",Length
);
102 BaseAddress
= (PVOID
)PAGE_ROUND_UP(((ULONG
)&etext
));
103 DPRINT("BaseAddress %x\n",BaseAddress
);
104 MmCreateMemoryArea(NULL
,
105 MmGetKernelAddressSpace(),
112 BaseAddress
= (PVOID
)PAGE_ROUND_UP(((ULONG
)&end
));
113 Length
= ParamLength
;
114 MmCreateMemoryArea(NULL
,
115 MmGetKernelAddressSpace(),
122 BaseAddress
= (PVOID
)(KERNEL_BASE
+ PAGE_ROUND_UP(kernel_len
) + PAGESIZE
);
123 Length
= NONPAGED_POOL_SIZE
;
124 MmCreateMemoryArea(NULL
,
125 MmGetKernelAddressSpace(),
132 // MmDumpMemoryAreas();
133 DPRINT("MmInitVirtualMemory() done\n");
136 NTSTATUS
MmAccessFault(KPROCESSOR_MODE Mode
,
139 return(STATUS_UNSUCCESSFUL
);
142 NTSTATUS
MmNotPresentFault(KPROCESSOR_MODE Mode
,
145 PMADDRESS_SPACE AddressSpace
;
146 MEMORY_AREA
* MemoryArea
;
149 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
151 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
153 DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
154 return(STATUS_UNSUCCESSFUL
);
156 if (PsGetCurrentProcess() == NULL
)
158 DbgPrint("No current process\n");
159 return(STATUS_UNSUCCESSFUL
);
163 * Find the memory area for the faulting address
165 if (Address
>= KERNEL_BASE
)
170 if (Mode
!= KernelMode
)
172 DbgPrint("%s:%d\n",__FILE__
,__LINE__
);
173 return(STATUS_UNSUCCESSFUL
);
175 AddressSpace
= MmGetKernelAddressSpace();
179 AddressSpace
= &PsGetCurrentProcess()->Pcb
.AddressSpace
;
182 MmLockAddressSpace(AddressSpace
);
183 MemoryArea
= MmOpenMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
184 if (MemoryArea
== NULL
)
186 DbgPrint("%s:%d\n",__FILE__
,__LINE__
);
187 MmUnlockAddressSpace(AddressSpace
);
188 return(STATUS_UNSUCCESSFUL
);
191 switch (MemoryArea
->Type
)
193 case MEMORY_AREA_SYSTEM
:
194 Status
= STATUS_UNSUCCESSFUL
;
197 case MEMORY_AREA_SECTION_VIEW_COMMIT
:
198 Status
= MmNotPresentFaultSectionView(AddressSpace
,
203 case MEMORY_AREA_COMMIT
:
204 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
210 Status
= STATUS_UNSUCCESSFUL
;
213 DPRINT("Completed page fault handling\n");
214 MmUnlockAddressSpace(AddressSpace
);
218 BOOLEAN STDCALL
MmIsThisAnNtAsSystem(VOID
)
220 return(IsThisAnNtAsSystem
);
223 MM_SYSTEM_SIZE STDCALL
MmQuerySystemSize(VOID
)
225 return(MmSystemSize
);
228 void MmInitialize(boot_param
* bp
, ULONG LastKernelAddress
)
230 * FUNCTION: Initalize memory managment
233 unsigned int first_krnl_phys_addr
;
234 unsigned int last_krnl_phys_addr
;
236 unsigned int kernel_len
;
238 DPRINT("MmInitialize(bp %x, LastKernelAddress %x)\n", bp
,
244 MmDeletePageTable(NULL
, 0);
247 * Free all pages not used for kernel memory
248 * (we assume the kernel occupies a continuous range of physical
251 first_krnl_phys_addr
= bp
->start_mem
;
252 last_krnl_phys_addr
= bp
->end_mem
;
253 DPRINT("first krnl %x\nlast krnl %x\n",first_krnl_phys_addr
,
254 last_krnl_phys_addr
);
257 * Free physical memory not used by the kernel
259 LastKernelAddress
= (ULONG
)MmInitializePageList(
260 (PVOID
)first_krnl_phys_addr
,
261 (PVOID
)last_krnl_phys_addr
,
263 PAGE_ROUND_UP(LastKernelAddress
));
264 kernel_len
= last_krnl_phys_addr
- first_krnl_phys_addr
;
267 * Create a trap for null pointer references and protect text
271 DPRINT("stext %x etext %x\n",(int)&stext
,(int)&etext
);
272 for (i
=PAGE_ROUND_UP(((int)&stext
));
273 i
<PAGE_ROUND_DOWN(((int)&etext
));i
=i
+PAGESIZE
)
275 MmSetPageProtect(NULL
,
280 DPRINT("Invalidating between %x and %x\n",
282 KERNEL_BASE
+ PAGE_TABLE_SIZE
);
283 for (i
=(LastKernelAddress
);
284 i
<(KERNEL_BASE
+ PAGE_TABLE_SIZE
);
287 MmSetPage(NULL
, (PVOID
)(i
), PAGE_NOACCESS
, 0);
289 DPRINT("Almost done MmInit()\n");
292 * Intialize memory areas
294 MmInitVirtualMemory(bp
);
297 VOID
MmInitSystem (ULONG Phase
, boot_param
* bp
, ULONG LastKernelAddress
)
301 /* Phase 0 Initialization */
302 MmInitializeKernelAddressSpace();
303 MmInitialize (bp
, LastKernelAddress
);
307 /* Phase 1 Initialization */
308 MmInitSectionImplementation();
314 /* Miscellanea functions: they may fit somewhere else */
318 MmAdjustWorkingSetSize (
331 MmDbgTranslatePhysicalAddress (
348 return (STATUS_NOT_IMPLEMENTED
);
354 MmSetAddressRangeModified (