PowerPC support drop in freeldr, from my branch. Some stuff not working, but disk IO now implemented. Get boot partition either from boot-device env var or from cmd line. Needs some work to build with the new tools. Modified: trunk/reactos/boot/freeldr/bootsect/ofwboot.s Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c Added: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c _____
Modified: trunk/reactos/boot/freeldr/bootsect/ofwboot.s --- trunk/reactos/boot/freeldr/bootsect/ofwboot.s 2005-12-04 12:07:08 UTC (rev 19856) +++ trunk/reactos/boot/freeldr/bootsect/ofwboot.s 2005-12-04 12:13:48 UTC (rev 19857) @@ -61,9 +61,10 @@
li %r9,0x12 /* BATL(0, BAT_M, BAT_PP_RW) */ mtibatl 0,%r9 mtdbatl 0,%r9 - li %r9,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */ - mtibatu 0,%r9 - mtdbatu 0,%r9 + li %r10,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */ + mtibatu 0,%r10 + mtdbatu 0,%r10 + isync
li %r8,0x3030 @@ -93,6 +94,8 @@
bl ofw_print_eol
+ bl setup_exc + /* Zero CTR */ mtcr %r31 @@ -630,6 +633,53 @@ /* Return */ blr
+ofw_open: + /* Reserve stack space ... + * 20 bytes for the ofw call, + * r8, r9, and lr */ + subi %r1,%r1,32 + + /* Store r8, r9, lr */ + stw %r8,20(%r1) + stw %r9,24(%r1) + mflr %r8 + stw %r8,28(%r1) + + /* Get open name */ + lis %r8,0xe00000@ha + addi %r9,%r8,ofw_open_name - _start + stw %r9,0(%r1) + + /* 1 Argument and 1 return */ + li %r9,1 + stw %r9,4(%r1) + stw %r9,8(%r1) + + stw %r3,12(%r1) + + /* Load up the call address */ + lwz %r9,ofw_call_addr - _start(%r8) + mtlr %r9 + + /* Set argument */ + mr %r3,%r1 + + /* Fire */ + blrl + + lwz %r3,16(%r1) + + /* Restore registers */ + lwz %r8,28(%r1) + mtlr %r8 + lwz %r9,24(%r1) + lwz %r8,20(%r1) + + addi %r1,%r1,32 + + /* Return */ + blr + ofw_getprop_hook: /* Reserve stack space: * 32 bytes for the ofw call @@ -889,7 +939,224 @@ /* Fire */ blrl /* No return from exit */ + +ofw_child: + /* Reserve stack space ... + * 20 bytes for the ofw call, + * r8, r9, and lr */ + subi %r1,%r1,32 + + /* Store r8, r9, lr */ + stw %r8,20(%r1) + stw %r9,24(%r1) + mflr %r8 + stw %r8,28(%r1) + + /* Get child name */ + lis %r8,0xe00000@ha + addi %r9,%r8,ofw_child_name - _start + stw %r9,0(%r1) + + /* 1 Argument and 1 return */ + li %r9,1 + stw %r9,4(%r1) + stw %r9,8(%r1) + + stw %r3,12(%r1) + + /* Load up the call address */ + lwz %r9,ofw_call_addr - _start(%r8) + mtlr %r9 + + /* Set argument */ + mr %r3,%r1 + + /* Fire */ + blrl + + lwz %r3,16(%r1) + + /* Restore registers */ + lwz %r8,28(%r1) + mtlr %r8 + lwz %r9,24(%r1) + lwz %r8,20(%r1) + + addi %r1,%r1,32 + + /* Return */ + blr + +ofw_peer: + /* Reserve stack space ... + * 20 bytes for the ofw call, + * r8, r9, and lr */ + subi %r1,%r1,32 + + /* Store r8, r9, lr */ + stw %r8,20(%r1) + stw %r9,24(%r1) + mflr %r8 + stw %r8,28(%r1) + + /* Get peer name */ + lis %r8,0xe00000@ha + addi %r9,%r8,ofw_peer_name - _start + stw %r9,0(%r1) + + /* 1 Argument and 1 return */ + li %r9,1 + stw %r9,4(%r1) + stw %r9,8(%r1) + + stw %r3,12(%r1) + + /* Load up the call address */ + lwz %r9,ofw_call_addr - _start(%r8) + mtlr %r9 + + /* Set argument */ + mr %r3,%r1 + + /* Fire */ + blrl + + lwz %r3,16(%r1) + + /* Restore registers */ + lwz %r8,28(%r1) + mtlr %r8 + lwz %r9,24(%r1) + lwz %r8,20(%r1) + + addi %r1,%r1,32 + + /* Return */ + blr + +ofw_seek: + /* Reserve stack space ... + * 20 bytes for the ofw call, + * r8, r9, and lr */ + subi %r1,%r1,32 + + /* Store r8, r9, lr */ + stw %r8,20(%r1) + stw %r9,24(%r1) + mflr %r8 + stw %r8,28(%r1) + + /* Get peer name */ + lis %r8,0xe00000@ha + addi %r9,%r8,ofw_seek_name - _start + stw %r9,0(%r1) + + /* 3 Arguments and 1 return */ + li %r9,3 + stw %r9,4(%r1) + li %r9,1 + stw %r9,8(%r1) + + stw %r3,12(%r1) + stw %r4,16(%r1) + stw %r5,20(%r1) + + /* Load up the call address */ + lwz %r9,ofw_call_addr - _start(%r8) + mtlr %r9 + + /* Set argument */ + mr %r3,%r1 + + /* Fire */ + blrl + + lwz %r3,16(%r1) + + /* Restore registers */ + lwz %r8,28(%r1) + mtlr %r8 + lwz %r9,24(%r1) + lwz %r8,20(%r1) + + addi %r1,%r1,32 + + /* Return */ + blr + + +setup_exc: + subi %r1,%r1,32 + + stw %r3,0(%r1) + mflr %r3 + stw %r3,4(%r1) + stw %r8,8(%r1) + stw %r9,12(%r1) + stw %r10,16(%r1) + stw %r12,20(%r1) + + lis %r8,0xe00000@ha + xor %r12,%r12,%r12 + addi %r12,%r12,0x300 + addi %r9,%r8,dsi_exc - _start + addi %r10,%r8,dsi_end - _start + +copy_loop: + cmp 0,0,%r9,%r10 + beq ret_setup_exc + + mr %r3,%r12 + bl ofw_print_number + bl ofw_print_space + + lwz %r3,0(%r9) + stw %r3,0(%r12) + + bl ofw_print_number + bl ofw_print_eol + + addi %r12,%r12,4 + addi %r9,%r9,4 + b copy_loop + +ret_setup_exc: + mfmsr %r12 + andi. %r12,%r12,0xffbf + mtmsr %r12 + + lwz %r12,20(%r1) + lwz %r10,16(%r1) + lwz %r9,12(%r1) + lwz %r8,8(%r1) + + lwz %r3,4(%r1) + mtlr %r3 + lwz %r3,0(%r1) + + blr + +dsi_exc: + subi %r1,%r1,16 + + stw %r0,0(%r1) + stw %r3,4(%r1) + + mfsrr0 %r3 + addi %r3,%r3,4 + mtsrr0 %r3 + + /* mfsrr1 %r3 */ + /* ori %r3,%r3,2 */ + /* mtsrr1 %r3 */ + lwz %r3,4(%r1) + lwz %r0,0(%r1) + + addi %r1,%r1,16 + rfi +dsi_end: + .org 0x1000 freeldr_banner: .ascii "ReactOS OpenFirmware Boot Program\r\n\0" @@ -899,7 +1166,6 @@
freeldr_reg_init: .ascii "r\0" - freeldr_reg_lr: .ascii "lr \0" freeldr_reg_cr: @@ -933,6 +1199,18 @@ ofw_exit_name: .ascii "exit\0"
+ofw_open_name: + .ascii "open\0" + +ofw_child_name: + .ascii "child\0" + +ofw_peer_name: + .ascii "peer\0" + +ofw_seek_name: + .ascii "seek\0" + ofw_chosen_name: .ascii "/chosen\0"
@@ -954,6 +1232,10 @@ .long ofw_print_regs .long ofw_print_string .long ofw_print_number + .long ofw_open + .long ofw_child + .long ofw_peer + .long ofw_seek .org 0x2000 stack: _____
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s --- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s 2005-12-04 12:07:08 UTC (rev 19856) +++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s 2005-12-04 12:13:48 UTC (rev 19857) @@ -1,3 +1,3 @@
.extern PpcInit _start: - b PpcInit + b PpcInit+4 _____
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c --- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c 2005-12-04 12:07:08 UTC (rev 19856) +++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c 2005-12-04 12:13:48 UTC (rev 19857) @@ -22,20 +22,18 @@
extern void BootMain( char * ); extern char *GetFreeLoaderVersionString(); -ULONG BootPartition = 0; -ULONG BootDrive = 0; - of_proxy ofproxy; void *PageDirectoryStart, *PageDirectoryEnd; -static int chosen_package, stdin_handle; +static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; -char BootPath[0x100]; +char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; +jmp_buf jmp;
-void le_swap( const void *start_addr_v, - const void *end_addr_v, +void le_swap( const void *start_addr_v, + const void *end_addr_v, const void *target_addr_v ) { - long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), - *end_addr = (long *)ROUND_UP((long)end_addr_v,8), + long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), + *end_addr = (long *)ROUND_UP((long)end_addr_v,8), *target_addr = (long *)ROUND_DOWN((long)target_addr_v,8); long tmp; while( start_addr <= end_addr ) { @@ -68,6 +66,7 @@ return ret; }
+/* Since this is from external storage, it doesn't need swapping */ int ofw_write( int handle, const char *data, int len ) { int ret; le_swap( data, data + len, data ); @@ -77,12 +76,15 @@ return ret; }
+/* Since this is from external storage, it doesn't need swapping */ int ofw_read( int handle, const char *data, int len ) { int ret; + le_swap( data, data + len, data ); ret = ofproxy ( 12, (void *)handle, (char *)data, (void *)len, NULL ); le_swap( data, data + len, data ); + return ret; }
@@ -105,14 +107,75 @@ ofproxy( 28, (void *)num, NULL, NULL, NULL ); }
+int ofw_open( const char *name ) { + int ret, len; + + len = strlen(name); + le_swap( name, name + len, name ); + ret = ofproxy( 32, (char *)name, NULL, NULL, NULL ); + le_swap( name, name + len, name ); + return ret; +} + +int ofw_child( int package ) { + return ofproxy( 36, (void *)package, NULL, NULL, NULL ); +} + +int ofw_peer( int package ) { + return ofproxy( 40, (void *)package, NULL, NULL, NULL ); +} + +int ofw_seek( int handle, long long location ) { + return ofproxy( 44, (void *)handle, (void *)(int)(location >> 32), (void *)(int)location, NULL ); +} + void PpcPutChar( int ch ) { char buf[3]; - if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; } + if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; } else { buf[0] = ch; buf[1] = 0; } buf[2] = 0; ofw_print_string( buf ); }
+int PpcFindDevice( int depth, int parent, char *devname, int *nth ) { + static char buf[256]; + int next = 0; + int gotname = 0; + int match = 0; + int i; + + next = ofw_child( parent ); + + //printf( "next = %x\n", next ); + + gotname = ofw_getprop(parent, "name", buf, 256); + + //printf( "gotname = %d\n", gotname ); + + match = !strncmp(buf, devname, strlen(devname)); + + if( !nth && match ) return parent; + else if( match ) *nth--; + + for( i = 0; i < depth; i++ ) PpcPutChar( ' ' ); + + if( depth == 1 ) { + if( gotname > 0 ) { + printf( "%c Name: %s\n", match ? '*' : ' ', buf ); + } else { + printf( "- No name attribute for %x\n", parent ); + } + } + + while( !match && next ) { + i = PpcFindDevice( depth+1, next, devname, nth ); + if( i ) return i; + next = ofw_peer( next ); + } + + return 0; +} + BOOL PpcConsKbHit() { return TRUE; } @@ -167,12 +230,12 @@ return FALSE; }
-VOID PpcVideoSetPaletteColor( UCHAR Color, +VOID PpcVideoSetPaletteColor( UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue ) { printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue ); }
-VOID PpcVideoGetPaletteColor( UCHAR Color, +VOID PpcVideoGetPaletteColor( UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue ) { printf( "GetPaletteColor(%x)\n", Color); } @@ -198,16 +261,74 @@ BiosMemoryMap[0].BaseAddress = 0; BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */
- printf( "Returning memory map (%dk total)\n", + printf( "Returning memory map (%dk total)\n", (int)BiosMemoryMap[0].Length / 1024 );
return 1; }
+/* Strategy: + * + * For now, it'll be easy enough to use the boot command line as our boot path. + * Treat it as the path of a disk partition. We might even be able to get + * away with grabbing a partition image by tftp in this scenario. + */ + +BOOL PpcDiskGetBootVolume( PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType ) { + *DriveNumber = 0; + *StartSector = 0; + *SectorCount = 0; + *FsType = FS_FAT; + return TRUE; +} + +BOOL PpcDiskGetSystemVolume( char *SystemPath, + char *RemainingPath, + PULONG Device, + PULONG DriveNumber, + PULONGLONG StartSector, + PULONGLONG SectorCount, + int *FsType ) { + return FALSE; +} + +BOOL PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) { + strncpy( OutBootPath, BootPath, Size ); + return TRUE; +} + +VOID PpcDiskGetBootDevice( PULONG BootDevice ) { + BootDevice[0] = BootDevice[1] = 0; +} + +BOOL PpcDiskBootingFromFloppy(VOID) { + return FALSE; +} + BOOL PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer ) { - printf("DiskReadLogicalSectors\n"); - return FALSE; + int rlen = 0; + + if( part_handle == -1 ) { + part_handle = ofw_open( BootPart ); + + if( part_handle == -1 ) { + printf("Could not open any disk devices we know about\n"); + return FALSE; + } + } + + if( part_handle == -1 ) { + printf("Got partition handle %x\n", part_handle); + return FALSE; + } + + if( ofw_seek( part_handle, SectorNumber * 512 ) ) { + printf("Seek to %x failed\n", SectorNumber * 512); + return FALSE; + } + rlen = ofw_read( part_handle, Buffer, SectorCount * 512 ); + return rlen > 0; }
BOOL PpcDiskGetPartitionEntry( ULONG DriveNumber, ULONG PartitionNumber, @@ -218,24 +339,32 @@
BOOL PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY DriveGeometry ) { printf("GetGeometry(%d)\n", DriveNumber); - return FALSE; + DriveGeometry->BytesPerSector = 512; + DriveGeometry->Heads = 16; + DriveGeometry->Sectors = 63; + return TRUE; }
ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) { printf("GetCacheableBlockCount\n"); - return 0; + return 1; }
-VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day, +VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second ) { printf("RTCGeturrentDateTime\n"); }
VOID PpcHwDetect() { + printf("PpcHwDetect\n"); }
+typedef unsigned int uint32_t; + void PpcInit( of_proxy the_ofproxy ) { + int len; ofproxy = the_ofproxy; + chosen_package = ofw_finddevice( "/chosen" );
ofw_getprop( chosen_package, "stdin", @@ -246,9 +375,9 @@ MachVtbl.ConsPutChar = PpcPutChar; MachVtbl.ConsKbHit = PpcConsKbHit; MachVtbl.ConsGetCh = PpcConsGetCh; + + printf( "stdin_handle is %x\n", stdin_handle );
- printf("chosen_package = %x\n", chosen_package); - MachVtbl.VideoClearScreen = PpcVideoClearScreen; MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode; MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize; @@ -256,7 +385,7 @@ MachVtbl.VideoSetTextCursorPosition = PpcVideoSetTextCursorPosition; MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor; MachVtbl.VideoPutChar = PpcVideoPutChar; - MachVtbl.VideoCopyOffScreenBufferToVRAM = + MachVtbl.VideoCopyOffScreenBufferToVRAM = PpcVideoCopyOffScreenBufferToVRAM; MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed; MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor; @@ -266,6 +395,11 @@
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+ MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume; + MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume; + MachVtbl.DiskGetBootPath = PpcDiskGetBootPath; + MachVtbl.DiskGetBootDevice = PpcDiskGetBootDevice; + MachVtbl.DiskBootingFromFloppy = PpcDiskBootingFromFloppy; MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors; MachVtbl.DiskGetPartitionEntry = PpcDiskGetPartitionEntry; MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry; @@ -276,24 +410,57 @@ MachVtbl.HwDetect = PpcHwDetect;
printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() ); - BootMain("freeldr-ppc"); -}
-void MachInit(const char *CmdLine) { - int len; - printf( "Determining boot device:\n" ); - len = ofw_getprop(chosen_package, "bootpath", - BootPath, sizeof(BootPath)); - printf( "Got %d bytes of path\n", len ); - BootPath[len] = 0; - printf( "Boot Path: %s\n", BootPath ); + len = ofw_getprop(chosen_package, "bootargs", + CmdLine, sizeof(CmdLine));
- printf( "FreeLDR starting\n" ); + if( len < 0 ) len = 0; + CmdLine[len] = 0; + + BootMain( CmdLine ); }
-void FrLdrSetupPageDirectory() { +void MachInit(char *CmdLine) { + int len, i; + char *sep; + + BootPart[0] = 0; + BootPath[0] = 0; + + printf( "Determining boot device: [%s]\n", CmdLine ); + + printf( "Boot Args: %s\n", CmdLine ); + sep = NULL; + for( i = 0; i < strlen(CmdLine); i++ ) { + if( strncmp(CmdLine + i, "boot=", 5) == 0) { + strcpy(BootPart, CmdLine + i + 5); + sep = strchr(BootPart, ' '); + if( sep ) + *sep = 0; + break; + } + } + + if( strlen(BootPart) == 0 ) { + len = ofw_getprop(chosen_package, "bootpath", + BootPath, sizeof(BootPath)); + + if( len < 0 ) len = 0; + BootPath[len] = 0; + printf( "Boot Path: %s\n", BootPath ); + + sep = strrchr(BootPath, ','); + + strcpy(BootPart, BootPath); + if( sep ) { + BootPart[sep - BootPath] = 0; + } + } + + printf( "FreeLDR starting (boot partition: %s)\n", BootPart ); }
+/* Compatibility functions that don't do much */ void beep() { }
@@ -303,3 +470,18 @@
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) { } + +void DiskStopFloppyMotor() { +} + +void BootOldLinuxKernel( unsigned long size ) { + ofw_exit(); +} + +void BootNewLinuxKernel() { + ofw_exit(); +} + +void ChainLoadBiosBootSectorCode() { + ofw_exit(); +} _____
Added: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c --- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c 2005-12-04 12:07:08 UTC (rev 19856) +++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c 2005-12-04 12:13:48 UTC (rev 19857) @@ -0,0 +1,661 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: Freeloader + * FILE: boot/freeldr/freeldr/multiboot.c + * PURPOSE: ReactOS Loader + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Hartmut Birr - SMP/PAE Code + */ + +#include <freeldr.h> +#include <internal/powerpc/ke.h> + +#define NDEBUG +#include <debug.h> + +/* Base Addres of Kernel in Physical Memory */ +#define KERNEL_BASE_PHYS 0x200000 + +/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ +#define PFN_SHIFT 12 + +/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */ +#define PDE_SHIFT 20 +#define PDE_SHIFT_PAE 18 + + +/* Converts a Relative Address read from the Kernel into a Physical Address */ +#define RaToPa(p) \ + (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS) + +/* Converts a Phsyical Address Pointer into a Page Frame Number */ +#define PaPtrToPfn(p) \ + (((ULONG_PTR)&p) >> PFN_SHIFT) + +/* Converts a Phsyical Address into a Page Frame Number */ +#define PaToPfn(p) \ + ((p) >> PFN_SHIFT) + +#define STARTUP_BASE 0xF0000000 +#define HYPERSPACE_BASE 0xF0800000 +#define APIC_BASE 0xFEC00000 +#define KPCR_BASE 0xFF000000 + +#define LowMemPageTableIndex 0 +#define StartupPageTableIndex (STARTUP_BASE >> 20) / sizeof(HARDWARE_PTE_X86) +#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 20) / sizeof(HARDWARE_PTE_X86) +#define KpcrPageTableIndex (KPCR_BASE >> 20) / sizeof(HARDWARE_PTE_X86) +#define ApicPageTableIndex (APIC_BASE >> 20) / sizeof(HARDWARE_PTE_X86) + +#define LowMemPageTableIndexPae 0 +#define StartupPageTableIndexPae (STARTUP_BASE >> 21) +#define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21) +#define KpcrPageTableIndexPae (KPCR_BASE >> 21) +#define ApicPageTableIndexPae (APIC_BASE >> 21) + + +#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase + +/* Load Address of Next Module */ +ULONG_PTR NextModuleBase = 0; + +/* Currently Opened Module */ +PFRLDR_MODULE CurrentModule = NULL; + +/* Unrelocated Kernel Base in Virtual Memory */ +ULONG_PTR KernelBase; + +/* Wether PAE is to be used or not */ +BOOLEAN PaeModeEnabled; + +/* Kernel Entrypoint in Physical Memory */ +ULONG_PTR KernelEntry; + +/* FUNCTIONS *****************************************************************/ + +/*++ + * FrLdrStartup + * INTERNAL + * + * Prepares the system for loading the Kernel. + * + * Params: + * Magic - Multiboot Magic + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +STDCALL +FrLdrStartup(ULONG Magic) +{ +#if 0 + /* Disable Interrupts */ + KeArchDisableInterrupts(); + + /* Re-initalize EFLAGS */ + KeArchEraseFlags(); + + /* Initialize the page directory */ + FrLdrSetupPageDirectory(); +#endif +} + +/*++ + * FrLdrGetKernelBase + * INTERNAL + * + * Gets the Kernel Base to use. + * + * Params: + * + * Returns: + * None. + * + * Remarks: + * Sets both the FreeLdr internal variable as well as the one which + * will be used by the Kernel. + * + *--*/ +VOID +FASTCALL +FrLdrGetKernelBase(VOID) +{ + PCHAR p; + + /* Read Command Line */ + p = (PCHAR)LoaderBlock.CommandLine; + while ((p = strchr(p, '/')) != NULL) { + + /* Find "/3GB" */ + if (!strnicmp(p + 1, "3GB", 3)) { + + /* Make sure there's nothing following it */ + if (p[4] == ' ' || p[4] == 0) { + + /* Use 3GB */ + KernelBase = 0xC0000000; + } + } + + p++; + } + + /* Set KernelBase */ + LoaderBlock.KernelBase = KernelBase; +} + +/*++ + * FrLdrSetupPageDirectory + * INTERNAL + * + * Sets up the ReactOS Startup Page Directory. + * + * Params: + * None. + * + * Returns: + * None. + * + * Remarks: + * We are setting PDEs, but using the equvivalent (for our purpose) PTE structure. + * As such, please note that PageFrameNumber == PageEntryNumber. + * + *--*/ +VOID +FASTCALL +FrLdrSetupPageDirectory(VOID) +{ +#if 0 + PPAGE_DIRECTORY_X86 PageDir; + PPAGE_DIRECTORY_TABLE_X64 PageDirTablePae; + PPAGE_DIRECTORY_X64 PageDirPae; + ULONG KernelPageTableIndex; + ULONG i; + + if (PaeModeEnabled) { + + /* Get the Kernel Table Index */ + KernelPageTableIndex = (KernelBase >> 21); + + /* Get the Startup Page Directory Table */ + PageDirTablePae = (PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae; + + /* Get the Startup Page Directory */ + PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae; + + /* Set the Startup page directory table */ + for (i = 0; i < 4; i++) + { + PageDirTablePae->Pde[i].Valid = 1; + PageDirTablePae->Pde[i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i; + } + + /* Set up the Low Memory PDE */ + for (i = 0; i < 2; i++) + { + PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1; + PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1; + PageDirPae->Pde[LowMemPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i; + } + + /* Set up the Kernel PDEs */ + for (i = 0; i < 3; i++) + { + PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1; + PageDirPae->Pde[KernelPageTableIndex + i].Write = 1; + PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber = PaPtrToPfn(kernel_pagetable_pae) + i; + } + + /* Set up the Startup PDE */ + for (i = 0; i < 4; i++) + { + PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1; + PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1; + PageDirPae->Pde[StartupPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i; + } + + /* Set up the Hyperspace PDE */ + for (i = 0; i < 2; i++) + { + PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1; + PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1; + PageDirPae->Pde[HyperspacePageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i; + } + + /* Set up the Apic PDE */ + for (i = 0; i < 2; i++) + { + PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1; + PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1; + PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(apic_pagetable_pae) + i; + } + + /* Set up the KPCR PDE */ + PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1; + PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1; + PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber = PaPtrToPfn(kpcr_pagetable_pae); + + /* Set up Low Memory PTEs */ + PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae; + for (i=0; i<1024; i++) { + + PageDirPae->Pde[i].Valid = 1; + PageDirPae->Pde[i].Write = 1; + PageDirPae->Pde[i].Owner = 1; + PageDirPae->Pde[i].PageFrameNumber = i; + } + + /* Set up Kernel PTEs */ + PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae; + for (i=0; i<1536; i++) { + + PageDirPae->Pde[i].Valid = 1; + PageDirPae->Pde[i].Write = 1; [truncated at 1000 lines; 403 more skipped]