- Implemented PAE (physical address extension) mapping.

- Added the command line switches /pae and /noexecute for enabling the PAE mapping.

svn path=/trunk/; revision=10808
This commit is contained in:
Hartmut Birr 2004-09-09 20:42:33 +00:00
parent 176e26ac5d
commit faaad49380
10 changed files with 1523 additions and 474 deletions

View file

@ -136,10 +136,13 @@ VOID
NtEarlyInitVdm(VOID);
#define X86_EFLAGS_ID (1 << 21)
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
#define X86_CR4_PGE (1 << 7)
#define X86_FEATURE_PGE (1 << 13)
#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */
#define X86_CR4_PGE 0x00000080 /* enable global pages */
#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
#define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
#if defined(__GNUC__)
#define Ke386DisableInterrupts() __asm__("cli\n\t");

View file

@ -55,14 +55,11 @@ struct _EPROCESS;
PULONG MmGetPageDirectory(VOID);
VOID MiEnablePAE(PVOID* LastKernelAddress);
/*
* Amount of memory that can be mapped by a page table
*/
#define PAGE_TABLE_SIZE (4*1024*1024)
#define PAGE_MASK(x) ((x)&(~0xfff))
#define VADDR_TO_PT_OFFSET(x) ((((x)/1024)%4096))
#define VADDR_TO_PD_OFFSET(x) ((x)/(4*1024*1024))
#define PAGE_MASK(x) ((x)&(~0xfff))
#define PAE_PAGE_MASK(x) ((x)&(~0xfffLL))
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_MM_H */

View file

@ -116,7 +116,7 @@ VOID KeInitializeTimerImpl(VOID);
VOID KeInitializeBugCheck(VOID);
VOID Phase1Initialization(PVOID Context);
VOID KeInit1(VOID);
VOID KeInit1(PCHAR CommandLine, PULONG LastKernelAddress);
VOID KeInit2(VOID);
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame);

View file

@ -674,6 +674,10 @@ VOID MmMarkPageUnmapped(PFN_TYPE Page);
VOID MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size);
VOID MiInitPageDirectoryMap(VOID);
ULONG MiGetUserPageDirectoryCount(VOID);
/* wset.c ********************************************************************/
NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);

View file

@ -37,7 +37,7 @@ ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0;
static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS];
ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags;
ULONG Ke386Cpuid = 300;
ULONG Ke386Cpuid = 0x300;
/* FUNCTIONS *****************************************************************/
@ -150,15 +150,24 @@ KeApplicationProcessorInit(VOID)
/* Enable global pages */
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
}
/* Enable PAE mode */
if (Ke386CpuidFlags & X86_FEATURE_PAE)
{
MiEnablePAE(NULL);
}
/* Now we can enable interrupts. */
Ke386EnableInterrupts();
}
VOID INIT_FUNCTION
KeInit1(VOID)
KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
{
PKPCR KPCR;
BOOLEAN Pae = FALSE;
BOOLEAN NoExecute = FALSE;
PCHAR p1, p2;
extern USHORT KiBootGdt[];
extern KTSS KiBootTss;
@ -195,7 +204,7 @@ KeInit1(VOID)
if (Ke386CpuidFlags & X86_FEATURE_PGE)
{
ULONG Flags;
ULONG Flags;
/* Enable global pages */
Ke386SaveFlags(Flags);
Ke386DisableInterrupts();
@ -203,6 +212,36 @@ KeInit1(VOID)
Ke386RestoreFlags(Flags);
}
/* Search for pae and noexecute */
p1 = (PCHAR)KeLoaderBlock.CommandLine;
while(*p1 && (p2 = strchr(p1, '/')))
{
p2++;
if (!_strnicmp(p2, "PAE", 3))
{
if (p2[3] == ' ' || p2[3] == 0)
{
p2 += 3;
Pae = TRUE;
}
}
else if (!_strnicmp(p2, "NOEXECUTE", 9))
{
if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0)
{
p2 += 9;
NoExecute = TRUE;
}
}
p1 = p2;
}
/* Enable PAE mode */
if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) ||
(NoExecute && (Ke386CpuidFlags & X86_FEATURE_PAE) /* && (check for the non execution capabilities of the processor) */))
{
MiEnablePAE((PVOID*)LastKernelAddress);
}
}
VOID INIT_FUNCTION
@ -212,4 +251,17 @@ KeInit2(VOID)
KeInitializeBugCheck();
KeInitializeDispatcher();
KeInitializeTimerImpl();
if (Ke386CpuidFlags & X86_FEATURE_PAE)
{
DPRINT1("CPU supports PAE mode\n");
if (Ke386GetCr4() & X86_CR4_PAE)
{
DPRINT1("CPU runs in PAE mode\n");
}
else
{
DPRINT1("CPU doesn't run in PAE mode\n");
}
}
}

View file

@ -29,6 +29,7 @@
.globl _unmap_me4
.globl _pagetable_start
.globl _pagetable_end
.globl _pae_pagedirtable
/*
* This is called by the realmode loader, with protected mode
@ -329,7 +330,8 @@ kernel_pagetable:
kernelmap_pagetable:
.fill 4096, 1, 0
_pae_pagedirtable:
.fill 4096, 1, 0
#ifdef MP
apic_pagetable:
.fill 4096, 1, 0

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: main.c,v 1.193 2004/08/31 20:17:18 hbirr Exp $
/* $Id: main.c,v 1.194 2004/09/09 20:42:33 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -848,15 +848,11 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
{
ULONG i;
ULONG size;
ULONG last_kernel_address;
extern ULONG _bss_end__;
ULONG HalBase;
ULONG DriverBase;
ULONG DriverSize;
/* Low level architecture specific initialization */
KeInit1();
/*
* Copy the parameters to a local buffer because lowmem will go away
*/
@ -956,13 +952,17 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
}
LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
/* Low level architecture specific initialization */
KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
#ifdef HAL_DBG
HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
#endif
HalBase = KeLoaderModules[1].ModStart;
DriverBase =
PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
DriverBase = LastKernelAddress;
/*
* Process hal.dll
@ -970,7 +970,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KERNEL_BASE, &DriverSize);
LdrHalBase = (ULONG_PTR)DriverBase;
last_kernel_address = DriverBase + DriverSize;
LastKernelAddress += PAGE_ROUND_UP(DriverSize);
/*
* Process ntoskrnl.exe
@ -981,8 +981,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
/* time in the boot process that we can use HAL */
FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KERNEL_BASE + 0x200000;
LastKrnlPhysAddr = last_kernel_address - KERNEL_BASE + 0x200000;
LastKernelAddress = last_kernel_address;
LastKrnlPhysAddr = LastKernelAddress - KERNEL_BASE + 0x200000;
#ifndef ACPI
/* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */

View file

@ -1,4 +1,4 @@
/* $Id: aspace.c,v 1.18 2004/08/15 16:39:06 chorns Exp $
/* $Id: aspace.c,v 1.19 2004/09/09 20:42:33 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -81,11 +81,13 @@ MmInitializeAddressSpace(PEPROCESS Process,
AddressSpace->Process = Process;
if (Process != NULL)
{
ULONG Count;
Count = MiGetUserPageDirectoryCount();
AddressSpace->PageTableRefCountTable =
ExAllocatePoolWithTag(NonPagedPool, 768 * sizeof(USHORT),
ExAllocatePoolWithTag(NonPagedPool, Count * sizeof(USHORT),
TAG_PTRC);
RtlZeroMemory(AddressSpace->PageTableRefCountTable, 768 * sizeof(USHORT));
AddressSpace->PageTableRefCountTableSize = 768;
RtlZeroMemory(AddressSpace->PageTableRefCountTable, Count * sizeof(USHORT));
AddressSpace->PageTableRefCountTableSize = Count;
}
else
{

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.67 2004/08/19 22:17:47 hbirr Exp $
/* $Id: mminit.c,v 1.68 2004/09/09 20:42:33 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -34,7 +34,6 @@ 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;
@ -107,17 +106,7 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
/*
* Setup the system area descriptor list
*/
BaseAddress = (PVOID)0xf0000000;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
0x400000,
0,
&kernel_map_desc,
TRUE,
FALSE,
BoundaryAddressMultiple);
MiInitPageDirectoryMap();
BaseAddress = (PVOID)KPCR_BASE;
MmCreateMemoryArea(NULL,