-/* $Id: mminit.c,v 1.64 2004/08/01 07:24:58 hbirr Exp $
+/* $Id$
*
- * COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/mminit.c
- * PURPOSE: kernel memory managment initialization functions
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * Created 9/4/98
+ * COPYRIGHT: See COPYING in the top directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/mminit.c
+ * PURPOSE: Kernel memory managment initialization functions
+ *
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-#include <internal/i386/segment.h>
-#include <internal/mm.h>
-#include <internal/ntoskrnl.h>
-#include <internal/io.h>
-#include <internal/ps.h>
-#include <internal/pool.h>
-
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
static BOOLEAN IsThisAnNtAsSystem = FALSE;
static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
-static MEMORY_AREA* kernel_text_desc = NULL;
-static MEMORY_AREA* kernel_init_desc = NULL;
-static MEMORY_AREA* kernel_map_desc = NULL;
-static MEMORY_AREA* kernel_kpcr_desc = NULL;
-static MEMORY_AREA* kernel_data_desc = NULL;
-static MEMORY_AREA* kernel_param_desc = NULL;
-static MEMORY_AREA* kernel_pool_desc = NULL;
-static MEMORY_AREA* kernel_shared_data_desc = NULL;
-static MEMORY_AREA* kernel_mapped_vga_framebuffer_desc = NULL;
-static MEMORY_AREA* MiKernelMapDescriptor = NULL;
-static MEMORY_AREA* MiPagedPoolDescriptor = NULL;
-
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
PVOID MiNonPagedPoolStart;
ULONG MiNonPagedPoolLength;
-PVOID MiKernelMapStart;
-ULONG MiKernelMapLength;
+
+extern ULONG init_stack;
+extern ULONG init_stack_top;
/* FUNCTIONS ****************************************************************/
return(MmSystemSize);
}
-VOID MiShutdownMemoryManager(VOID)
+VOID
+NTAPI
+MiShutdownMemoryManager(VOID)
{}
-VOID INIT_FUNCTION
-MmInitVirtualMemory(ULONG LastKernelAddress,
+VOID
+INIT_FUNCTION
+NTAPI
+MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
ULONG KernelLength)
/*
* FUNCTION: Intialize the memory areas list
NTSTATUS Status;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PFN_TYPE Pfn;
+ PMEMORY_AREA MArea;
DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
MmInitMemoryAreas();
- /* Don't change the start of kernel map. Pte's must always exist for this region. */
- MiKernelMapStart = (char*)LastKernelAddress + PAGE_SIZE;
- MiKernelMapLength = MM_KERNEL_MAP_SIZE;
-
- MiNonPagedPoolStart = (char*)MiKernelMapStart + MiKernelMapLength + PAGE_SIZE;
+ /* Start the paged and nonpaged pool at a 4MB boundary. */
+ MiNonPagedPoolStart = (PVOID)ROUND_UP((ULONG_PTR)LastKernelAddress + PAGE_SIZE, 0x400000);
MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE;
- MmPagedPoolBase = (char*)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE;
+ MmPagedPoolBase = (PVOID)ROUND_UP((ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE, 0x400000);
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
+ DPRINT("NonPagedPool %x - %x, PagedPool %x - %x\n", MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength - 1,
+ MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize - 1);
- MiInitKernelMap();
MiInitializeNonPagedPool();
/*
* Setup the system area descriptor list
*/
- BaseAddress = (PVOID)0xf0000000;
+ MiInitPageDirectoryMap();
+
+ BaseAddress = (PVOID)KPCR_BASE;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
- 0x400000,
+ PAGE_SIZE * MAXIMUM_PROCESSORS,
0,
- &kernel_map_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
- BaseAddress = (PVOID)KPCR_BASE;
+ /* Local APIC base */
+ BaseAddress = (PVOID)0xFEE00000;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
- PAGE_SIZE * MAXIMUM_PROCESSORS,
+ PAGE_SIZE,
0,
- &kernel_kpcr_desc,
+ &MArea,
+ TRUE,
FALSE,
+ BoundaryAddressMultiple);
+
+ /* i/o APIC base */
+ BaseAddress = (PVOID)0xFEC00000;
+ MmCreateMemoryArea(NULL,
+ MmGetKernelAddressSpace(),
+ MEMORY_AREA_SYSTEM,
+ &BaseAddress,
+ PAGE_SIZE,
+ 0,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
&BaseAddress,
0x20000,
0,
- &kernel_mapped_vga_framebuffer_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
BaseAddress = (PVOID)KERNEL_BASE;
- Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE;
+ Length = PAGE_ROUND_UP(((ULONG_PTR)&_text_end__)) - KERNEL_BASE;
ParamLength = ParamLength - Length;
/*
&BaseAddress,
Length,
0,
- &kernel_text_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_text_end__));
- assert (BaseAddress == (PVOID)&_init_start__);
- Length = PAGE_ROUND_UP(((ULONG)&_init_end__)) -
- PAGE_ROUND_UP(((ULONG)&_text_end__));
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_text_end__));
+ ASSERT(BaseAddress == (PVOID)&_init_start__);
+ Length = PAGE_ROUND_UP(((ULONG_PTR)&_init_end__)) -
+ PAGE_ROUND_UP(((ULONG_PTR)&_text_end__));
ParamLength = ParamLength - Length;
MmCreateMemoryArea(NULL,
&BaseAddress,
Length,
0,
- &kernel_init_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
- Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
- PAGE_ROUND_UP(((ULONG)&_init_end__));
+ Length = PAGE_ROUND_UP(((ULONG_PTR)&_bss_end__)) -
+ PAGE_ROUND_UP(((ULONG_PTR)&_init_end__));
ParamLength = ParamLength - Length;
DPRINT("Length %x\n",Length);
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_init_end__));
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_init_end__));
DPRINT("BaseAddress %x\n",BaseAddress);
/*
&BaseAddress,
Length,
0,
- &kernel_data_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
- Length = LastKernelAddress - (ULONG)BaseAddress;
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_bss_end__));
+ Length = LastKernelAddress - (ULONG_PTR)BaseAddress;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
Length,
0,
- &kernel_param_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
&BaseAddress,
MiNonPagedPoolLength,
0,
- &kernel_pool_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
- BaseAddress = MiKernelMapStart;
- Status = MmCreateMemoryArea(NULL,
- MmGetKernelAddressSpace(),
- MEMORY_AREA_SYSTEM,
- &BaseAddress,
- MiKernelMapLength,
- 0,
- &MiKernelMapDescriptor,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
-
BaseAddress = MmPagedPoolBase;
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
&BaseAddress,
MmPagedPoolSize,
0,
- &MiPagedPoolDescriptor,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
&BaseAddress,
Length,
0,
- &kernel_shared_data_desc,
- FALSE,
+ &MArea,
+ TRUE,
FALSE,
BoundaryAddressMultiple);
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pfn);
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
}
-VOID INIT_FUNCTION
-MmInit1(ULONG FirstKrnlPhysAddr,
- ULONG LastKrnlPhysAddr,
- ULONG LastKernelAddress,
+VOID
+INIT_FUNCTION
+NTAPI
+MmInit1(ULONG_PTR FirstKrnlPhysAddr,
+ ULONG_PTR LastKrnlPhysAddr,
+ ULONG_PTR LastKernelAddress,
PADDRESS_RANGE BIOSMemoryMap,
ULONG AddressRangeCount,
ULONG MaxMem)
{
ULONG i;
ULONG kernel_len;
-#ifndef MP
+ ULONG_PTR MappingAddress;
- extern unsigned int unmap_me, unmap_me2, unmap_me3;
-#endif
-
- DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
+ DPRINT("MmInit1(FirstKrnlPhysAddr, %p, LastKrnlPhysAddr %p, LastKernelAddress %p)\n",
FirstKrnlPhysAddr,
LastKrnlPhysAddr,
LastKernelAddress);
-
if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0))
{
// If we have a bios memory map, recalulate the memory size
KeLoaderBlock.MemHigher = (MaxMem - 1) * 1024;
}
- /*
- * FIXME: Set this based on the system command line
- */
- MmSystemRangeStart = (PVOID)KERNEL_BASE; // 0xC0000000
- MmUserProbeAddress = (PVOID)0x7fff0000;
- MmHighestUserAddress = (PVOID)0x7ffeffff;
-
- MmInitGlobalKernelPageDirectory();
+ /* Set memory limits */
+ MmUserProbeAddress = (ULONG_PTR)MmSystemRangeStart - 0x10000;
+ MmHighestUserAddress = (PVOID)(MmUserProbeAddress - 1);
/*
* Initialize memory managment statistics
MmStats.PagingRequestsInLastFiveMinutes = 0;
MmStats.PagingRequestsInLastFifteenMinutes = 0;
- /*
- * Initialize the kernel address space
- */
- MmInitializeKernelAddressSpace();
-
- /*
- * Unmap low memory
- */
-#ifndef MP
- /* In SMP mode we unmap the low memory in MmInit3.
- The APIC needs the mapping of the first pages
- while the processors are starting up. */
- MmDeletePageTable(NULL, 0);
-#endif
/*
* Free all pages not used for kernel memory
* (we assume the kernel occupies a continuous range of physical
MmStats.NrTotalPages += 16;
#endif
+ /*
+ * Initialize the kernel address space
+ */
+ MmInitializeKernelAddressSpace();
+
+ MmInitGlobalKernelPageDirectory();
+
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024);
+ DPRINT1("Kernel Stack Limits. InitTop = 0x%x, Init = 0x%x\n", init_stack_top, init_stack);
- LastKernelAddress = (ULONG)MmInitializePageList((PVOID)FirstKrnlPhysAddr,
- (PVOID)LastKrnlPhysAddr,
+ LastKernelAddress = (ULONG_PTR)MmInitializePageList(
+ FirstKrnlPhysAddr,
+ LastKrnlPhysAddr,
MmStats.NrTotalPages,
PAGE_ROUND_UP(LastKernelAddress),
BIOSMemoryMap,
kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
/*
- * Create a trap for null pointer references and protect text
- * segment
+ * Unmap low memory
*/
- CHECKPOINT;
- DPRINT("_text_start__ %x _init_end__ %x\n",(int)&_text_start__,(int)&_init_end__);
- for (i=PAGE_ROUND_DOWN(((int)&_text_start__));
- i<PAGE_ROUND_UP(((int)&_init_end__));i=i+PAGE_SIZE)
- {
- MmSetPageProtect(NULL,
- (PVOID)i,
- PAGE_EXECUTE_READ);
- }
-
- DPRINT("Invalidating between %x and %x\n",
- LastKernelAddress, 0xc0600000);
- for (i=(LastKernelAddress); i<0xc0600000; i+=PAGE_SIZE)
+#ifdef CONFIG_SMP
+ /* In SMP mode we unmap the low memory pagetable in MmInit3.
+ The APIC needs the mapping of the first pages
+ while the processors are starting up.
+ We unmap all pages except page 2 and 3. */
+ for (MappingAddress = 0;
+ MappingAddress < 1024 * PAGE_SIZE;
+ MappingAddress += PAGE_SIZE)
{
- MmRawDeleteVirtualMapping((PVOID)(i));
+ if (MappingAddress != 2 * PAGE_SIZE &&
+ MappingAddress != 3 * PAGE_SIZE)
+ {
+ MmRawDeleteVirtualMapping((PVOID)MappingAddress);
+ }
}
+#else
+ MmDeletePageTable(NULL, 0);
+#endif
DPRINT("Invalidating between %x and %x\n",
- 0xd0100000, 0xd0400000);
- for (i=0xd0100000; i<0xd0400000; i+=PAGE_SIZE)
+ LastKernelAddress, KERNEL_BASE + 0x00600000);
+ for (MappingAddress = LastKernelAddress;
+ MappingAddress < KERNEL_BASE + 0x00600000;
+ MappingAddress += PAGE_SIZE)
{
- MmRawDeleteVirtualMapping((PVOID)(i));
+ MmRawDeleteVirtualMapping((PVOID)MappingAddress);
}
DPRINT("Almost done MmInit()\n");
-#ifndef MP
- /* FIXME: This is broken in SMP mode */
- MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, TRUE, NULL, NULL);
- MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, TRUE, NULL, NULL);
- MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, TRUE, NULL, NULL);
-#endif
/*
* Intialize memory areas
*/
MmInitializeMdlImplementation();
}
-VOID INIT_FUNCTION
+VOID
+NTAPI
+INIT_FUNCTION
MmInit2(VOID)
{
MmInitializeRmapList();
MmInitPagingFile();
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
MmInit3(VOID)
{
/*
* Unmap low memory
*/
-#ifdef MP
+#ifdef CONFIG_SMP
/* In SMP mode we can unmap the low memory
if all processors are started. */
MmDeletePageTable(NULL, 0);
PFN_TYPE Page, SWAPENTRY SwapEntry,
BOOLEAN Dirty)
{
- assert(SwapEntry == 0);
+ ASSERT(SwapEntry == 0);
if (Page != 0)
{
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
}
VOID
+NTAPI
MiFreeInitMemory(VOID)
{
MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryArea(MmGetKernelAddressSpace(),
- (PVOID)&_init_start__,
- PAGE_ROUND_UP((ULONG)&_init_end__) - (ULONG)_init_start__,
- MiFreeInitMemoryPage,
- NULL);
+ MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+ (PVOID)&_init_start__,
+ MiFreeInitMemoryPage,
+ NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}