Author: arty Date: Thu Aug 31 12:01:30 2006 New Revision: 23835
URL: http://svn.reactos.org/svn/reactos?rev=23835&view=rev Log: Some intermediate work. We start loading the kernel now. Working on early boot memory mapping. We'll rely heavily on open firmware until we're on our own page table.
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/boot/freeldr/fre... ============================================================================== --- branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c (original) +++ branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c Thu Aug 31 12:01:30 2006 @@ -25,7 +25,7 @@ extern void BootMain( char * ); extern char *GetFreeLoaderVersionString(); of_proxy ofproxy; -void *PageDirectoryStart, *PageDirectoryEnd; +void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0; static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; @@ -95,7 +95,7 @@ }
BOOLEAN PpcConsKbHit() { - return TRUE; + return FALSE; }
int PpcConsGetCh() { @@ -193,6 +193,14 @@
printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
+ if( mem_base ) { + BiosMemoryMap[0].Type = MEMTYPE_USABLE; + BiosMemoryMap[0].BaseAddress = (ULONG)mem_base; + BiosMemoryMap[0].Length = TOTAL_HEAP_NEEDED; + printf("[cached] returning 1 element\n"); + return 1; + } + ofw_getprop(chosen_package, "memory", (char *)&memhandle, sizeof(memhandle)); ofw_getprop(chosen_package, "mmu", @@ -207,8 +215,10 @@ for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) { BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE; BiosMemoryMap[num_mem].BaseAddress = memdata[i]; + mem_base = (void *)memdata[i]; BiosMemoryMap[num_mem].Length = memdata[i+1]; - if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED ) { + if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED && + total < TOTAL_HEAP_NEEDED ) { BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; ofw_claim(BiosMemoryMap[num_mem].BaseAddress, BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ @@ -248,7 +258,14 @@ PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType ) { - return FALSE; + char *remain = strchr(SystemPath, '\'); + if( remain ) { + strcpy( RemainingPath, remain+1 ); + } else { + RemainingPath[0] = 0; + } + *Device = 0; + return PpcDiskGetBootVolume(DriveNumber, StartSector, SectorCount, FsType); }
BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) { @@ -318,6 +335,44 @@
VOID PpcHwDetect() { printf("PpcHwDetect\n"); +} + +BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) { + CHAR BootPath[256]; + ULONG PartitionNumber; + ULONG DriveNumber; + PARTITION_TABLE_ENTRY PartEntry; + char *p; + + if (!DissectArcPath(SystemPath, BootPath, &DriveNumber, &PartitionNumber)) + { + return FALSE; + } + + if (0 != PartitionNumber) + { + return TRUE; + } + + if (! DiskGetActivePartitionEntry(DriveNumber, + &PartEntry, + &PartitionNumber) || + PartitionNumber < 1 || 9 < PartitionNumber) + { + return FALSE; + } + + p = SystemPath; + while ('\0' != *p && 0 != _strnicmp(p, "partition(", 10)) { + p++; + } + p = strchr(p, ')'); + if (NULL == p || '0' != *(p - 1)) { + return FALSE; + } + *(p - 1) = '0' + PartitionNumber; + + return TRUE; }
typedef unsigned int uint32_t; @@ -368,6 +423,7 @@
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+ MachVtbl.DiskNormalizeSystemPath = PpcDiskNormalizeSystemPath; MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume; MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume; MachVtbl.DiskGetBootPath = PpcDiskGetBootPath;
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/boot/freeldr/fre... ============================================================================== --- branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c (original) +++ branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c Thu Aug 31 12:01:30 2006 @@ -1,59 +1,68 @@ /* - * 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) + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer brianp@sginet.com + * Copyright (C) 2005 Alex Ionescu alex@relsoft.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <freeldr.h> -#include <internal/powerpc/ke.h> + +#include <of_call.h>
#define NDEBUG #include <debug.h>
-int xstrnicmp( const char *a, const char *b, int n ) { - while( n-- && *a && (*a++ == *b++) ); - return *a - *b; -} - -/* Base Addres of Kernel in Physical Memory */ -#define KERNEL_BASE_PHYS 0x200000 +static PVOID KernelMemory = 0;
/* 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 22 #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) - +ULONG RaToPa(ULONG p) { + return ofw_virt2phys((ULONG)(p + KernelMemory), 1); +} + /* 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 STARTUP_BASE 0xC0000000 +#define HYPERSPACE_BASE 0xC0400000 +#define HYPERSPACE_PAE_BASE 0xC0800000 #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 StartupPageTableIndex (STARTUP_BASE >> 22) +#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22) +#define KpcrPageTableIndex (KPCR_BASE >> 22) +#define ApicPageTableIndex (APIC_BASE >> 22)
#define LowMemPageTableIndexPae 0 #define StartupPageTableIndexPae (STARTUP_BASE >> 21) -#define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21) +#define HyperspacePageTableIndexPae (HYPERSPACE_PAE_BASE >> 21) #define KpcrPageTableIndexPae (KPCR_BASE >> 21) #define ApicPageTableIndexPae (APIC_BASE >> 21)
@@ -64,7 +73,7 @@ ULONG_PTR NextModuleBase = 0;
/* Currently Opened Module */ -VOID *CurrentModule = NULL; +PLOADER_MODULE CurrentModule = NULL;
/* Unrelocated Kernel Base in Virtual Memory */ ULONG_PTR KernelBase; @@ -78,7 +87,7 @@ /* FUNCTIONS *****************************************************************/
/*++ - * FrLdrStartup + * FrLdrStartup * INTERNAL * * Prepares the system for loading the Kernel. @@ -96,21 +105,34 @@ VOID NTAPI FrLdrStartup(ULONG Magic) -{ -#if 0 - /* Disable Interrupts */ - KeArchDisableInterrupts(); - - /* Re-initalize EFLAGS */ - KeArchEraseFlags(); - - /* Initialize the page directory */ - FrLdrSetupPageDirectory(); -#endif +{ }
/*++ - * FrLdrGetKernelBase + * FrLdrSetupPae + * INTERNAL + * + * Configures PAE on a MP System, and sets the PDBR if it's supported, or if + * the system is UP. + * + * Params: + * Magic - Multiboot Magic + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +FASTCALL +FrLdrSetupPae(ULONG Magic) +{ +} + +/*++ + * FrLdrGetKernelBase * INTERNAL * * Gets the Kernel Base to use. @@ -125,36 +147,59 @@ * will be used by the Kernel. * *--*/ -VOID +static VOID FASTCALL FrLdrGetKernelBase(VOID) { PCHAR p; - + + /* Set KernelBase */ + LoaderBlock.KernelBase = KernelBase; + /* Read Command Line */ p = (PCHAR)LoaderBlock.CommandLine; while ((p = strchr(p, '/')) != NULL) { - + /* Find "/3GB" */ - if (!xstrnicmp(p + 1, "3GB", 3)) { - + if (!_strnicmp(p + 1, "3GB", 3)) { + /* Make sure there's nothing following it */ if (p[4] == ' ' || p[4] == 0) { - + /* Use 3GB */ - KernelBase = 0xC0000000; + KernelBase = 0xE0000000; + LoaderBlock.KernelBase = 0xC0000000; } }
p++; } - - /* Set KernelBase */ - LoaderBlock.KernelBase = KernelBase; }
/*++ - * FrLdrSetupPageDirectory + * FrLdrGetPaeMode + * INTERNAL + * + * Determines whether PAE mode shoudl be enabled or not. + * + * Params: + * None. + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +FASTCALL +FrLdrGetPaeMode(VOID) +{ +} + +/*++ + * FrLdrSetupPageDirectory * INTERNAL * * Sets up the ReactOS Startup Page Directory. @@ -174,199 +219,10 @@ 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; - PageDirPae->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS) + i; - } - - /* Set up APIC PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&apic_pagetable_pae; - PageDirPae->Pde[0].Valid = 1; - PageDirPae->Pde[0].Write = 1; - PageDirPae->Pde[0].CacheDisable = 1; - PageDirPae->Pde[0].WriteThrough = 1; - PageDirPae->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE); - PageDirPae->Pde[0x200].Valid = 1; - PageDirPae->Pde[0x200].Write = 1; - PageDirPae->Pde[0x200].CacheDisable = 1; - PageDirPae->Pde[0x200].WriteThrough = 1; - PageDirPae->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS); - - /* Set up KPCR PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&kpcr_pagetable_pae; - PageDirPae->Pde[0].Valid = 1; - PageDirPae->Pde[0].Write = 1; - PageDirPae->Pde[0].PageFrameNumber = 1; - - } else { - - /* Get the Kernel Table Index */ - KernelPageTableIndex = (KernelBase >> PDE_SHIFT) / sizeof(HARDWARE_PTE_X86); - - /* Get the Startup Page Directory */ - PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory; - - /* Set up the Low Memory PDE */ - PageDir->Pde[LowMemPageTableIndex].Valid = 1; - PageDir->Pde[LowMemPageTableIndex].Write = 1; - PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable); - - /* Set up the Kernel PDEs */ - PageDir->Pde[KernelPageTableIndex].Valid = 1; - PageDir->Pde[KernelPageTableIndex].Write = 1; - PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable); - PageDir->Pde[KernelPageTableIndex + 1].Valid = 1; - PageDir->Pde[KernelPageTableIndex + 1].Write = 1; - PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096); - - /* Set up the Startup PDE */ - PageDir->Pde[StartupPageTableIndex].Valid = 1; - PageDir->Pde[StartupPageTableIndex].Write = 1; - PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory); - - /* Set up the Hyperspace PDE */ - PageDir->Pde[HyperspacePageTableIndex].Valid = 1; - PageDir->Pde[HyperspacePageTableIndex].Write = 1; - PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable); - - /* Set up the Apic PDE */ - PageDir->Pde[ApicPageTableIndex].Valid = 1; - PageDir->Pde[ApicPageTableIndex].Write = 1; - PageDir->Pde[ApicPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable); - - /* Set up the KPCR PDE */ - PageDir->Pde[KpcrPageTableIndex].Valid = 1; - PageDir->Pde[KpcrPageTableIndex].Write = 1; - PageDir->Pde[KpcrPageTableIndex].PageFrameNumber = PaPtrToPfn(kpcr_pagetable); - - /* Set up Low Memory PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable; - for (i=0; i<1024; i++) { - - PageDir->Pde[i].Valid = 1; - PageDir->Pde[i].Write = 1; - PageDir->Pde[i].Owner = 1; - PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE); - } - - /* Set up Kernel PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable; - for (i=0; i<1536; i++) { - - PageDir->Pde[i].Valid = 1; - PageDir->Pde[i].Write = 1; - PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE); - } - - /* Set up APIC PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable; - PageDir->Pde[0].Valid = 1; - PageDir->Pde[0].Write = 1; - PageDir->Pde[0].CacheDisable = 1; - PageDir->Pde[0].WriteThrough = 1; - PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE); - PageDir->Pde[0x200].Valid = 1; - PageDir->Pde[0x200].Write = 1; - PageDir->Pde[0x200].CacheDisable = 1; - PageDir->Pde[0x200].WriteThrough = 1; - PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS); - - /* Set up KPCR PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable; - PageDir->Pde[0].Valid = 1; - PageDir->Pde[0].Write = 1; - PageDir->Pde[0].PageFrameNumber = 1; - } - return; -#endif }
/*++ - * FrLdrMapKernel + * FrLdrMapKernel * INTERNAL * * Maps the Kernel into memory, does PE Section Mapping, initalizes the @@ -386,7 +242,6 @@ NTAPI FrLdrMapKernel(FILE *KernelImage) { -#if 0 PIMAGE_DOS_HEADER ImageHeader; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER Section; @@ -395,7 +250,7 @@ ULONG_PTR SourceSection; ULONG_PTR TargetSection; ULONG SectionSize; - LONG i; + INT i; PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; ULONG Count; @@ -407,10 +262,10 @@
/* Allocate 1024 bytes for PE Header */ ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024); - + /* Make sure it was succesful */ if (ImageHeader == NULL) { - + return FALSE; }
@@ -424,94 +279,97 @@
/* Now read the MZ header to get the offset to the PE Header */ NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew); - + /* Get Kernel Base */ - KernelBase = NtHeader->OptionalHeader.ImageBase; + KernelBase = NtHeader->OptionalHeader.ImageBase; FrLdrGetKernelBase(); - + + printf("About to do RaToPa(%x)\n", + NtHeader->OptionalHeader.AddressOfEntryPoint); /* Save Entrypoint */ KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); - + printf("RaToPa -> %x\n", KernelEntry); + /* Save the Image Size */ ImageSize = NtHeader->OptionalHeader.SizeOfImage; - + /* Free the Header */ MmFreeMemory(ImageHeader);
/* Set the file pointer to zero */ FsSetFilePointer(KernelImage, 0);
+ /* Allocate kernel memory */ + KernelMemory = MmAllocateMemory(ImageSize); + /* Load the file image */ - FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS); - + FsReadFile(KernelImage, ImageSize, NULL, KernelMemory); + /* Reload the NT Header */ - NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew); - + NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KernelMemory + ImageHeader->e_lfanew); + /* Load the first section */ Section = IMAGE_FIRST_SECTION(NtHeader); SectionCount = NtHeader->FileHeader.NumberOfSections - 1; - + /* Now go to the last section */ Section += SectionCount; - - /* Walk each section backwards */ - for (i=SectionCount; i >= 0; i--, Section--) { - - /* Get the disk location and the memory location, and the size */ + + /* Walk each section backwards */ + for (i=(INT)SectionCount; i >= 0; i--, Section--) { + + /* Get the disk location and the memory location, and the size */ SourceSection = RaToPa(Section->PointerToRawData); TargetSection = RaToPa(Section->VirtualAddress); SectionSize = Section->SizeOfRawData; - + /* If the section is already mapped correctly, go to the next */ if (SourceSection == TargetSection) continue; - + /* Load it into memory */ memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize); - + /* Check for unitilizated data */ if (Section->SizeOfRawData < Section->Misc.VirtualSize) { - + /* Zero it out */ - memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData), + memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData), 0, Section->Misc.VirtualSize - Section->SizeOfRawData); } } - + /* Get the Relocation Data Directory */ RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - + /* Get the Relocation Section Start and End*/ - RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress); + RelocationDir = (PIMAGE_BASE_RELOCATION)(KernelMemory + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); - + /* Calculate Difference between Real Base and Compiled Base*/ - Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;; - + Delta = KernelBase - NtHeader->OptionalHeader.ImageBase; + /* Determine how far we shoudl relocate */ - MaxAddress = KERNEL_BASE_PHYS + ImageSize; - + MaxAddress = (ULONG)KernelMemory + ImageSize; + /* Relocate until we've processed all the blocks */ while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { - + /* See how many Relocation Blocks we have */ Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - + /* Calculate the Address of this Directory */ - Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress; - + Address = (ULONG)KernelMemory + RelocationDir->VirtualAddress; + /* Calculate the Offset of the Type */ TypeOffset = (PUSHORT)(RelocationDir + 1);
- for (i = 0; i < Count; i++) { - + for (i = 0; i < (INT)Count; i++) { + ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
- /* Don't relocate after the end of the loaded driver */ - if ((ULONG_PTR)ShortPtr >= MaxAddress) break; - switch (*TypeOffset >> 12) { - + case IMAGE_REL_BASED_ABSOLUTE: break;
@@ -528,65 +386,63 @@ *LongPtr += Delta; break; } - + TypeOffset++; } - + /* Move to the next Relocation Table */ RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } - + /* Increase the next Load Base */ - NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE); + NextModuleBase = ROUND_UP((ULONG)KernelMemory + ImageSize, PAGE_SIZE);
/* Return Success */ -#endif return TRUE; }
ULONG_PTR NTAPI -FrLdrLoadModule(FILE *ModuleImage, - LPCSTR ModuleName, +FrLdrLoadModule(FILE *ModuleImage, + LPCSTR ModuleName, PULONG ModuleSize) { -#if 0 ULONG LocalModuleSize; - PFRLDR_MODULE ModuleData; + PLOADER_MODULE ModuleData; LPSTR NameBuffer; LPSTR TempName;
/* Get current module data structure and module name string array */ - ModuleData = &multiboot_modules[LoaderBlock.ModsCount]; - + ModuleData = &reactos_modules[LoaderBlock.ModsCount]; + /* Get only the Module Name */ do { - + TempName = strchr(ModuleName, '\'); - + if(TempName) { ModuleName = TempName + 1; }
} while(TempName); - NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount]; + NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Get Module Size */ LocalModuleSize = FsGetFileSize(ModuleImage); - + /* Fill out Module Data Structure */ - ModuleData->ModuleStart = NextModuleBase; - ModuleData->ModuleEnd = NextModuleBase + LocalModuleSize; - + ModuleData->ModStart = NextModuleBase; + ModuleData->ModEnd = NextModuleBase + LocalModuleSize; + /* Save name */ strcpy(NameBuffer, ModuleName); - ModuleData->ModuleName = NameBuffer; + ModuleData->String = (ULONG_PTR)NameBuffer;
/* Load the file image */ FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
/* Move to next memory block and increase Module Count */ - NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE); + NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE); LoaderBlock.ModsCount++;
/* Return Module Size if required */ @@ -594,63 +450,55 @@ *ModuleSize = LocalModuleSize; }
- return(ModuleData->ModuleStart); -#else - return 0; -#endif + return(ModuleData->ModStart); }
ULONG_PTR NTAPI FrLdrCreateModule(LPCSTR ModuleName) { -#if 0 - PFRLDR_MODULE ModuleData; + PLOADER_MODULE ModuleData; LPSTR NameBuffer;
/* Get current module data structure and module name string array */ - ModuleData = &multiboot_modules[LoaderBlock.ModsCount]; - NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount]; + ModuleData = &reactos_modules[LoaderBlock.ModsCount]; + NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Set up the structure */ - ModuleData->ModuleStart = NextModuleBase; - ModuleData->ModuleEnd = -1; - + ModuleData->ModStart = NextModuleBase; + ModuleData->ModEnd = -1; + /* Copy the name */ strcpy(NameBuffer, ModuleName); - ModuleData->ModuleName = NameBuffer; + ModuleData->String = (ULONG_PTR)NameBuffer;
/* Set the current Module */ CurrentModule = ModuleData;
/* Return Module Base Address */ - return(ModuleData->ModuleStart); -#else - return 0; -#endif + return(ModuleData->ModStart); }
BOOLEAN NTAPI -FrLdrCloseModule(ULONG_PTR ModuleBase, +FrLdrCloseModule(ULONG_PTR ModuleBase, ULONG ModuleSize) { -#if 0 - PFRLDR_MODULE ModuleData = CurrentModule; + PLOADER_MODULE ModuleData = CurrentModule;
/* Make sure a module is opened */ if (ModuleData) { - + /* Make sure this is the right module and that it hasn't been closed */ - if ((ModuleBase == ModuleData->ModuleStart) && (ModuleData->ModuleEnd == -1)) { - + if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) { + /* Close the Module */ - ModuleData->ModuleEnd = ModuleData->ModuleStart + ModuleSize; + ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
/* Set the next Module Base and increase the number of modules */ - NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE); + NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE); LoaderBlock.ModsCount++; - + /* Close the currently opened module */ CurrentModule = NULL;
@@ -660,6 +508,5 @@ }
/* Failure path */ -#endif return(FALSE); }