ARM Port Memory Management Checkpoint:

- Implemented and defined the MMU-OS architecture for the ARM port. The details are too long for a commit message, but we have decided to replicate the x86 NT memory manager layout. We've defined a PTE_BASE at 0xC0000000 just like on x86, and we use a PDE_BASE at 0xC1000000. Unlike the x86, we can't use PDE-PTE self-mapping because ARM has different formats (and sizes!) for PDE vs PTEs! We emulate the behavior however (which adds a small performance hit) and the Mm porting is thus at least 10 times easier.
- Moved serial port to 0xE0000000 for now.
- We now parse the board memory map from u-boot.
- Added memory allocation code to FreeLDR -- we now build a full ARC memory map for the kernel.
- FreeLDR allocates page tables and sets up the initial support for our memory layout (see comments for some lengthier explenations)
- Allocations made by FreeLDR for loading ReactOS are now made from a "shared heap" page that's also marked in the memory map.
- Registry and NLS data are now being put into the loader block.
- We now create a loader entry for the kernel (but not anything else -- we'll have to parse the list properly later).
- Defined correct _HARDWARE_PTE_ARM and _MMPTE_HARDWARE for ARM.
- ARM_COARSE_PAGE_TABLE is now 4KB instead of 1KB, going against the architecture! We do this for proper OS support of the PTE_BASE.
- Fixed build due to KiSystemStartulReal change.
- Fixed a bug on the x86 build when creating memory allocation descriptors. Memory corruption could occur in certain scenarios.
- Implemented significant portions of the ARM memory manager code in the kernel:
  - MmGetPageDirectory.
  - MmDeletePageTable (for the kernel address space only).
  - MmIsPagePresent (for the kernel address space only).
  - MmCreateVirtualMappingForKernel.
  - MmCreateVirtualMapping (calls MmCreateVirtualMappingUnsafe).
  - MmCreateVirtualMappingUnsafe (for the kernel address space only).
  - MmSetPageProtect (unused on ARM).
  - MmCreateHyperspaceMapping.
  - MmDeleteHyperspaceMapping.
  - MmInitGlobalKernelPageDirectory.
  - MmInitPageDirectoryMap.
- With the above, this means we now go well inside MmInit1: the PFN database is setup and works, memory areas are functional, and non-paged pool is fully working.
- We currently hit a data abort during paged pool setup -- this is to be expected, since we don't have any exception handlers yet. These are coming up next -- we have to start handling crashes (and page faults).


svn path=/trunk/; revision=32640
This commit is contained in:
ReactOS Portable Systems Group
2008-03-10 17:27:14 +00:00
parent 6f83c4fcb6
commit 0b44376e27
11 changed files with 1704 additions and 94 deletions
@@ -61,12 +61,16 @@ L_ArmInit:
.long ArmInit
.align 4
.global BootStack
BootStack:
.space 0x4000
BootStackEnd:
.long 0
.section pagedata
.global TranslationTableStart
TranslationTableStart:
.global ArmTranslationTable
ArmTranslationTable:
.space 0x4000 // 0x00000000->0xFFFFFFFF
@@ -74,19 +78,81 @@ ArmTranslationTable:
.global BootTranslationTable
BootTranslationTable:
.space 0x0400 // 0x00000000->0x800FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00100000->0x801FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00200000->0x802FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00300000->0x803FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00400000->0x804FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00500000->0x805FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00600000->0x806FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00700000->0x807FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.global KernelTranslationTable
KernelTranslationTable:
.space 0x0400 // 0x00800000->0x808FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00900000->0x809FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00A00000->0x80AFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00B00000->0x80BFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00C00000->0x80CFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0x00D00000->0x80DFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.global FlatMapTranslationTable
FlatMapTranslationTable:
.space 0x0400 // 0xYYYYYYYY->0xC00FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC01FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC02FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC03FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC04FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC05FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC06FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC07FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC08FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC09FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0AFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0BFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0CFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0DFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0EFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.space 0x0400 // 0xYYYYYYYY->0xC0FFFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.global MasterTranslationTable
MasterTranslationTable:
.space 0x0400 // 0xYYYYYYYY->0xC10FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.global HyperSpaceTranslationTable
HyperSpaceTranslationTable:
.space 0x0400 // 0xYYYYYYYY->0xC10FFFFF
.space 0x0C00 // PADDING FOR 4KB GRANULARITY
.global TranslationTableEnd
TranslationTableEnd:
File diff suppressed because it is too large Load Diff
@@ -15,12 +15,16 @@
PARM_BOARD_CONFIGURATION_BLOCK ArmBoardBlock;
ULONG BootDrive, BootPartition;
VOID ArmPrepareForReactOS(IN BOOLEAN Setup);
ADDRESS_RANGE ArmBoardMemoryMap[16];
ULONG ArmBoardMemoryMapRangeCount;
/* FUNCTIONS ******************************************************************/
VOID
ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
{
ULONG i;
//
// Remember the pointer
//
@@ -38,6 +42,22 @@ ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
ASSERT((ArmBoardBlock->BoardType == MACH_TYPE_FEROCEON) ||
(ArmBoardBlock->BoardType == MACH_TYPE_VERSATILE_PB));
//
// Save data required for memory initialization
//
ArmBoardMemoryMapRangeCount = ArmBoardBlock->MemoryMapEntryCount;
ASSERT(ArmBoardMemoryMapRangeCount != 0);
ASSERT(ArmBoardMemoryMapRangeCount < 16);
for (i = 0; i < ArmBoardMemoryMapRangeCount; i++)
{
//
// Copy each entry
//
RtlCopyMemory(&ArmBoardMemoryMap[i],
&ArmBoardBlock->MemoryMap[i],
sizeof(ADDRESS_RANGE));
}
//
// Call FreeLDR's portable entrypoint with our command-line
//
@@ -16,7 +16,10 @@ LdrPEGetExportByName(
);
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
PVOID AnsiData, OemData, UnicodeData, RegistryData;
ULONG Drivers;
PVOID AnsiData, OemData, UnicodeData, RegistryData, KernelData, HalData, DriverData[16];
ULONG RegistrySize, AnsiSize, OemSize, UnicodeSize, KernelSize, HalSize, DriverSize[16];
/* MODULE MANAGEMENT **********************************************************/
PLOADER_MODULE
@@ -101,19 +104,23 @@ FrLdrLoadModule(FILE *ModuleImage,
if (!_stricmp(NameBuffer, "ansi.nls"))
{
AnsiData = (PVOID)NextModuleBase;
AnsiSize = LocalModuleSize;
}
else if (!_stricmp(NameBuffer, "oem.nls"))
{
OemData = (PVOID)NextModuleBase;
OemSize = LocalModuleSize;
}
else if (!_stricmp(NameBuffer, "casemap.nls"))
{
UnicodeData = (PVOID)NextModuleBase;
UnicodeSize = LocalModuleSize;
}
else if (!(_stricmp(NameBuffer, "system")) ||
!(_stricmp(NameBuffer, "system.hiv")))
{
RegistryData = (PVOID)NextModuleBase;
RegistrySize = LocalModuleSize;
}
/* Load the file image */
@@ -548,6 +555,24 @@ FrLdrMapImage(IN FILE *Image,
reactos_modules[ImageId].String = (ULONG_PTR)reactos_module_strings[ImageId];
LoaderBlock.ModsCount++;
/* Detect kernel or HAL */
if (!_stricmp(Name, "ntoskrnl.exe"))
{
KernelData = (PVOID)NextModuleBase;
KernelSize = ImageSize;
}
else if (!_stricmp(Name, "hal.dll"))
{
HalData = (PVOID)NextModuleBase;
HalSize = ImageSize;
}
else
{
DriverData[Drivers] = (PVOID)NextModuleBase;
DriverSize[Drivers] = ImageSize;
Drivers++;
}
/* Increase the next Load Base */
NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
+162 -26
View File
@@ -47,19 +47,87 @@ C_ASSERT(MM_ALLOCATION_GRANULARITY >= PAGE_SIZE);
//
typedef struct _HARDWARE_PTE_ARM
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype: 1;
ULONG reserved: 1;
ULONG PageFrameNumber:20;
union
{
union
{
struct
{
ULONG Type:2;
ULONG Unused:30;
} Fault;
struct
{
ULONG Type:2;
ULONG Ignored:2;
ULONG Reserved:1;
ULONG Domain:4;
ULONG Ignored1:1;
ULONG BaseAddress:22;
} Coarse;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Reserved:1;
ULONG Domain:4;
ULONG Ignored:1;
ULONG Access:2;
ULONG Ignored1:8;
ULONG BaseAddress:12;
} Section;
struct
{
ULONG Type:2;
ULONG Reserved:3;
ULONG Domain:4;
ULONG Ignored:3;
ULONG BaseAddress:20;
} Fine;
} L1;
union
{
struct
{
ULONG Type:2;
ULONG Unused:30;
} Fault;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Access1:2;
ULONG Access2:2;
ULONG Access3:2;
ULONG Ignored:4;
ULONG BaseAddress:16;
} Large;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Access1:2;
ULONG Access2:2;
ULONG Access3:2;
ULONG BaseAddress:20;
} Small;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Ignored:4;
ULONG BaseAddress:22;
} Tiny;
} L2;
ULONG AsUlong;
};
} HARDWARE_PTE_ARM, *PHARDWARE_PTE_ARM;
typedef struct _MMPTE_SOFTWARE
@@ -117,19 +185,87 @@ typedef struct _MMPTE_LIST
typedef struct _MMPTE_HARDWARE
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG reserved:1;
ULONG PageFrameNumber:20;
union
{
union
{
struct
{
ULONG Type:2;
ULONG Unused:30;
} Fault;
struct
{
ULONG Type:2;
ULONG Ignored:2;
ULONG Reserved:1;
ULONG Domain:4;
ULONG Ignored1:1;
ULONG BaseAddress:22;
} Coarse;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Reserved:1;
ULONG Domain:4;
ULONG Ignored:1;
ULONG Access:2;
ULONG Ignored1:8;
ULONG BaseAddress:12;
} Section;
struct
{
ULONG Type:2;
ULONG Reserved:3;
ULONG Domain:4;
ULONG Ignored:3;
ULONG BaseAddress:20;
} Fine;
} L1;
union
{
struct
{
ULONG Type:2;
ULONG Unused:30;
} Fault;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Access1:2;
ULONG Access2:2;
ULONG Access3:2;
ULONG Ignored:4;
ULONG BaseAddress:16;
} Large;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Access1:2;
ULONG Access2:2;
ULONG Access3:2;
ULONG BaseAddress:20;
} Small;
struct
{
ULONG Type:2;
ULONG Buffered:1;
ULONG Cached:1;
ULONG Access0:2;
ULONG Ignored:4;
ULONG BaseAddress:22;
} Tiny;
} L2;
ULONG AsUlong;
};
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
//
@@ -174,5 +174,6 @@ KeFlushTb(
);
#define KeArchInitThreadWithContext KeArmInitThreadWithContext
#define KiSystemStartupReal KiSystemStartup
#endif
@@ -113,6 +113,7 @@ typedef struct _ARM_TRANSLATION_TABLE
typedef struct _ARM_COARSE_PAGE_TABLE
{
ARM_PTE Pte[256];
ULONG Padding[768];
} ARM_COARSE_PAGE_TABLE, *PARM_COARSE_PAGE_TABLE;
typedef enum _ARM_L1_PTE_TYPE
+1 -1
View File
@@ -17,7 +17,7 @@
//
// UART Registers
//
#define UART_BASE (void*)0xc00f1000 /* HACK: freeldr mapped it here */
#define UART_BASE (void*)0xe00f1000 /* HACK: freeldr mapped it here */
#define UART_PL01x_DR (UART_BASE + 0x00)
#define UART_PL01x_RSR (UART_BASE + 0x04)
+1 -1
View File
@@ -771,7 +771,7 @@ KiRosAllocateNtDescriptor(IN TYPE_OF_MEMORY MemoryType,
if (MdBlock)
{
/* If it contains our limit as well, break out early */
if ((MdBlock->PageCount + MdBlock->BasePage) > AlignedLimit) break;
if ((MdBlock->PageCount + MdBlock->BasePage) >= AlignedLimit) break;
}
/* Loop the memory list */
+400 -32
View File
@@ -20,6 +20,29 @@
while (TRUE); \
}
//
// Take 0x80812345 and extract:
// PTE_BASE[0x808][0x12]
//
#define MiGetPteAddress(x) \
(PMMPTE)(PTE_BASE + (((ULONG)(x) >> 20) << 12) + ((((ULONG)(x) >> 12) & 0xFF) << 2))
#define MiGetPdeAddress(x) \
(PMMPTE)(PDE_BASE + (((ULONG)(x) >> 20) << 2))
#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
#define PTE_BASE 0xC0000000
#define PDE_BASE 0xC1000000
#define HYPER_SPACE ((PVOID)0xC1100000)
ULONG MmGlobalKernelPageDirectory[1024];
MMPTE MiArmTemplatePte, MiArmTemplatePde;
VOID
KiFlushSingleTb(IN BOOLEAN Invalid,
IN PVOID Virtual);
/* FUNCTIONS ******************************************************************/
VOID
@@ -71,10 +94,9 @@ PULONG
MmGetPageDirectory(VOID)
{
//
// TODO
// Return the TTB
//
UNIMPLEMENTED;
return 0;
return (PULONG)KeArmTranslationTableRegisterGet().AsUlong;
}
@@ -96,10 +118,65 @@ NTAPI
MmDeletePageTable(IN PEPROCESS Process,
IN PVOID Address)
{
PMMPTE PointerPde;
//
// TODO
// Not valid for kernel addresses
//
UNIMPLEMENTED;
DPRINT1("MmDeletePageTable(%p, %p)\n", Process, Address);
ASSERT(Address < MmSystemRangeStart);
//
// Check if this is for a different process
//
if ((Process) && (Process != PsGetCurrentProcess()))
{
//
// TODO
//
UNIMPLEMENTED;
return;
}
//
// Get the PDE
//
PointerPde = MiGetPdeAddress(Address);
//
// On ARM, we use a section mapping for the original low-memory mapping
//
if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
{
//
// Make sure it's valid
//
ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
}
//
// Clear the PDE
//
PointerPde->u.Hard.AsUlong = 0;
ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
//
// Check if this is a kernel PDE
//
if ((PointerPde >= (PMMPTE)PTE_BASE) && (PointerPde < (PMMPTE)PTE_BASE + (1024 * 1024)))
{
//
// Invalidate the TLB entry
//
KiFlushSingleTb(TRUE, Address);
}
else
{
//
// Process PDE, unmap it from hyperspace (will also invalidate TLB entry)
//
MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(PointerPde));
}
}
PFN_TYPE
@@ -215,11 +292,38 @@ NTAPI
MmIsPagePresent(IN PEPROCESS Process,
IN PVOID Address)
{
PMMPTE Pte;
//
// TODO
// Check if this is for a different process
//
UNIMPLEMENTED;
return 0;
if ((Process) && (Process != PsGetCurrentProcess()))
{
//
// TODO
//
UNIMPLEMENTED;
return 0;
}
//
// Get the PDE
//
Pte = MiGetPdeAddress(Address);
if (Pte->u.Hard.L1.Fault.Type != FaultPte)
{
//
// Get the PTE
//
Pte = MiGetPteAddress(Address);
}
//
// Return whether or not it's valid
//
return (Pte->u.Hard.L1.Fault.Type != FaultPte);
}
BOOLEAN
@@ -237,15 +341,107 @@ MmIsPageSwapEntry(IN PEPROCESS Process,
NTSTATUS
NTAPI
MmCreateVirtualMappingForKernel(IN PVOID Address,
IN ULONG flProtect,
IN PPFN_TYPE Pages,
IN ULONG Protection,
IN PPFN_NUMBER Pages,
IN ULONG PageCount)
{
PMMPTE PointerPte, LastPte, PointerPde, LastPde;
MMPTE TempPte, TempPde;
NTSTATUS Status;
PFN_NUMBER Pfn;
DPRINT1("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n",
Address, Protection, *Pages, PageCount);
ASSERT(Address >= MmSystemRangeStart);
//
// TODO
// Get our templates
//
UNIMPLEMENTED;
return 0;
TempPte = MiArmTemplatePte;
TempPde = MiArmTemplatePde;
//
// Check if we have PDEs for this region
//
PointerPde = MiGetPdeAddress(Address);
LastPde = PointerPde + (PageCount / 256);
while (PointerPde <= LastPde)
{
//
// Check if we need to allocate the PDE
//
if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
{
//
// Request a page
//
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
if (!NT_SUCCESS(Status)) return Status;
//
// Setup the PFN
//
TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn << PAGE_SHIFT) >> CPT_SHIFT;
//
// Write the PDE
//
ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
*PointerPde = TempPde;
//
// Get the PTE for this 1MB region
//
PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
//
// Write the PFN of the PDE
//
TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
//
// Write the PTE
//
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
*PointerPte = TempPte;
}
//
// Next
//
PointerPde++;
}
//
// Get start and end address and loop each PTE
//
PointerPte = MiGetPteAddress(Address);
LastPte = PointerPte + PageCount - 1;
while (PointerPte <= LastPte)
{
//
// Set the PFN
//
TempPte.u.Hard.L2.Small.BaseAddress = *Pages++;
//
// Write the PTE
//
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
*PointerPte = TempPte;
//
// Next
//
PointerPte++;
}
//
// All done
//
return STATUS_SUCCESS;
}
NTSTATUS
@@ -265,10 +461,27 @@ NTSTATUS
NTAPI
MmCreateVirtualMappingUnsafe(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG flProtect,
IN ULONG Protection,
IN PPFN_TYPE Pages,
IN ULONG PageCount)
{
DPRINT1("MmCreateVirtualMappingUnsafe(%p %x, %x, %x, %d)\n",
Process, Address, Protection, *Pages, PageCount);
//
// Are we only handling the kernel?
//
if (!Process)
{
//
// Call the kernel version
//
return MmCreateVirtualMappingForKernel(Address,
Protection,
Pages,
PageCount);
}
//
// TODO
//
@@ -280,15 +493,33 @@ NTSTATUS
NTAPI
MmCreateVirtualMapping(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG flProtect,
IN ULONG Protection,
IN PPFN_TYPE Pages,
IN ULONG PageCount)
{
ULONG i;
DPRINT1("MmCreateVirtualMapping(%p %x, %x, %x, %d)\n",
Process, Address, Protection, *Pages, PageCount);
//
// TODO
// Loop each page
//
UNIMPLEMENTED;
return 0;
for (i = 0; i < PageCount; i++)
{
//
// Make sure the page is marked as in use
//
ASSERT(MmIsPageInUse(Pages[i]));
}
//
// Call the unsafe version
//
return MmCreateVirtualMappingUnsafe(Process,
Address,
Protection,
Pages,
PageCount);
}
ULONG
@@ -307,12 +538,12 @@ VOID
NTAPI
MmSetPageProtect(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG flProtect)
IN ULONG Protection)
{
//
// TODO
// We don't enforce any protection on the pages -- they are all RWX
//
UNIMPLEMENTED;
return;
}
/*
@@ -335,34 +566,124 @@ PVOID
NTAPI
MmCreateHyperspaceMapping(IN PFN_TYPE Page)
{
PMMPTE PointerPte, FirstPte, LastPte;
MMPTE TempPte;
PVOID Address;
DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Page);
//
// TODO
// Loop hyperspace PTEs (1MB)
//
UNIMPLEMENTED;
return 0;
FirstPte = PointerPte = MiGetPteAddress(HYPER_SPACE);
LastPte = PointerPte + 256;
while (PointerPte <= LastPte)
{
//
// Find a free slot
//
if (PointerPte->u.Hard.L2.Fault.Type == FaultPte)
{
//
// Use this entry
//
break;
}
//
// Try the next one
//
PointerPte++;
}
//
// Check if we didn't find anything
//
if (PointerPte > LastPte) return NULL;
//
// Create the mapping
//
TempPte = MiArmTemplatePte;
TempPte.u.Hard.L2.Small.BaseAddress = Page;
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
*PointerPte = TempPte;
//
// Return the address
//
Address = HYPER_SPACE + ((PointerPte - FirstPte) * PAGE_SIZE);
KiFlushSingleTb(FALSE, Address);
DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Address);
return Address;
}
PFN_TYPE
NTAPI
MmDeleteHyperspaceMapping(IN PVOID Address)
{
PFN_TYPE Pfn = {0};
PFN_TYPE Pfn;
PMMPTE PointerPte;
DPRINT1("MmDeleteHyperspaceMapping(%lx)\n", Address);
//
// TODO
// Get the PTE
//
UNIMPLEMENTED;
PointerPte = MiGetPteAddress(Address);
ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
//
// Save the PFN
//
Pfn = PointerPte->u.Hard.L2.Small.BaseAddress;
//
// Destroy the PTE
//
PointerPte->u.Hard.AsUlong = 0;
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
//
// Flush the TLB entry and return the PFN
//
KiFlushSingleTb(TRUE, Address);
return Pfn;
}
VOID
NTAPI
MmInitGlobalKernelPageDirectory(VOID)
{
ULONG i;
PULONG CurrentPageDirectory = (PULONG)PDE_BASE;
//
// TODO
// Good place to setup template PTE/PDEs.
// We are lazy and pick a known-good PTE
//
UNIMPLEMENTED;
MiArmTemplatePte = *MiGetPteAddress(0x80000000);
MiArmTemplatePde = *MiGetPdeAddress(0x80000000);
//
// Loop the 2GB of address space which belong to the kernel
//
for (i = MiGetPdeOffset(MmSystemRangeStart); i < 1024; i++)
{
//
// Check if we have an entry for this already
//
if ((i != MiGetPdeOffset(PTE_BASE)) &&
(i != MiGetPdeOffset(HYPER_SPACE)) &&
(!MmGlobalKernelPageDirectory[i]) &&
(CurrentPageDirectory[i]))
{
//
// We don't, link it in our global page directory
//
MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
}
}
}
ULONG
@@ -380,8 +701,55 @@ VOID
NTAPI
MiInitPageDirectoryMap(VOID)
{
MEMORY_AREA* MemoryArea = NULL;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PVOID BaseAddress;
NTSTATUS Status;
DPRINT1("MiInitPageDirectoryMap()\n");
//
// TODO
// Create memory area for the PTE area
//
UNIMPLEMENTED;
BoundaryAddressMultiple.QuadPart = 0;
BaseAddress = (PVOID)PTE_BASE;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
0x1000000,
PAGE_READWRITE,
&MemoryArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
//
// Create memory area for the PDE area
//
BaseAddress = (PVOID)PDE_BASE;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
0x100000,
PAGE_READWRITE,
&MemoryArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
//
// And finally, hyperspace
//
BaseAddress = (PVOID)HYPER_SPACE;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
PAGE_SIZE,
PAGE_READWRITE,
&MemoryArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
}
+4 -3
View File
@@ -347,9 +347,7 @@ MiGetLastKernelAddress(VOID)
NextEntry = NextEntry->Flink)
{
Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
if (Md->MemoryType == LoaderBootDriver ||
Md->MemoryType == LoaderSystemCode ||
Md->MemoryType == LoaderHalCode)
if (Md->MemoryType != LoaderFree)
{
if (Md->BasePage+Md->PageCount > LastKrnlPhysAddr)
LastKrnlPhysAddr = Md->BasePage+Md->PageCount;
@@ -432,10 +430,13 @@ MmInit1(VOID)
MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MiNonPagedPoolStart +
MiNonPagedPoolLength);
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
/* Dump kernel memory layout */
MiDbgKernelLayout();
/* Initialize the page list */
MmInitializePageList();
/* Unmap low memory */
MmDeletePageTable(NULL, 0);