[FREELDR]: Use WinLDR-style booting exclusively for ARM. Remove thousands of lines of old code where we basically did the same thing.

[FREELDR]: Build WinLDR for ARM too, and implement the required portability functions to get it working. Don't build "ros-style" loading on ARM.
[FREELDR]: Redo from scratch the entire paging setup for ARM. Instead of using 20MB of physical RAM, we now only use 1MB that's passed on to the kernel.
[FREELDR]: Fix loads of bugs in the ARM loader code (ha-ha!).
[FREELDR]: Cleanup compiler and linker flags in the rbuild files.
[ARMLLB]: Remove all deprecated video machine routines that are not used anymore.
If all went well, the ARM port should now boot on Versatile platforms up until the ARM3 initialization code.

svn path=/trunk/; revision=45526
This commit is contained in:
Sir Richard 2010-02-09 03:10:07 +00:00
parent 7cd39aa34b
commit 8c8041b1d6
15 changed files with 402 additions and 1696 deletions

View file

@ -8,6 +8,26 @@
#include "precomp.h"
USHORT ColorPalette[16][3] =
{
{0x00, 0x00, 0x00},
{0x00, 0x00, 0xAA},
{0x00, 0xAA, 0x00},
{0x00, 0xAA, 0xAA},
{0xAA, 0x00, 0x00},
{0xAA, 0x00, 0xAA},
{0xAA, 0x55, 0x00},
{0xAA, 0xAA, 0xAA},
{0x55, 0x55, 0x55},
{0x55, 0x55, 0xFF},
{0x55, 0xFF, 0x55},
{0x55, 0xFF, 0xFF},
{0xFF, 0x55, 0x55},
{0xFF, 0x55, 0xFF},
{0xFF, 0xFF, 0x55},
{0xFF, 0xFF, 0xFF},
};
VOID
LlbFwPutChar(INT Ch)
{
@ -53,55 +73,6 @@ LlbFwVideoGetDisplaySize(OUT PULONG Width,
*Depth = 16;
}
ULONG
LlbFwVideoGetBufferSize(VOID)
{
/* X * Y * BPP */
return LlbHwGetScreenWidth() * LlbHwGetScreenHeight() * 2;
}
VOID
LlbFwVideoSetTextCursorPosition(IN ULONG X,
IN ULONG Y)
{
printf("%s is UNIMPLEMENTED", __FUNCTION__);
while (TRUE);
}
VOID
LlbFwVideoHideShowTextCursor(IN BOOLEAN Show)
{
/* Nothing to do */
return;
}
USHORT ColorPalette[16][3] =
{
{0x00, 0x00, 0x00},
{0x00, 0x00, 0xAA},
{0x00, 0xAA, 0x00},
{0x00, 0xAA, 0xAA},
{0xAA, 0x00, 0x00},
{0xAA, 0x00, 0xAA},
{0xAA, 0x55, 0x00},
{0xAA, 0xAA, 0xAA},
{0x55, 0x55, 0x55},
{0x55, 0x55, 0xFF},
{0x55, 0xFF, 0x55},
{0x55, 0xFF, 0xFF},
{0xFF, 0x55, 0x55},
{0xFF, 0x55, 0xFF},
{0xFF, 0xFF, 0x55},
{0xFF, 0xFF, 0xFF},
};
VOID
LlbFwVideoCopyOffScreenBufferToVRAM(IN PVOID Buffer)
{
/* No double-buffer is used on ARM */
return;
}
VOID
LlbFwVideoClearScreen(IN UCHAR Attr)
{
@ -133,43 +104,6 @@ LlbFwVideoPutChar(IN INT c,
LlbVideoDrawChar(c, Buffer, Color, BackColor);
}
BOOLEAN
LlbFwVideoIsPaletteFixed(VOID)
{
printf("%s is UNIMPLEMENTED", __FUNCTION__);
while (TRUE);
return TRUE;
}
VOID
LlbFwVideoSetPaletteColor(IN UCHAR Color,
IN UCHAR Red,
IN UCHAR Green,
IN UCHAR Blue)
{
printf("%s is UNIMPLEMENTED", __FUNCTION__);
while (TRUE);
return;
}
VOID
LlbFwVideoGetPaletteColor(IN UCHAR Color,
OUT PUCHAR Red,
OUT PUCHAR Green,
OUT PUCHAR Blue)
{
printf("%s is UNIMPLEMENTED", __FUNCTION__);
while (TRUE);
return;
}
VOID
LlbFwVideoSync(VOID)
{
printf("%s is UNIMPLEMENTED", __FUNCTION__);
while (TRUE);
return;
}
TIMEINFO*
LlbFwGetTime(VOID)

View file

@ -76,16 +76,7 @@ LlbBuildArmBlock(VOID)
ArmBlock.VideoClearScreen = LlbFwVideoClearScreen;
ArmBlock.VideoSetDisplayMode = LlbFwVideoSetDisplayMode;
ArmBlock.VideoGetDisplaySize = LlbFwVideoGetDisplaySize;
ArmBlock.VideoGetBufferSize = LlbFwVideoGetBufferSize;
ArmBlock.VideoSetTextCursorPosition = LlbFwVideoSetTextCursorPosition;
ArmBlock.VideoSetTextCursorPosition = LlbFwVideoSetTextCursorPosition;
ArmBlock.VideoHideShowTextCursor = LlbFwVideoHideShowTextCursor;
ArmBlock.VideoPutChar = LlbFwVideoPutChar;
ArmBlock.VideoCopyOffScreenBufferToVRAM = LlbFwVideoCopyOffScreenBufferToVRAM;
ArmBlock.VideoIsPaletteFixed = LlbFwVideoIsPaletteFixed;
ArmBlock.VideoSetPaletteColor = LlbFwVideoSetPaletteColor;
ArmBlock.VideoGetPaletteColor = LlbFwVideoGetPaletteColor;
ArmBlock.VideoSync = LlbFwVideoSync;
ArmBlock.GetTime = LlbFwGetTime;
}

File diff suppressed because it is too large Load diff

View file

@ -9,73 +9,79 @@
/* INCLUDES *******************************************************************/
#include <freeldr.h>
#define RGB565(r, g, b) (((r >> 3) << 11)| ((g >> 2) << 5)| ((b >> 3) << 0))
#include <internal/arm/intrin_i.h>
/* GLOBALS ********************************************************************/
UCHAR BootStack[0x4000];
PUCHAR BootStackEnd = &BootStack[0x3FFF];
PARM_BOARD_CONFIGURATION_BLOCK ArmBoardBlock;
ULONG BootDrive, BootPartition;
VOID ArmPrepareForReactOS(IN BOOLEAN Setup);
ADDRESS_RANGE ArmBoardMemoryMap[16];
ULONG ArmBoardMemoryMapRangeCount;
ULONG gDiskReadBuffer, gFileSysBuffer;
BOOLEAN ArmHwDetectRan;
PCONFIGURATION_COMPONENT_DATA RootNode;
ULONG FirstLevelDcacheSize;
ULONG FirstLevelDcacheFillSize;
ULONG FirstLevelIcacheSize;
ULONG FirstLevelIcacheFillSize;
ULONG SecondLevelDcacheSize;
ULONG SecondLevelDcacheFillSize;
ULONG SecondLevelIcacheSize;
ULONG SecondLevelIcacheFillSize;
ARC_DISK_SIGNATURE reactos_arc_disk_info;
ULONG reactos_disk_count;
CHAR reactos_arc_hardware_data[256];
ULONG SizeBits[] =
{
-1, // INVALID
-1, // INVALID
1 << 12, // 4KB
1 << 13, // 8KB
1 << 14, // 16KB
1 << 15, // 32KB
1 << 16, // 64KB
1 << 17 // 128KB
};
ULONG AssocBits[] =
{
-1, // INVALID
-1, // INVALID
4 // 4-way associative
};
ULONG LenBits[] =
{
-1, // INVALID
-1, // INVALID
8 // 8 words per line (32 bytes)
};
/* FUNCTIONS ******************************************************************/
VOID
ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
{
ULONG i;
//
// Remember the pointer
//
/* Remember the pointer */
ArmBoardBlock = BootContext;
//
// Let's make sure we understand the LLB
//
/* Let's make sure we understand the LLB */
ASSERT(ArmBoardBlock->MajorVersion == ARM_BOARD_CONFIGURATION_MAJOR_VERSION);
ASSERT(ArmBoardBlock->MinorVersion == ARM_BOARD_CONFIGURATION_MINOR_VERSION);
//
// This should probably go away once we support more boards
//
/* This should probably go away once we support more boards */
ASSERT((ArmBoardBlock->BoardType == MACH_TYPE_FEROCEON) ||
(ArmBoardBlock->BoardType == MACH_TYPE_VERSATILE_PB) ||
(ArmBoardBlock->BoardType == MACH_TYPE_OMAP3_BEAGLE));
//
// 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
//
/* Call FreeLDR's portable entrypoint with our command-line */
BootMain(ArmBoardBlock->CommandLine);
}
BOOLEAN
ArmDiskNormalizeSystemPath(IN OUT PCHAR SystemPath,
IN unsigned Size)
VOID
ArmPrepareForReactOS(IN BOOLEAN Setup)
{
/* Only RAMDISK supported for now */
if (!strstr(SystemPath, "ramdisk(0)")) return FALSE;
return TRUE;
return;
}
BOOLEAN
@ -95,28 +101,42 @@ ArmDiskGetBootPath(OUT PCHAR BootPath,
PCONFIGURATION_COMPONENT_DATA
ArmHwDetect(VOID)
{
PCONFIGURATION_COMPONENT_DATA RootNode;
ARM_CACHE_REGISTER CacheReg;
//
// Create the root node
//
/* Create the root node */
if (ArmHwDetectRan++) return RootNode;
FldrCreateSystemKey(&RootNode);
//
// TODO:
// There's no such thing as "PnP" on embedded hardware.
// The boot loader will send us a device tree, similar to ACPI
// or OpenFirmware device trees, and we will convert it to ARC.
//
/*
* TODO:
* There's no such thing as "PnP" on embedded hardware.
* The boot loader will send us a device tree, similar to ACPI
* or OpenFirmware device trees, and we will convert it to ARC.
*/
//
// Register RAMDISK Device
//
/* Get cache information */
CacheReg = KeArmCacheRegisterGet();
FirstLevelDcacheSize = SizeBits[CacheReg.DSize];
FirstLevelDcacheFillSize = LenBits[CacheReg.DLength];
FirstLevelDcacheFillSize <<= 2;
FirstLevelIcacheSize = SizeBits[CacheReg.ISize];
FirstLevelIcacheFillSize = LenBits[CacheReg.ILength];
FirstLevelIcacheFillSize <<= 2;
SecondLevelDcacheSize =
SecondLevelDcacheFillSize =
SecondLevelIcacheSize =
SecondLevelIcacheFillSize = 0;
/* Register RAMDISK Device */
RamDiskInitialize();
//
// Return the root node
//
/* Fill out the ARC disk block */
reactos_arc_disk_info.Signature = 0xBADAB00F;
reactos_arc_disk_info.CheckSum = 0xDEADBABE;
reactos_arc_disk_info.ArcName = "ramdisk(0)";
reactos_disk_count = 1;
/* Return the root node */
return RootNode;
}
@ -124,34 +144,26 @@ ULONG
ArmMemGetMemoryMap(OUT PBIOS_MEMORY_MAP BiosMemoryMap,
IN ULONG MaxMemoryMapSize)
{
//
// Return whatever the board returned to us (CS0 Base + Size and FLASH0)
//
RtlCopyMemory(BiosMemoryMap,
ArmBoardBlock->MemoryMap,
ArmBoardBlock->MemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP));
/* Return whatever the board returned to us (CS0 Base + Size and FLASH0) */
memcpy(BiosMemoryMap,
ArmBoardBlock->MemoryMap,
ArmBoardBlock->MemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP));
return ArmBoardBlock->MemoryMapEntryCount;
}
VOID
MachInit(IN PCCH CommandLine)
{
//
// Setup board-specific ARM routines
//
/* Setup board-specific ARM routines */
switch (ArmBoardBlock->BoardType)
{
//
// Check for Feroceon-base boards
//
/* Check for Feroceon-base boards */
case MACH_TYPE_FEROCEON:
TuiPrintf("Not implemented\n");
while (TRUE);
break;
//
// Check for ARM Versatile PB boards
//
/* Check for ARM Versatile PB boards */
case MACH_TYPE_VERSATILE_PB:
/* Copy Machine Routines from Firmware Table */
@ -161,16 +173,7 @@ MachInit(IN PCCH CommandLine)
MachVtbl.VideoClearScreen = ArmBoardBlock->VideoClearScreen;
MachVtbl.VideoSetDisplayMode = ArmBoardBlock->VideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = ArmBoardBlock->VideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = ArmBoardBlock->VideoGetBufferSize;
MachVtbl.VideoSetTextCursorPosition = ArmBoardBlock->VideoSetTextCursorPosition;
MachVtbl.VideoSetTextCursorPosition = ArmBoardBlock->VideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = ArmBoardBlock->VideoHideShowTextCursor;
MachVtbl.VideoPutChar = ArmBoardBlock->VideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = ArmBoardBlock->VideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = ArmBoardBlock->VideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = ArmBoardBlock->VideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = ArmBoardBlock->VideoGetPaletteColor;
MachVtbl.VideoSync = ArmBoardBlock->VideoSync;
MachVtbl.GetTime = ArmBoardBlock->GetTime;
/* Setup the disk and file system buffers */
@ -178,10 +181,10 @@ MachInit(IN PCCH CommandLine)
gFileSysBuffer = 0x00090000;
break;
//
// Check for TI OMAP3 boards
// For now that means only Beagle, but ZOOM and others should be ok too
//
/*
* Check for TI OMAP3 boards
* For now that means only Beagle, but ZOOM and others should be ok too
*/
case MACH_TYPE_OMAP3_BEAGLE:
TuiPrintf("Not implemented\n");
while (TRUE);
@ -191,22 +194,9 @@ MachInit(IN PCCH CommandLine)
ASSERT(FALSE);
}
//
// Setup generic ARM routines for all boards
//
/* Setup generic ARM routines for all boards */
MachVtbl.PrepareForReactOS = ArmPrepareForReactOS;
MachVtbl.GetMemoryMap = ArmMemGetMemoryMap;
MachVtbl.HwDetect = ArmHwDetect;
//
// Setup disk I/O routines
//
MachVtbl.DiskGetBootPath = ArmDiskGetBootPath;
MachVtbl.DiskNormalizeSystemPath = ArmDiskNormalizeSystemPath;
//
// We can now print to the console
//
TuiPrintf("%s for ARM\n", GetFreeLoaderVersionString());
TuiPrintf("Bootargs: %s\n\n", CommandLine);
}

View file

@ -218,6 +218,7 @@ VOID RunLoader(VOID)
IniOpenSection("Operating Systems", &SectionId);
IniReadSettingByName(SectionId, SectionName, SettingValue, sizeof(SettingValue));
#ifndef _M_ARM
// Install the drive mapper according to this sections drive mappings
#ifdef __i386__
DriveMapMapDrivesInSection(SectionName);
@ -270,6 +271,9 @@ VOID RunLoader(VOID)
{
LoadAndBootDrive(SectionName);
}
#endif
#else
LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_WS03);
#endif
}

View file

@ -7,19 +7,6 @@
<include base="ReactOS">include/reactos/libs</include>
<include base="ReactOS">include/reactos/elf</include>
<define name="_NTHAL_" />
<group compilerset="gcc">
<compilerflag>-fno-inline</compilerflag>
<compilerflag>-fno-zero-initialized-in-bss</compilerflag>
</group>
<if property="ARCH" value="arm">
<group compilerset="gcc">
<compilerflag>-ffreestanding</compilerflag>
<compilerflag>-fno-builtin</compilerflag>
<compilerflag>-Os</compilerflag>
</group>
</if>
<directory name="arch">
<directory name="i386">
<if property="ARCH" value="i386">
@ -73,7 +60,6 @@
<directory name="arm">
<if property="ARCH" value="arm">
<file first="true">boot.s</file>
<file>loader.c</file>
<file>macharm.c</file>
</if>
</directory>
@ -102,6 +88,11 @@
</directory>
<directory name="windows">
<if property="ARCH" value="arm">
<directory name="arm">
<file>wlmemory.c</file>
</directory>
</if>
<if property="ARCH" value="i386">
<directory name="i386">
<file>ntsetup.c</file>

View file

@ -7,10 +7,6 @@
<include base="ntoskrnl">include</include>
<define name="_NTHAL_" />
<define name="_NTSYSTEM_" />
<group compilerset="gcc">
<compilerflag>-fno-inline</compilerflag>
<compilerflag>-fno-zero-initialized-in-bss</compilerflag>
</group>
<directory name="arcemul">
<file>mm.c</file>
<file>time.c</file>
@ -56,6 +52,7 @@
<file>libsupp.c</file>
</directory>
<directory name="ui">
<file>directui.c</file>
<file>gui.c</file>
<file>minitui.c</file>
<file>noui.c</file>
@ -68,24 +65,13 @@
<file>palette.c</file>
<file>video.c</file>
</directory>
<if property="ARCH" value="i386">
<directory name="windows">
<file>conversion.c</file>
<file>peloader.c</file>
<file>winldr.c</file>
<file>wlmemory.c</file>
<file>wlregistry.c</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="windows">
<file>conversion.c</file>
<file>peloader.c</file>
<file>winldr.c</file>
<file>wlmemory.c</file>
<file>wlregistry.c</file>
</directory>
</if>
<directory name="windows">
<file>conversion.c</file>
<file>peloader.c</file>
<file>winldr.c</file>
<file>wlmemory.c</file>
<file>wlregistry.c</file>
</directory>
<file>freeldr.c</file>
<file>debug.c</file>
<file>version.c</file>

View file

@ -4,10 +4,6 @@
<include base="freeldr_base64k">include</include>
<include base="ntoskrnl">include</include>
<define name="_NTHAL_" />
<group compilerset="gcc">
<compilerflag>-fno-inline</compilerflag>
<compilerflag>-fno-zero-initialized-in-bss</compilerflag>
</group>
<directory name="arch">
<if property="ARCH" value="i386">
<directory name="i386">

View file

@ -4,9 +4,5 @@
<include base="freeldr_main">include</include>
<include base="ntoskrnl">include</include>
<define name="_NTHAL_" />
<group compilerset="gcc">
<compilerflag>-fno-inline</compilerflag>
<compilerflag>-fno-zero-initialized-in-bss</compilerflag>
</group>
<file>bootmgr.c</file>
</module>

View file

@ -3,10 +3,6 @@
<module name="freeldr_startup" type="objectlibrary">
<include base="freeldr_startup">include</include>
<include base="ntoskrnl">include</include>
<group compilerset="gcc">
<compilerflag>-fno-inline</compilerflag>
<compilerflag>-fno-zero-initialized-in-bss</compilerflag>
</group>
<directory name="arch">
<if property="ARCH" value="i386">
<directory name="i386">

View file

@ -16,12 +16,6 @@
#include "../../../../../armllb/inc/osloader.h"
#include "../../../../../armllb/inc/machtype.h"
//
// Static heap for ARC Hardware Component Tree
// 16KB oughta be enough for anyone.
//
#define HW_MAX_ARC_HEAP_SIZE 16 * 1024
//
// ARC Component Configuration Routines
//
@ -31,21 +25,16 @@ FldrCreateSystemKey(
OUT PCONFIGURATION_COMPONENT_DATA *SystemKey
);
VOID
NTAPI
FldrCreateComponentKey(
IN PCONFIGURATION_COMPONENT_DATA SystemKey,
IN CONFIGURATION_CLASS Class,
IN CONFIGURATION_TYPE Type,
IN IDENTIFIER_FLAG Flags,
IN ULONG Key,
IN ULONG Affinity,
IN PCHAR IdentifierString,
IN PCM_PARTIAL_RESOURCE_LIST ResourceList,
IN ULONG Size,
OUT PCONFIGURATION_COMPONENT_DATA *ComponentKey
);
#define HW_MAX_ARC_HEAP_SIZE 256
extern PARM_BOARD_CONFIGURATION_BLOCK ArmBoardBlock;
extern ULONG FirstLevelDcacheSize;
extern ULONG FirstLevelDcacheFillSize;
extern ULONG FirstLevelIcacheSize;
extern ULONG FirstLevelIcacheFillSize;
extern ULONG SecondLevelDcacheSize;
extern ULONG SecondLevelDcacheFillSize;
extern ULONG SecondLevelIcacheSize;
extern ULONG SecondLevelIcacheFillSize;
#endif

View file

@ -1,3 +1,4 @@
#ifndef _M_ARM
#include <freeldr.h>
#include <debug.h>
@ -780,5 +781,5 @@ FrLdrMapImage(IN PFILE Image,
/* Return the final mapped address */
return LoadBase;
}
#endif
/* EOF */

View file

@ -18,6 +18,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _M_ARM
#include <freeldr.h>
#include <debug.h>
@ -889,6 +890,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
* Load boot drivers
*/
FrLdrLoadBootDrivers(szBootPath, 40);
UiDrawProgressBarCenter(100, 100, szLoadingMsg);
//UiUnInitialize("Booting ReactOS...");
//
@ -901,5 +903,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
//
FrLdrStartup(0x2badb002);
}
#endif
/* EOF */

View file

@ -0,0 +1,256 @@
/*
* PROJECT: ReactOS Boot Loader
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: boot/freeldr/arch/arm/loader.c
* PURPOSE: ARM Kernel Loader
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES ***************************************************************/
#include <freeldr.h>
#include <debug.h>
#include <internal/arm/mm.h>
#include <internal/arm/intrin_i.h>
#define PFN_SHIFT 12
#define LARGE_PFN_SHIFT 20
#define PTE_BASE 0xC0000000
#define PDE_BASE 0xC0400000
#define PDR_BASE 0xFFD00000
#define MMIO_BASE 0x10000000
#define VECTOR_BASE 0xFFFF0000
#define LowMemPageTableIndex 0
#define KernelPageTableIndex (KSEG0_BASE >> PDE_SHIFT)
#define StartupPtePageTableIndex (PTE_BASE >> PDE_SHIFT)
#define StartupPdePageTableIndex (PDE_BASE >> PDE_SHIFT)
#define MmioPageTableIndex (MMIO_BASE >> PDE_SHIFT)
#define PdrPageTableIndex (PDR_BASE >> PDE_SHIFT)
#define VectorPageTableIndex (VECTOR_BASE >> PDE_SHIFT)
/* Converts a Physical Address into a Page Frame Number */
#define PaToPfn(p) ((p) >> PFN_SHIFT)
#define PaToLargePfn(p) ((p) >> LARGE_PFN_SHIFT)
#define PaPtrToPfn(p) (((ULONG_PTR)(p)) >> PFN_SHIFT)
/* Converts a Physical Address into a Coarse Page Table PFN */
#define PaPtrToPdePfn(p) (((ULONG_PTR)(p)) >> CPT_SHIFT)
typedef struct _KPDR_PAGE
{
PAGE_DIRECTORY_ARM PageDir; // 0xC0400000 [0xFFD00000]
CHAR HyperSpace[233 * PAGE_SIZE]; // 0xC0404000 [0xFFD04000]
PAGE_TABLE_ARM KernelPageTable[3]; // 0xC04ED000 [0xFFDED000]
CHAR SharedData[PAGE_SIZE]; // 0xC04F0000 [0xFFDF0000]
CHAR KernelStack[KERNEL_STACK_SIZE]; // 0xC04F1000 [0xFFDF1000]
CHAR PanicStack[KERNEL_STACK_SIZE]; // 0xC04F4000 [0xFFDF4000]
CHAR InterruptStack[KERNEL_STACK_SIZE]; // 0xC04F7000 [0xFFDF7000]
CHAR InitialProcess[PAGE_SIZE]; // 0xC04FA000 [0xFFDFA000]
CHAR InitialThread[PAGE_SIZE]; // 0xC04FB000 [0xFFDFB000]
CHAR Prcb[PAGE_SIZE]; // 0xC04FC000 [0xFFDFC000]
PAGE_TABLE_ARM PageDirPageTable; // 0xC04FD000 [0xFFDFD000]
PAGE_TABLE_ARM VectorPageTable; // 0xC04FE000 [0xFFDFE000]
CHAR Pcr[PAGE_SIZE]; // 0xC04FF000 [0xFFDFF000]
} KPDR_PAGE, *PKPDR_PAGE;
C_ASSERT(sizeof(KPDR_PAGE) == (1 * 1024 * 1024));
HARDWARE_PTE_ARMV6 TempPte;
HARDWARE_LARGE_PTE_ARMV6 TempLargePte;
HARDWARE_PDE_ARMV6 TempPde;
PKPDR_PAGE PdrPage;
/* FUNCTIONS **************************************************************/
BOOLEAN
MempSetupPaging(IN ULONG StartPage,
IN ULONG NumberOfPages)
{
return TRUE;
}
VOID
MempUnmapPage(IN ULONG Page)
{
return;
}
VOID
MempDump(VOID)
{
return;
}
BOOLEAN
WinLdrMapSpecialPages(ULONG PcrBasePage)
{
ULONG i;
PHARDWARE_PTE_ARMV6 PointerPte;
PHARDWARE_PDE_ARMV6 PointerPde;
PHARDWARE_LARGE_PTE_ARMV6 LargePte;
PFN_NUMBER Pfn;
/* Setup the Startup PDE */
LargePte = &PdrPage->PageDir.Pte[StartupPdePageTableIndex];
TempLargePte.PageFrameNumber = PaToLargePfn((ULONG_PTR)&PdrPage->PageDir);
*LargePte = TempLargePte;
/* Map-in the PDR */
LargePte = &PdrPage->PageDir.Pte[PdrPageTableIndex];
*LargePte = TempLargePte;
/* After this point, any MiAddressToPde is guaranteed not to fault */
/*
* Link them in the Startup PDE.
* Note these are the entries in the PD at (MiAddressToPde(PTE_BASE)).
*/
PointerPde = &PdrPage->PageDir.Pde[StartupPtePageTableIndex];
Pfn = PaPtrToPdePfn(&PdrPage->PageDirPageTable);
for (i = 0; i < 4; i++)
{
TempPde.PageFrameNumber = Pfn++;
*PointerPde++ = TempPde;
}
/*
* Now map these page tables in PTE space (MiAddressToPte(PTE_BASE)).
* Note that they all live on a single page, since each is 1KB.
*/
PointerPte = &PdrPage->PageDirPageTable.Pte[0x300];
TempPte.PageFrameNumber = PaPtrToPfn(&PdrPage->PageDirPageTable);
*PointerPte = TempPte;
/*
* After this point, MiAddressToPte((PDE_BASE) to MiAddressToPte(PDE_TOP))
* is guaranteed not to fault.
* Any subsequent page allocation will first need its page table created
* and mapped in the PTE_BASE first, then the page table itself will be
* editable through its flat PTE address.
*/
/* Setup the Vector PDE */
PointerPde = &PdrPage->PageDir.Pde[VectorPageTableIndex];
TempPde.PageFrameNumber = PaPtrToPdePfn(&PdrPage->VectorPageTable);
*PointerPde = TempPde;
/* Setup the Vector PTEs */
PointerPte = &PdrPage->VectorPageTable.Pte[0xF0];
TempPte.PageFrameNumber = 0;
*PointerPte = TempPte;
/* TODO: Map in the kernel CPTs */
return TRUE;
}
VOID
WinLdrSetupForNt(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PVOID *GdtIdt,
IN ULONG *PcrBasePage,
IN ULONG *TssBasePage)
{
PKPDR_PAGE PdrPage = (PVOID)0xFFD00000;
/* Load cache information */
LoaderBlock->u.Arm.FirstLevelDcacheSize = FirstLevelDcacheSize;
LoaderBlock->u.Arm.FirstLevelDcacheFillSize = FirstLevelDcacheFillSize;
LoaderBlock->u.Arm.FirstLevelIcacheSize = FirstLevelIcacheSize;
LoaderBlock->u.Arm.FirstLevelIcacheFillSize = FirstLevelIcacheFillSize;
LoaderBlock->u.Arm.SecondLevelDcacheSize = SecondLevelDcacheSize;
LoaderBlock->u.Arm.SecondLevelDcacheFillSize = SecondLevelDcacheFillSize;
LoaderBlock->u.Arm.SecondLevelIcacheSize = SecondLevelIcacheSize;
LoaderBlock->u.Arm.SecondLevelIcacheFillSize = SecondLevelIcacheSize;
/* Write initial context information */
LoaderBlock->KernelStack = (ULONG_PTR)PdrPage->KernelStack;
LoaderBlock->KernelStack += KERNEL_STACK_SIZE;
LoaderBlock->u.Arm.PanicStack = (ULONG_PTR)PdrPage->PanicStack;
LoaderBlock->u.Arm.PanicStack += KERNEL_STACK_SIZE;
LoaderBlock->u.Arm.InterruptStack = (ULONG_PTR)PdrPage->InterruptStack;
LoaderBlock->u.Arm.InterruptStack += KERNEL_STACK_SIZE;
LoaderBlock->Prcb = (ULONG_PTR)PdrPage->Prcb;
LoaderBlock->Process = (ULONG_PTR)PdrPage->InitialProcess;
LoaderBlock->Thread = (ULONG_PTR)PdrPage->InitialThread;
}
BOOLEAN
MempAllocatePageTables(VOID)
{
ULONG i;
PHARDWARE_PTE_ARMV6 PointerPte;
PHARDWARE_PDE_ARMV6 PointerPde;
PHARDWARE_LARGE_PTE_ARMV6 LargePte;
PFN_NUMBER Pfn;
/* Setup templates */
TempPte.Accessed = TempPte.Valid = TempLargePte.LargePage = TempLargePte.Accessed = TempPde.Valid = 1;
/* Allocate the 1MB "PDR" (Processor Data Region). Must be 1MB aligned */
PdrPage = MmAllocateMemoryAtAddress(sizeof(KPDR_PAGE), (PVOID)0x700000, LoaderMemoryData);
/* Setup the Low Memory PDE as an identity-mapped Large Page (1MB) */
LargePte = &PdrPage->PageDir.Pte[LowMemPageTableIndex];
*LargePte = TempLargePte;
/* Setup the MMIO PDE as two identity mapped large pages -- the kernel will blow these away later */
LargePte = &PdrPage->PageDir.Pte[MmioPageTableIndex];
Pfn = PaToLargePfn(0x10000000);
for (i = 0; i < 2; i++)
{
TempLargePte.PageFrameNumber = Pfn++;
*LargePte++ = TempLargePte;
}
/* Setup the Kernel PDEs */
PointerPde = &PdrPage->PageDir.Pde[KernelPageTableIndex];
Pfn = PaPtrToPdePfn(PdrPage->KernelPageTable);
for (i = 0; i < 12; i++)
{
TempPde.PageFrameNumber = Pfn;
*PointerPde++ = TempPde;
Pfn++;
}
/* Setup the Kernel PTEs */
PointerPte = PdrPage->KernelPageTable[0].Pte;
Pfn = 0;
for (i = 0; i < 3072; i++)
{
TempPte.PageFrameNumber = Pfn++;
*PointerPte++ = TempPte;
}
/* Done */
return TRUE;
}
VOID
WinLdrSetProcessorContext(PVOID GdtIdt,
IN ULONG Pcr,
IN ULONG Tss)
{
ARM_CONTROL_REGISTER ControlRegister;
ARM_TTB_REGISTER TtbRegister;
ARM_DOMAIN_REGISTER DomainRegister;
/* Set the TTBR */
TtbRegister.AsUlong = (ULONG_PTR)&PdrPage->PageDir;
ASSERT(TtbRegister.Reserved == 0);
KeArmTranslationTableRegisterSet(TtbRegister);
/* Disable domains and simply use access bits on PTEs */
DomainRegister.AsUlong = 0;
DomainRegister.Domain0 = ClientDomain;
KeArmDomainRegisterSet(DomainRegister);
/* Enable ARMv6+ paging (MMU), caches and the access bit */
ControlRegister = KeArmControlRegisterGet();
ControlRegister.MmuEnabled = TRUE;
ControlRegister.ICacheEnabled = TRUE;
ControlRegister.DCacheEnabled = TRUE;
ControlRegister.ForceAp = TRUE;
ControlRegister.ExtendedPageTables = TRUE;
KeArmControlRegisterSet(ControlRegister);
}

View file

@ -198,6 +198,10 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
}
#ifdef _M_ARM
#define PKTSS PVOID
#endif
BOOLEAN
WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
ULONG PcrBasePage,