PowerPC support drop in freeldr, from my branch.
[reactos.git] / reactos / boot / freeldr / freeldr / arch / powerpc / mboot.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Freeloader
4 * FILE: boot/freeldr/freeldr/multiboot.c
5 * PURPOSE: ReactOS Loader
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Hartmut Birr - SMP/PAE Code
8 */
9
10 #include <freeldr.h>
11 #include <internal/powerpc/ke.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* Base Addres of Kernel in Physical Memory */
17 #define KERNEL_BASE_PHYS 0x200000
18
19 /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
20 #define PFN_SHIFT 12
21
22 /* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */
23 #define PDE_SHIFT 20
24 #define PDE_SHIFT_PAE 18
25
26
27 /* Converts a Relative Address read from the Kernel into a Physical Address */
28 #define RaToPa(p) \
29 (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS)
30
31 /* Converts a Phsyical Address Pointer into a Page Frame Number */
32 #define PaPtrToPfn(p) \
33 (((ULONG_PTR)&p) >> PFN_SHIFT)
34
35 /* Converts a Phsyical Address into a Page Frame Number */
36 #define PaToPfn(p) \
37 ((p) >> PFN_SHIFT)
38
39 #define STARTUP_BASE 0xF0000000
40 #define HYPERSPACE_BASE 0xF0800000
41 #define APIC_BASE 0xFEC00000
42 #define KPCR_BASE 0xFF000000
43
44 #define LowMemPageTableIndex 0
45 #define StartupPageTableIndex (STARTUP_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
46 #define HyperspacePageTableIndex (HYPERSPACE_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
47 #define KpcrPageTableIndex (KPCR_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
48 #define ApicPageTableIndex (APIC_BASE >> 20) / sizeof(HARDWARE_PTE_X86)
49
50 #define LowMemPageTableIndexPae 0
51 #define StartupPageTableIndexPae (STARTUP_BASE >> 21)
52 #define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21)
53 #define KpcrPageTableIndexPae (KPCR_BASE >> 21)
54 #define ApicPageTableIndexPae (APIC_BASE >> 21)
55
56
57 #define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase
58
59 /* Load Address of Next Module */
60 ULONG_PTR NextModuleBase = 0;
61
62 /* Currently Opened Module */
63 PFRLDR_MODULE CurrentModule = NULL;
64
65 /* Unrelocated Kernel Base in Virtual Memory */
66 ULONG_PTR KernelBase;
67
68 /* Wether PAE is to be used or not */
69 BOOLEAN PaeModeEnabled;
70
71 /* Kernel Entrypoint in Physical Memory */
72 ULONG_PTR KernelEntry;
73
74 /* FUNCTIONS *****************************************************************/
75
76 /*++
77 * FrLdrStartup
78 * INTERNAL
79 *
80 * Prepares the system for loading the Kernel.
81 *
82 * Params:
83 * Magic - Multiboot Magic
84 *
85 * Returns:
86 * None.
87 *
88 * Remarks:
89 * None.
90 *
91 *--*/
92 VOID
93 STDCALL
94 FrLdrStartup(ULONG Magic)
95 {
96 #if 0
97 /* Disable Interrupts */
98 KeArchDisableInterrupts();
99
100 /* Re-initalize EFLAGS */
101 KeArchEraseFlags();
102
103 /* Initialize the page directory */
104 FrLdrSetupPageDirectory();
105 #endif
106 }
107
108 /*++
109 * FrLdrGetKernelBase
110 * INTERNAL
111 *
112 * Gets the Kernel Base to use.
113 *
114 * Params:
115 *
116 * Returns:
117 * None.
118 *
119 * Remarks:
120 * Sets both the FreeLdr internal variable as well as the one which
121 * will be used by the Kernel.
122 *
123 *--*/
124 VOID
125 FASTCALL
126 FrLdrGetKernelBase(VOID)
127 {
128 PCHAR p;
129
130 /* Read Command Line */
131 p = (PCHAR)LoaderBlock.CommandLine;
132 while ((p = strchr(p, '/')) != NULL) {
133
134 /* Find "/3GB" */
135 if (!strnicmp(p + 1, "3GB", 3)) {
136
137 /* Make sure there's nothing following it */
138 if (p[4] == ' ' || p[4] == 0) {
139
140 /* Use 3GB */
141 KernelBase = 0xC0000000;
142 }
143 }
144
145 p++;
146 }
147
148 /* Set KernelBase */
149 LoaderBlock.KernelBase = KernelBase;
150 }
151
152 /*++
153 * FrLdrSetupPageDirectory
154 * INTERNAL
155 *
156 * Sets up the ReactOS Startup Page Directory.
157 *
158 * Params:
159 * None.
160 *
161 * Returns:
162 * None.
163 *
164 * Remarks:
165 * We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
166 * As such, please note that PageFrameNumber == PageEntryNumber.
167 *
168 *--*/
169 VOID
170 FASTCALL
171 FrLdrSetupPageDirectory(VOID)
172 {
173 #if 0
174 PPAGE_DIRECTORY_X86 PageDir;
175 PPAGE_DIRECTORY_TABLE_X64 PageDirTablePae;
176 PPAGE_DIRECTORY_X64 PageDirPae;
177 ULONG KernelPageTableIndex;
178 ULONG i;
179
180 if (PaeModeEnabled) {
181
182 /* Get the Kernel Table Index */
183 KernelPageTableIndex = (KernelBase >> 21);
184
185 /* Get the Startup Page Directory Table */
186 PageDirTablePae = (PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae;
187
188 /* Get the Startup Page Directory */
189 PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae;
190
191 /* Set the Startup page directory table */
192 for (i = 0; i < 4; i++)
193 {
194 PageDirTablePae->Pde[i].Valid = 1;
195 PageDirTablePae->Pde[i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
196 }
197
198 /* Set up the Low Memory PDE */
199 for (i = 0; i < 2; i++)
200 {
201 PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1;
202 PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1;
203 PageDirPae->Pde[LowMemPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i;
204 }
205
206 /* Set up the Kernel PDEs */
207 for (i = 0; i < 3; i++)
208 {
209 PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1;
210 PageDirPae->Pde[KernelPageTableIndex + i].Write = 1;
211 PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber = PaPtrToPfn(kernel_pagetable_pae) + i;
212 }
213
214 /* Set up the Startup PDE */
215 for (i = 0; i < 4; i++)
216 {
217 PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1;
218 PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1;
219 PageDirPae->Pde[StartupPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
220 }
221
222 /* Set up the Hyperspace PDE */
223 for (i = 0; i < 2; i++)
224 {
225 PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1;
226 PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1;
227 PageDirPae->Pde[HyperspacePageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i;
228 }
229
230 /* Set up the Apic PDE */
231 for (i = 0; i < 2; i++)
232 {
233 PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1;
234 PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1;
235 PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(apic_pagetable_pae) + i;
236 }
237
238 /* Set up the KPCR PDE */
239 PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1;
240 PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1;
241 PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber = PaPtrToPfn(kpcr_pagetable_pae);
242
243 /* Set up Low Memory PTEs */
244 PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae;
245 for (i=0; i<1024; i++) {
246
247 PageDirPae->Pde[i].Valid = 1;
248 PageDirPae->Pde[i].Write = 1;
249 PageDirPae->Pde[i].Owner = 1;
250 PageDirPae->Pde[i].PageFrameNumber = i;
251 }
252
253 /* Set up Kernel PTEs */
254 PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae;
255 for (i=0; i<1536; i++) {
256
257 PageDirPae->Pde[i].Valid = 1;
258 PageDirPae->Pde[i].Write = 1;
259 PageDirPae->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS) + i;
260 }
261
262 /* Set up APIC PTEs */
263 PageDirPae = (PPAGE_DIRECTORY_X64)&apic_pagetable_pae;
264 PageDirPae->Pde[0].Valid = 1;
265 PageDirPae->Pde[0].Write = 1;
266 PageDirPae->Pde[0].CacheDisable = 1;
267 PageDirPae->Pde[0].WriteThrough = 1;
268 PageDirPae->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
269 PageDirPae->Pde[0x200].Valid = 1;
270 PageDirPae->Pde[0x200].Write = 1;
271 PageDirPae->Pde[0x200].CacheDisable = 1;
272 PageDirPae->Pde[0x200].WriteThrough = 1;
273 PageDirPae->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
274
275 /* Set up KPCR PTEs */
276 PageDirPae = (PPAGE_DIRECTORY_X64)&kpcr_pagetable_pae;
277 PageDirPae->Pde[0].Valid = 1;
278 PageDirPae->Pde[0].Write = 1;
279 PageDirPae->Pde[0].PageFrameNumber = 1;
280
281 } else {
282
283 /* Get the Kernel Table Index */
284 KernelPageTableIndex = (KernelBase >> PDE_SHIFT) / sizeof(HARDWARE_PTE_X86);
285
286 /* Get the Startup Page Directory */
287 PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
288
289 /* Set up the Low Memory PDE */
290 PageDir->Pde[LowMemPageTableIndex].Valid = 1;
291 PageDir->Pde[LowMemPageTableIndex].Write = 1;
292 PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
293
294 /* Set up the Kernel PDEs */
295 PageDir->Pde[KernelPageTableIndex].Valid = 1;
296 PageDir->Pde[KernelPageTableIndex].Write = 1;
297 PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
298 PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
299 PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
300 PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
301
302 /* Set up the Startup PDE */
303 PageDir->Pde[StartupPageTableIndex].Valid = 1;
304 PageDir->Pde[StartupPageTableIndex].Write = 1;
305 PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
306
307 /* Set up the Hyperspace PDE */
308 PageDir->Pde[HyperspacePageTableIndex].Valid = 1;
309 PageDir->Pde[HyperspacePageTableIndex].Write = 1;
310 PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable);
311
312 /* Set up the Apic PDE */
313 PageDir->Pde[ApicPageTableIndex].Valid = 1;
314 PageDir->Pde[ApicPageTableIndex].Write = 1;
315 PageDir->Pde[ApicPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
316
317 /* Set up the KPCR PDE */
318 PageDir->Pde[KpcrPageTableIndex].Valid = 1;
319 PageDir->Pde[KpcrPageTableIndex].Write = 1;
320 PageDir->Pde[KpcrPageTableIndex].PageFrameNumber = PaPtrToPfn(kpcr_pagetable);
321
322 /* Set up Low Memory PTEs */
323 PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
324 for (i=0; i<1024; i++) {
325
326 PageDir->Pde[i].Valid = 1;
327 PageDir->Pde[i].Write = 1;
328 PageDir->Pde[i].Owner = 1;
329 PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
330 }
331
332 /* Set up Kernel PTEs */
333 PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
334 for (i=0; i<1536; i++) {
335
336 PageDir->Pde[i].Valid = 1;
337 PageDir->Pde[i].Write = 1;
338 PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
339 }
340
341 /* Set up APIC PTEs */
342 PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
343 PageDir->Pde[0].Valid = 1;
344 PageDir->Pde[0].Write = 1;
345 PageDir->Pde[0].CacheDisable = 1;
346 PageDir->Pde[0].WriteThrough = 1;
347 PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
348 PageDir->Pde[0x200].Valid = 1;
349 PageDir->Pde[0x200].Write = 1;
350 PageDir->Pde[0x200].CacheDisable = 1;
351 PageDir->Pde[0x200].WriteThrough = 1;
352 PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
353
354 /* Set up KPCR PTEs */
355 PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable;
356 PageDir->Pde[0].Valid = 1;
357 PageDir->Pde[0].Write = 1;
358 PageDir->Pde[0].PageFrameNumber = 1;
359 }
360 return;
361 #endif
362 }
363
364 /*++
365 * FrLdrMapKernel
366 * INTERNAL
367 *
368 * Maps the Kernel into memory, does PE Section Mapping, initalizes the
369 * uninitialized data sections, and relocates the image.
370 *
371 * Params:
372 * KernelImage - FILE Structure representing the ntoskrnl image file.
373 *
374 * Returns:
375 * TRUE if the Kernel was mapped.
376 *
377 * Remarks:
378 * None.
379 *
380 *--*/
381 BOOL
382 STDCALL
383 FrLdrMapKernel(FILE *KernelImage)
384 {
385 #if 0
386 PIMAGE_DOS_HEADER ImageHeader;
387 PIMAGE_NT_HEADERS NtHeader;
388 PIMAGE_SECTION_HEADER Section;
389 ULONG SectionCount;
390 ULONG ImageSize;
391 ULONG_PTR SourceSection;
392 ULONG_PTR TargetSection;
393 ULONG SectionSize;
394 LONG i;
395 PIMAGE_DATA_DIRECTORY RelocationDDir;
396 PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
397 ULONG Count;
398 ULONG_PTR Address, MaxAddress;
399 PUSHORT TypeOffset;
400 ULONG_PTR Delta;
401 PUSHORT ShortPtr;
402 PULONG LongPtr;
403
404 /* Allocate 1024 bytes for PE Header */
405 ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
406
407 /* Make sure it was succesful */
408 if (ImageHeader == NULL) {
409
410 return FALSE;
411 }
412
413 /* Load the first 1024 bytes of the kernel image so we can read the PE header */
414 if (!FsReadFile(KernelImage, 1024, NULL, ImageHeader)) {
415
416 /* Fail if we couldn't read */
417 MmFreeMemory(ImageHeader);
418 return FALSE;
419 }
420
421 /* Now read the MZ header to get the offset to the PE Header */
422 NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
423
424 /* Get Kernel Base */
425 KernelBase = NtHeader->OptionalHeader.ImageBase;
426 FrLdrGetKernelBase();
427
428 /* Save Entrypoint */
429 KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
430
431 /* Save the Image Size */
432 ImageSize = NtHeader->OptionalHeader.SizeOfImage;
433
434 /* Free the Header */
435 MmFreeMemory(ImageHeader);
436
437 /* Set the file pointer to zero */
438 FsSetFilePointer(KernelImage, 0);
439
440 /* Load the file image */
441 FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS);
442
443 /* Reload the NT Header */
444 NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew);
445
446 /* Load the first section */
447 Section = IMAGE_FIRST_SECTION(NtHeader);
448 SectionCount = NtHeader->FileHeader.NumberOfSections - 1;
449
450 /* Now go to the last section */
451 Section += SectionCount;
452
453 /* Walk each section backwards */
454 for (i=SectionCount; i >= 0; i--, Section--) {
455
456 /* Get the disk location and the memory location, and the size */
457 SourceSection = RaToPa(Section->PointerToRawData);
458 TargetSection = RaToPa(Section->VirtualAddress);
459 SectionSize = Section->SizeOfRawData;
460
461 /* If the section is already mapped correctly, go to the next */
462 if (SourceSection == TargetSection) continue;
463
464 /* Load it into memory */
465 memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize);
466
467 /* Check for unitilizated data */
468 if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
469
470 /* Zero it out */
471 memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData),
472 0,
473 Section->Misc.VirtualSize - Section->SizeOfRawData);
474 }
475 }
476
477 /* Get the Relocation Data Directory */
478 RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
479
480 /* Get the Relocation Section Start and End*/
481 RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
482 RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
483
484 /* Calculate Difference between Real Base and Compiled Base*/
485 Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
486
487 /* Determine how far we shoudl relocate */
488 MaxAddress = KERNEL_BASE_PHYS + ImageSize;
489
490 /* Relocate until we've processed all the blocks */
491 while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
492
493 /* See how many Relocation Blocks we have */
494 Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
495
496 /* Calculate the Address of this Directory */
497 Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
498
499 /* Calculate the Offset of the Type */
500 TypeOffset = (PUSHORT)(RelocationDir + 1);
501
502 for (i = 0; i < Count; i++) {
503
504 ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
505
506 /* Don't relocate after the end of the loaded driver */
507 if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
508
509 switch (*TypeOffset >> 12) {
510
511 case IMAGE_REL_BASED_ABSOLUTE:
512 break;
513
514 case IMAGE_REL_BASED_HIGH:
515 *ShortPtr += HIWORD(Delta);
516 break;
517
518 case IMAGE_REL_BASED_LOW:
519 *ShortPtr += LOWORD(Delta);
520 break;
521
522 case IMAGE_REL_BASED_HIGHLOW:
523 LongPtr = (PULONG)ShortPtr;
524 *LongPtr += Delta;
525 break;
526 }
527
528 TypeOffset++;
529 }
530
531 /* Move to the next Relocation Table */
532 RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
533 }
534
535 /* Increase the next Load Base */
536 NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
537
538 /* Return Success */
539 #endif
540 return TRUE;
541 }
542
543 ULONG_PTR
544 STDCALL
545 FrLdrLoadModule(FILE *ModuleImage,
546 LPSTR ModuleName,
547 PULONG ModuleSize)
548 {
549 #if 0
550 ULONG LocalModuleSize;
551 PFRLDR_MODULE ModuleData;
552 LPSTR NameBuffer;
553 LPSTR TempName;
554
555 /* Get current module data structure and module name string array */
556 ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
557
558 /* Get only the Module Name */
559 do {
560
561 TempName = strchr(ModuleName, '\\');
562
563 if(TempName) {
564 ModuleName = TempName + 1;
565 }
566
567 } while(TempName);
568 NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
569
570 /* Get Module Size */
571 LocalModuleSize = FsGetFileSize(ModuleImage);
572
573 /* Fill out Module Data Structure */
574 ModuleData->ModuleStart = NextModuleBase;
575 ModuleData->ModuleEnd = NextModuleBase + LocalModuleSize;
576
577 /* Save name */
578 strcpy(NameBuffer, ModuleName);
579 ModuleData->ModuleName = NameBuffer;
580
581 /* Load the file image */
582 FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
583
584 /* Move to next memory block and increase Module Count */
585 NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
586 LoaderBlock.ModsCount++;
587
588 /* Return Module Size if required */
589 if (ModuleSize != NULL) {
590 *ModuleSize = LocalModuleSize;
591 }
592
593 return(ModuleData->ModuleStart);
594 #else
595 return 0;
596 #endif
597 }
598
599 ULONG_PTR
600 STDCALL
601 FrLdrCreateModule(LPSTR ModuleName)
602 {
603 #if 0
604 PFRLDR_MODULE ModuleData;
605 LPSTR NameBuffer;
606
607 /* Get current module data structure and module name string array */
608 ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
609 NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
610
611 /* Set up the structure */
612 ModuleData->ModuleStart = NextModuleBase;
613 ModuleData->ModuleEnd = -1;
614
615 /* Copy the name */
616 strcpy(NameBuffer, ModuleName);
617 ModuleData->ModuleName = NameBuffer;
618
619 /* Set the current Module */
620 CurrentModule = ModuleData;
621
622 /* Return Module Base Address */
623 return(ModuleData->ModuleStart);
624 #else
625 return 0;
626 #endif
627 }
628
629 BOOL
630 STDCALL
631 FrLdrCloseModule(ULONG_PTR ModuleBase,
632 ULONG ModuleSize)
633 {
634 #if 0
635 PFRLDR_MODULE ModuleData = CurrentModule;
636
637 /* Make sure a module is opened */
638 if (ModuleData) {
639
640 /* Make sure this is the right module and that it hasn't been closed */
641 if ((ModuleBase == ModuleData->ModuleStart) && (ModuleData->ModuleEnd == -1)) {
642
643 /* Close the Module */
644 ModuleData->ModuleEnd = ModuleData->ModuleStart + ModuleSize;
645
646 /* Set the next Module Base and increase the number of modules */
647 NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
648 LoaderBlock.ModsCount++;
649
650 /* Close the currently opened module */
651 CurrentModule = NULL;
652
653 /* Success */
654 return(TRUE);
655 }
656 }
657
658 /* Failure path */
659 #endif
660 return(FALSE);
661 }