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