ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mboot.c
Go to the documentation of this file.
00001 /*
00002  *  FreeLoader
00003  *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
00004  *  Copyright (C) 2005       Alex Ionescu  <alex@relsoft.net>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 
00021 #include <freeldr.h>
00022 #include <elf/elf.h>
00023 #include <elf/reactos.h>
00024 #include <of.h>
00025 #include "ppcmmu/mmu.h"
00026 #include "compat.h"
00027 
00028 #define NDEBUG
00029 #include <debug.h>
00030 
00031 /* We'll check this to see if we're in OFW land */
00032 extern of_proxy ofproxy;
00033 
00034 PVOID KernelMemory = 0;
00035 
00036 /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
00037 #define PFN_SHIFT 12
00038 
00039 /* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */
00040 #define PDE_SHIFT 22
00041 #define PDE_SHIFT_PAE 18
00042 
00043 #define STARTUP_BASE                0xC0000000
00044 #define HYPERSPACE_BASE             0xC0400000
00045 #define HYPERSPACE_PAE_BASE         0xC0800000
00046 #define APIC_BASE                   0xFEC00000
00047 #define KPCR_BASE                   0xFF000000
00048 
00049 #define LowMemPageTableIndex        0
00050 #define StartupPageTableIndex       (STARTUP_BASE >> 22)
00051 #define HyperspacePageTableIndex    (HYPERSPACE_BASE >> 22)
00052 #define KpcrPageTableIndex          (KPCR_BASE >> 22)
00053 #define ApicPageTableIndex          (APIC_BASE >> 22)
00054 
00055 #define BAT_GRANULARITY             (64 * 1024)
00056 #define KernelMemorySize            (8 * 1024 * 1024)
00057 #define XROUNDUP(x,n)               ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
00058 
00059 char reactos_module_strings[64][256];   // Array to hold module names
00060 
00061 /* Load Address of Next Module */
00062 ULONG_PTR NextModuleBase = 0;
00063 
00064 /* Currently Opened Module */
00065 PLOADER_MODULE CurrentModule = NULL;
00066 
00067 /* Unrelocated Kernel Base in Virtual Memory */
00068 ULONG_PTR KernelBase;
00069 
00070 /* Wether PAE is to be used or not */
00071 BOOLEAN PaeModeEnabled;
00072 
00073 /* Kernel Entrypoint in Physical Memory */
00074 ULONG_PTR KernelEntryPoint;
00075 
00076 /* Dummy to bring in memmove */
00077 PVOID memmove_dummy = memmove;
00078 
00079 PLOADER_MODULE
00080 NTAPI
00081 LdrGetModuleObject(PCHAR ModuleName);
00082 
00083 NTSTATUS
00084 NTAPI
00085 LdrPEFixupImports(IN PVOID DllBase,
00086                   IN PCHAR DllName);
00087 
00088 VOID PpcInitializeMmu(int max);
00089 
00090 /* FUNCTIONS *****************************************************************/
00091 
00092 /*++
00093  * FrLdrStartup
00094  * INTERNAL
00095  *
00096  *     Prepares the system for loading the Kernel.
00097  *
00098  * Params:
00099  *     Magic - Multiboot Magic
00100  *
00101  * Returns:
00102  *     None.
00103  *
00104  * Remarks:
00105  *     None.
00106  *
00107  *--*/
00108 
00109 typedef void (*KernelEntryFn)( void * );
00110 
00111 int MmuPageMiss(int trapCode, ppc_trap_frame_t *trap)
00112 {
00113     int i;
00114     printf("TRAP %x\n", trapCode);
00115     for( i = 0; i < 40; i++ )
00116     printf("r[%d] %x\n", i, trap->gpr[i]);
00117     printf("HALT!\n");
00118     while(1);
00119 }
00120 
00121 typedef struct _ppc_map_set_t {
00122     int mapsize;
00123     int usecount;
00124     ppc_map_info_t *info;
00125 } ppc_map_set_t;
00126 
00127 extern int mmu_handle;
00128 paddr_t MmuTranslate(paddr_t possibly_virtual)
00129 {
00130     if (ofproxy)
00131     {
00132         /* Openfirmware takes liberties with boot-time memory.
00133          * if you're in a unitary kernel, it's not as difficult, but since
00134          * we rely on loading things into virtual space from here, we need
00135          * to detect the mappings so far.
00136          */
00137         int args[2];
00138         args[0] = possibly_virtual;
00139         args[1] = 1; /* Marker to tell we want a physical addr */
00140         return (paddr_t)ofw_callmethod_ret("translate", mmu_handle, 2, args, 3);
00141     }
00142     else
00143     {
00144         /* Other booters don't remap ram */
00145         return possibly_virtual;
00146     }
00147 }
00148 
00149 VOID
00150 NTAPI
00151 FrLdrAddPageMapping(ppc_map_set_t *set, int proc, paddr_t phys, vaddr_t virt)
00152 {
00153     int j;
00154     paddr_t page = ROUND_DOWN(phys, (1<<PFN_SHIFT));
00155 
00156     if (virt == 0)
00157         virt = ROUND_DOWN(page, (1<<PFN_SHIFT));
00158     else
00159         virt = ROUND_DOWN(virt, (1<<PFN_SHIFT));
00160 
00161     page = MmuTranslate(page);
00162 
00163     //printf("Mapping virt [%x] to phys [%x (from) %x]\n", virt, page, phys);
00164 
00165     for( j = 0; j < set->usecount; j++ )
00166     {
00167         if(set->info[j].addr == page) return;
00168     }
00169 
00170     if (!set->mapsize)
00171     {
00172         set->mapsize = 0x80;
00173         set->info = MmAllocateMemory(0x80 * sizeof(*set->info));
00174     }
00175     else if (set->mapsize <= set->usecount)
00176     {
00177         ppc_map_info_t *newinfo = MmAllocateMemory(set->mapsize * 2 * sizeof(*set->info));
00178         memcpy(newinfo, set->info, set->mapsize * sizeof(*set->info));
00179         MmFreeMemory(set->info);
00180         set->info = newinfo;
00181         set->mapsize *= 2;
00182     }
00183 
00184     set->info[set->usecount].flags = MMU_ALL_RW;
00185     set->info[set->usecount].proc = proc;
00186     set->info[set->usecount].addr = virt;
00187     set->info[set->usecount].phys = page;
00188     set->usecount++;
00189 }
00190 
00191 extern int _start[], _end[];
00192 
00193 VOID
00194 NTAPI
00195 FrLdrStartup(ULONG Magic)
00196 {
00197     ULONG_PTR i, tmp, OldModCount = 0;
00198     PCHAR ModHeader;
00199     CHAR ModulesTreated[64] = { 0 };
00200     ULONG NumberOfEntries = 0, UsedEntries = 0;
00201     PPAGE_LOOKUP_TABLE_ITEM FreeLdrMap = MmGetMemoryMap(&NumberOfEntries);
00202     ppc_map_set_t memmap = { };
00203 
00204     printf("FrLdrStartup\n");
00205 
00206     /* Disable EE */
00207     __asm__("mfmsr %0" : "=r" (tmp));
00208     tmp &= 0x7fff;
00209     __asm__("mtmsr %0" : : "r" (tmp));
00210 
00211     while(OldModCount != LoaderBlock.ModsCount)
00212     {
00213         printf("Added %d modules last pass\n",
00214                LoaderBlock.ModsCount - OldModCount);
00215 
00216         OldModCount = LoaderBlock.ModsCount;
00217 
00218         for(i = 0; i < LoaderBlock.ModsCount; i++)
00219         {
00220             if (!ModulesTreated[i])
00221             {
00222                 ModulesTreated[i] = 1;
00223                 ModHeader = ((PCHAR)reactos_modules[i].ModStart);
00224                 if(ModHeader[0] == 'M' && ModHeader[1] == 'Z')
00225                     LdrPEFixupImports
00226                         ((PVOID)reactos_modules[i].ModStart,
00227                          (PCHAR)reactos_modules[i].String);
00228             }
00229         }
00230     }
00231 
00232     printf("Starting mmu\n");
00233 
00234     PpcInitializeMmu(0);
00235 
00236     printf("Allocating vsid 0 (kernel)\n");
00237     MmuAllocVsid(0, 0xff00);
00238 
00239     /* We'll use vsid 1 for freeldr (expendable) */
00240     printf("Allocating vsid 1 (freeldr)\n");
00241     MmuAllocVsid(1, 0xff);
00242 
00243     printf("Mapping Freeldr Code (%x-%x)\n", _start, _end);
00244 
00245     /* Map memory zones */
00246     /* Freeldr itself */
00247     for( i = (int)_start;
00248          i < (int)_end;
00249          i += (1<<PFN_SHIFT) ) {
00250         FrLdrAddPageMapping(&memmap, 1, i, 0);
00251     }
00252 
00253     printf("KernelBase %x\n", KernelBase);
00254 
00255     /* Heap pages -- this gets the entire freeldr heap */
00256     for( i = 0; i < NumberOfEntries; i++ ) {
00257         tmp = i<<PFN_SHIFT;
00258         if (FreeLdrMap[i].PageAllocated == LoaderSystemCode) {
00259             UsedEntries++;
00260             if (tmp >= (ULONG)KernelMemory &&
00261                 tmp <  (ULONG)KernelMemory + KernelMemorySize) {
00262                 FrLdrAddPageMapping(&memmap, 0, tmp, KernelBase + tmp - (ULONG)KernelMemory);
00263             } else {
00264                 FrLdrAddPageMapping(&memmap, 1, tmp, 0);
00265             }
00266         }
00267     }
00268 
00269     MmuMapPage(memmap.info, memmap.usecount);
00270 
00271     printf("Finished Mapping the Freeldr Heap (used %d pages)\n", UsedEntries);
00272 
00273     printf("Setting initial segments\n");
00274     MmuSetVsid(0, 8, 1);
00275     MmuSetVsid(8, 16, 0);
00276 
00277     printf("Segments set!\n");
00278 
00279     MmuTurnOn((KernelEntryFn)KernelEntryPoint, &LoaderBlock);
00280 
00281     /* Nothing more */
00282     while(1);
00283 }
00284 
00285 /*++
00286  * FrLdrSetupPae
00287  * INTERNAL
00288  *
00289  *     Configures PAE on a MP System, and sets the PDBR if it's supported, or if
00290  *     the system is UP.
00291  *
00292  * Params:
00293  *     Magic - Multiboot Magic
00294  *
00295  * Returns:
00296  *     None.
00297  *
00298  * Remarks:
00299  *     None.
00300  *
00301  *--*/
00302 VOID
00303 FASTCALL
00304 FrLdrSetupPae(ULONG Magic)
00305 {
00306 }
00307 
00308 /*++
00309  * FrLdrGetKernelBase
00310  * INTERNAL
00311  *
00312  *     Gets the Kernel Base to use.
00313  *
00314  * Params:
00315  *
00316  * Returns:
00317  *     None.
00318  *
00319  * Remarks:
00320  *     Sets both the FreeLdr internal variable as well as the one which
00321  *     will be used by the Kernel.
00322  *
00323  *--*/
00324 VOID
00325 FASTCALL
00326 FrLdrGetKernelBase(VOID)
00327 {
00328     PCHAR p;
00329 
00330     /* Default kernel base at 2GB */
00331     KernelBase = 0x80800000;
00332 
00333     /* Set KernelBase */
00334     LoaderBlock.KernelBase = 0x80000000;
00335 
00336     /* Read Command Line */
00337     p = (PCHAR)LoaderBlock.CommandLine;
00338     while ((p = strchr(p, '/')) != NULL) {
00339 
00340         /* Find "/3GB" */
00341         if (!_strnicmp(p + 1, "3GB", 3)) {
00342 
00343             /* Make sure there's nothing following it */
00344             if (p[4] == ' ' || p[4] == 0) {
00345 
00346                 /* Use 3GB */
00347                 KernelBase = 0xE0000000;
00348                 LoaderBlock.KernelBase = 0xC0000000;
00349             }
00350         }
00351 
00352         p++;
00353     }
00354 }
00355 
00356 /*++
00357  * FrLdrGetPaeMode
00358  * INTERNAL
00359  *
00360  *     Determines whether PAE mode shoudl be enabled or not.
00361  *
00362  * Params:
00363  *     None.
00364  *
00365  * Returns:
00366  *     None.
00367  *
00368  * Remarks:
00369  *     None.
00370  *
00371  *--*/
00372 VOID
00373 FASTCALL
00374 FrLdrGetPaeMode(VOID)
00375 {
00376 }
00377 
00378 /*++
00379  * FrLdrSetupPageDirectory
00380  * INTERNAL
00381  *
00382  *     Sets up the ReactOS Startup Page Directory.
00383  *
00384  * Params:
00385  *     None.
00386  *
00387  * Returns:
00388  *     None.
00389  *
00390  * Remarks:
00391  *     We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
00392  *     As such, please note that PageFrameNumber == PageEntryNumber.
00393  *
00394  *--*/
00395 VOID
00396 FASTCALL
00397 FrLdrSetupPageDirectory(VOID)
00398 {
00399 }
00400 
00401 /*++
00402  * FrLdrMapModule
00403  * INTERNAL
00404  *
00405  *     Loads the indicated elf image as PE.  The target will appear to be
00406  *     a PE image whose ImageBase has ever been KernelAddr.
00407  *
00408  * Params:
00409  *     Image -- File to load
00410  *     ImageName -- Name of image for the modules list
00411  *     MemLoadAddr -- Freeldr address of module
00412  *     KernelAddr -- Kernel address of module
00413  *--*/
00414 #define ELF_SECTION(n) ((Elf32_Shdr*)(sptr + (n * shsize)))
00415 #define COFF_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+(SWAPW(((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))))
00416 
00417 BOOLEAN
00418 NTAPI
00419 FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG KernelAddr)
00420 {
00421     PIMAGE_DOS_HEADER ImageHeader = 0;
00422     PIMAGE_NT_HEADERS NtHeader = 0;
00423     PIMAGE_SECTION_HEADER Section;
00424     ULONG SectionCount;
00425     ULONG ImageSize;
00426     INT i, j;
00427     PLOADER_MODULE ModuleData;
00428     //int phsize, phnum;
00429     int shsize, shnum, relsize, SectionAddr = 0;
00430     PCHAR sptr;
00431     Elf32_Ehdr ehdr;
00432     Elf32_Shdr *shdr;
00433     LPSTR TempName;
00434 
00435     TempName = strrchr(ImageName, '\\');
00436     if(TempName) TempName++; else TempName = (LPSTR)ImageName;
00437     ModuleData = LdrGetModuleObject(TempName);
00438 
00439     if(ModuleData)
00440     {
00441     return TRUE;
00442     }
00443 
00444     if(!KernelAddr)
00445     KernelAddr = (ULONG)NextModuleBase - (ULONG)KernelMemory + KernelBase;
00446     if(!MemLoadAddr)
00447     MemLoadAddr = (PCHAR)NextModuleBase;
00448 
00449     ModuleData = &reactos_modules[LoaderBlock.ModsCount];
00450     //printf("Loading file (elf at %x)\n", KernelAddr);
00451 
00452     /* Load the first 1024 bytes of the kernel image so we can read the PE header */
00453     if (!FsReadFile(KernelImage, sizeof(ehdr), NULL, &ehdr)) {
00454 
00455         /* Fail if we couldn't read */
00456     printf("Couldn't read the elf header\n");
00457         return FALSE;
00458     }
00459 
00460     /* Start by getting elf headers */
00461     //phsize = ehdr.e_phentsize;
00462     //phnum = ehdr.e_phnum;
00463     shsize = ehdr.e_shentsize;
00464     shnum = ehdr.e_shnum;
00465     sptr = (PCHAR)MmHeapAlloc(shnum * shsize);
00466 
00467     /* Read section headers */
00468     FsSetFilePointer(KernelImage,  ehdr.e_shoff);
00469     FsReadFile(KernelImage, shsize * shnum, NULL, sptr);
00470 
00471     /* Now we'll get the PE Header */
00472     for( i = 0; i < shnum; i++ )
00473     {
00474     shdr = ELF_SECTION(i);
00475     shdr->sh_addr = 0;
00476 
00477     /* Find the PE Header */
00478     if (shdr->sh_type == TYPE_PEHEADER)
00479     {
00480         FsSetFilePointer(KernelImage, shdr->sh_offset);
00481         FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr);
00482         ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
00483         NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
00484 #if 0
00485         printf("NtHeader at %x\n", SWAPD(ImageHeader->e_lfanew));
00486         printf("SectionAlignment %x\n",
00487            SWAPD(NtHeader->OptionalHeader.SectionAlignment));
00488         SectionAddr = ROUND_UP
00489         (shdr->sh_size, SWAPD(NtHeader->OptionalHeader.SectionAlignment));
00490         printf("Header ends at %x\n", SectionAddr);
00491 #endif
00492         break;
00493     }
00494     }
00495 
00496     if(i == shnum)
00497     {
00498     printf("No peheader section encountered :-(\n");
00499     return 0;
00500     }
00501 #if 0
00502     else
00503     {
00504         printf("DOS SIG: %s\n", (PCHAR)MemLoadAddr);
00505     }
00506 #endif
00507 
00508     /* Save the Image Base */
00509     NtHeader->OptionalHeader.ImageBase = SWAPD(KernelAddr);
00510 
00511     /* Load the file image */
00512     Section = COFF_FIRST_SECTION(NtHeader);
00513     SectionCount = SWAPW(NtHeader->FileHeader.NumberOfSections);
00514 
00515     /* Walk each section */
00516     for (i=0; i < SectionCount; i++, Section++)
00517     {
00518     shdr = ELF_SECTION((SWAPD(Section->PointerToRawData)+1));
00519 
00520     shdr->sh_addr = SectionAddr = SWAPD(Section->VirtualAddress);
00521     shdr->sh_addr += KernelAddr;
00522 
00523     Section->PointerToRawData = SWAPD((Section->VirtualAddress - KernelAddr));
00524 
00525     if (shdr->sh_type != SHT_NOBITS)
00526     {
00527         /* Content area */
00528         printf("Loading section %d at %x (real: %x:%d)\n", i, KernelAddr + SectionAddr, MemLoadAddr+SectionAddr, shdr->sh_size);
00529         FsSetFilePointer(KernelImage, shdr->sh_offset);
00530         FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr + SectionAddr);
00531     }
00532     else
00533     {
00534         /* Zero it out */
00535         printf("BSS section %d at %x\n", i, KernelAddr + SectionAddr);
00536         memset(MemLoadAddr + SectionAddr, 0,
00537            ROUND_UP(shdr->sh_size,
00538                 SWAPD(NtHeader->OptionalHeader.SectionAlignment)));
00539         }
00540     }
00541 
00542     ImageSize = SWAPD(NtHeader->OptionalHeader.SizeOfImage);
00543     printf("Total image size is %x\n", ImageSize);
00544 
00545     /* Handle relocation sections */
00546     for (i = 0; i < shnum; i++) {
00547     Elf32_Rela reloc = { };
00548     ULONG *Target32;
00549     USHORT *Target16;
00550     int numreloc, relstart, targetSection;
00551     Elf32_Sym symbol;
00552     PCHAR RelocSection, SymbolSection;
00553 
00554     shdr = ELF_SECTION(i);
00555     /* Only relocs here */
00556     if((shdr->sh_type != SHT_REL) &&
00557        (shdr->sh_type != SHT_RELA)) continue;
00558 
00559     relstart = shdr->sh_offset;
00560     relsize = shdr->sh_type == SHT_RELA ? 12 : 8;
00561     numreloc = shdr->sh_size / relsize;
00562     targetSection = shdr->sh_info;
00563 
00564     if (!ELF_SECTION(targetSection)->sh_addr) continue;
00565 
00566     RelocSection = MmHeapAlloc(shdr->sh_size);
00567     FsSetFilePointer(KernelImage, relstart);
00568     FsReadFile(KernelImage, shdr->sh_size, NULL, RelocSection);
00569 
00570     /* Get the symbol section */
00571     shdr = ELF_SECTION(shdr->sh_link);
00572 
00573     SymbolSection = MmHeapAlloc(shdr->sh_size);
00574     FsSetFilePointer(KernelImage, shdr->sh_offset);
00575     FsReadFile(KernelImage, shdr->sh_size, NULL, SymbolSection);
00576 
00577     for(j = 0; j < numreloc; j++)
00578     {
00579         ULONG S,A,P;
00580 
00581         /* Get the reloc */
00582         memcpy(&reloc, RelocSection + (j * relsize), sizeof(reloc));
00583 
00584         /* Get the symbol */
00585         memcpy(&symbol, SymbolSection + (ELF32_R_SYM(reloc.r_info) * sizeof(symbol)), sizeof(symbol));
00586 
00587         /* Compute addends */
00588         S = symbol.st_value + ELF_SECTION(symbol.st_shndx)->sh_addr;
00589         A = reloc.r_addend;
00590         P = reloc.r_offset + ELF_SECTION(targetSection)->sh_addr;
00591 
00592 #if 0
00593         printf("Symbol[%d] %d -> %d(%x:%x) -> %x(+%x)@%x\n",
00594            ELF32_R_TYPE(reloc.r_info),
00595            ELF32_R_SYM(reloc.r_info),
00596            symbol.st_shndx,
00597            ELF_SECTION(symbol.st_shndx)->sh_addr,
00598            symbol.st_value,
00599            S,
00600            A,
00601            P);
00602 #endif
00603 
00604         Target32 = (ULONG*)(((PCHAR)MemLoadAddr) + (P - KernelAddr));
00605         Target16 = (USHORT *)Target32;
00606 
00607         switch (ELF32_R_TYPE(reloc.r_info))
00608         {
00609         case R_PPC_NONE:
00610         break;
00611         case R_PPC_ADDR32:
00612         *Target32 = S + A;
00613         break;
00614         case R_PPC_REL32:
00615         *Target32 = S + A - P;
00616         break;
00617         case R_PPC_UADDR32: /* Special: Treat as RVA */
00618         *Target32 = S + A - KernelAddr;
00619         break;
00620         case R_PPC_ADDR24:
00621         *Target32 = (ADDR24_MASK & (S+A)) | (*Target32 & ~ADDR24_MASK);
00622         break;
00623         case R_PPC_REL24:
00624         *Target32 = (ADDR24_MASK & (S+A-P)) | (*Target32 & ~ADDR24_MASK);
00625         break;
00626         case R_PPC_ADDR16_LO:
00627         *Target16 = S + A;
00628         break;
00629         case R_PPC_ADDR16_HA:
00630         *Target16 = (S + A + 0x8000) >> 16;
00631         break;
00632         default:
00633         break;
00634         }
00635 
00636 #if 0
00637         printf("reloc[%d:%x]: (type %x sym %d val %d) off %x add %x (old %x new %x)\n",
00638            j,
00639            ((ULONG)Target32) - ((ULONG)MemLoadAddr),
00640            ELF32_R_TYPE(reloc.r_info),
00641            ELF32_R_SYM(reloc.r_info),
00642            symbol.st_value,
00643            reloc.r_offset, reloc.r_addend,
00644            x, *Target32);
00645 #endif
00646     }
00647 
00648     MmHeapFree(SymbolSection);
00649     MmHeapFree(RelocSection);
00650     }
00651 
00652     MmHeapFree(sptr);
00653 
00654     ModuleData->ModStart = (ULONG)MemLoadAddr;
00655     /* Increase the next Load Base */
00656     NextModuleBase = ROUND_UP((ULONG)MemLoadAddr + ImageSize, PAGE_SIZE);
00657     ModuleData->ModEnd = NextModuleBase;
00658     ModuleData->String = (ULONG)MmAllocateMemory(strlen(ImageName)+1);
00659     strcpy((PCHAR)ModuleData->String, ImageName);
00660     printf("Module %s (%x-%x) next at %x\n",
00661        ModuleData->String,
00662        ModuleData->ModStart,
00663        ModuleData->ModEnd,
00664        NextModuleBase);
00665     LoaderBlock.ModsCount++;
00666 
00667     /* Return Success */
00668     return TRUE;
00669 }
00670 
00671 /*++
00672  * FrLdrMapKernel
00673  * INTERNAL
00674  *
00675  *     Maps the Kernel into memory, does PE Section Mapping, initalizes the
00676  *     uninitialized data sections, and relocates the image.
00677  *
00678  * Params:
00679  *     KernelImage - FILE Structure representing the ntoskrnl image file.
00680  *
00681  * Returns:
00682  *     TRUE if the Kernel was mapped.
00683  *
00684  * Remarks:
00685  *     None.
00686  *
00687  *--*/
00688 BOOLEAN
00689 NTAPI
00690 FrLdrMapKernel(FILE *KernelImage)
00691 {
00692     /* Get Kernel Base */
00693     FrLdrGetKernelBase();
00694 
00695     /* Allocate kernel memory */
00696     KernelMemory = MmAllocateMemory(KernelMemorySize);
00697 
00698     return FrLdrMapModule(KernelImage, "ntoskrnl.exe", KernelMemory, KernelBase);
00699 }
00700 
00701 ULONG_PTR
00702 NTAPI
00703 FrLdrLoadModule(FILE *ModuleImage,
00704                 LPCSTR ModuleName,
00705                 PULONG ModuleSize)
00706 {
00707     ULONG LocalModuleSize;
00708     ULONG_PTR ThisModuleBase = NextModuleBase;
00709     PLOADER_MODULE ModuleData;
00710     LPSTR NameBuffer;
00711     LPSTR TempName;
00712 
00713     /* Get current module data structure and module name string array */
00714     ModuleData = &reactos_modules[LoaderBlock.ModsCount];
00715 
00716     /* Get only the Module Name */
00717     do {
00718 
00719         TempName = strchr(ModuleName, '\\');
00720 
00721         if(TempName) {
00722             ModuleName = TempName + 1;
00723         }
00724 
00725     } while(TempName);
00726     NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
00727 
00728 
00729     /* Get Module Size */
00730     LocalModuleSize = FsGetFileSize(ModuleImage);
00731 
00732     /* Fill out Module Data Structure */
00733     ModuleData->ModStart = NextModuleBase;
00734     ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
00735 
00736     /* Save name */
00737     strcpy(NameBuffer, ModuleName);
00738     ModuleData->String = (ULONG_PTR)NameBuffer;
00739 
00740     /* Load the file image */
00741     FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
00742 
00743     /* Move to next memory block and increase Module Count */
00744     NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
00745     LoaderBlock.ModsCount++;
00746 
00747     /* Return Module Size if required */
00748     if (ModuleSize != NULL) {
00749         *ModuleSize = LocalModuleSize;
00750     }
00751 
00752     printf("Module %s (%x-%x) next at %x\n",
00753        ModuleData->String,
00754        ModuleData->ModStart,
00755        ModuleData->ModEnd,
00756        NextModuleBase);
00757 
00758     return ThisModuleBase;
00759 }
00760 
00761 PVOID
00762 NTAPI
00763 FrLdrMapImage(IN FILE *Image, IN PCHAR ShortName, IN ULONG ImageType)
00764 {
00765     PVOID Result = NULL;
00766 
00767     printf("Loading image %s (type %d)\n", ShortName, ImageType);
00768 
00769     if (ImageType == 1)
00770     {
00771         if(FrLdrMapKernel(Image))
00772             Result = (PVOID)KernelMemory;
00773     }
00774     else
00775     {
00776         PVOID ModuleBase = (PVOID)NextModuleBase;
00777 
00778         if(FrLdrMapModule(Image, ShortName, 0, 0))
00779             Result = ModuleBase;
00780     }
00781     return Result;
00782 }
00783 
00784 ULONG_PTR
00785 NTAPI
00786 FrLdrCreateModule(LPCSTR ModuleName)
00787 {
00788     PLOADER_MODULE ModuleData;
00789     LPSTR NameBuffer;
00790 
00791     /* Get current module data structure and module name string array */
00792     ModuleData = &reactos_modules[LoaderBlock.ModsCount];
00793     NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
00794 
00795     /* Set up the structure */
00796     ModuleData->ModStart = NextModuleBase;
00797     ModuleData->ModEnd = -1;
00798 
00799     /* Copy the name */
00800     strcpy(NameBuffer, ModuleName);
00801     ModuleData->String = (ULONG_PTR)NameBuffer;
00802 
00803     /* Set the current Module */
00804     CurrentModule = ModuleData;
00805 
00806     /* Return Module Base Address */
00807     return(ModuleData->ModStart);
00808 }
00809 
00810 BOOLEAN
00811 NTAPI
00812 FrLdrCloseModule(ULONG_PTR ModuleBase,
00813                  ULONG ModuleSize)
00814 {
00815     PLOADER_MODULE ModuleData = CurrentModule;
00816 
00817     /* Make sure a module is opened */
00818     if (ModuleData) {
00819 
00820         /* Make sure this is the right module and that it hasn't been closed */
00821         if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == MAXULONG_PTR)) {
00822 
00823             /* Close the Module */
00824             ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
00825 
00826             /* Set the next Module Base and increase the number of modules */
00827             NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
00828             LoaderBlock.ModsCount++;
00829 
00830             /* Close the currently opened module */
00831             CurrentModule = NULL;
00832 
00833             /* Success */
00834             return(TRUE);
00835         }
00836     }
00837 
00838     /* Failure path */
00839     return(FALSE);
00840 }

Generated on Sat May 26 2012 04:17:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.