2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/freeldr.c
5 * PURPOSE: FreeLDR Bootstrap Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES *****************************************************************/
16 #include <ppcmmu/mmu.h>
19 typedef struct _BIOS_MEMORY_DESCRIPTOR
23 } BIOS_MEMORY_DESCRIPTOR
, *PBIOS_MEMORY_DESCRIPTOR
;
25 /* GLOBALS *******************************************************************/
27 /* FreeLDR Memory Data */
28 ULONG_PTR MmFreeLdrFirstKrnlPhysAddr
, MmFreeLdrLastKrnlPhysAddr
;
29 ULONG_PTR MmFreeLdrLastKernelAddress
;
30 ULONG MmFreeLdrMemHigher
;
31 ULONG MmFreeLdrPageDirectoryEnd
;
33 /* FreeLDR Loader Data */
34 PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock
;
35 BOOLEAN AcpiTableDetected
;
36 ADDRESS_RANGE KeMemoryMap
[64];
37 ULONG KeMemoryMapRangeCount
;
39 /* NT Loader Module/Descriptor Count */
43 /* NT Loader Data. Eats up about 100KB! */
44 LOADER_PARAMETER_BLOCK BldrLoaderBlock
; // 0x0000
45 LOADER_PARAMETER_EXTENSION BldrExtensionBlock
; // 0x0060
46 CHAR BldrCommandLine
[256]; // 0x00DC
47 CHAR BldrArcBootPath
[64]; // 0x01DC
48 CHAR BldrArcHalPath
[64]; // 0x021C
49 CHAR BldrNtHalPath
[64]; // 0x025C
50 CHAR BldrNtBootPath
[64]; // 0x029C
51 LDR_DATA_TABLE_ENTRY BldrModules
[64]; // 0x02DC
52 MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors
[60]; // 0x14DC
53 WCHAR BldrModuleStrings
[64][260]; // 0x19DC
54 WCHAR BldrModuleStringsFull
[64][260]; // 0x9BDC
55 NLS_DATA_BLOCK BldrNlsDataBlock
; // 0x11DDC
56 SETUP_LOADER_BLOCK BldrSetupBlock
; // 0x11DE8
57 ARC_DISK_INFORMATION BldrArcDiskInfo
; // 0x12134
58 CHAR BldrArcNames
[32][256]; // 0x1213C
59 ARC_DISK_SIGNATURE BldrDiskInfo
[32]; // 0x1413C
60 CHAR BldrArcHwBuffer
[16 * 1024]; // 0x1843C
63 BIOS_MEMORY_DESCRIPTOR BiosMemoryDescriptors
[16] = {{0}};
64 PBIOS_MEMORY_DESCRIPTOR BiosMemoryDescriptorList
= BiosMemoryDescriptors
;
67 ULONG NumberDescriptors
= 0;
68 MEMORY_DESCRIPTOR MDArray
[60] = {{0}};
70 /* FUNCTIONS *****************************************************************/
72 PMEMORY_ALLOCATION_DESCRIPTOR
74 KiRosGetMdFromArray(VOID
)
76 /* Return the next MD from the list, but make sure we don't overflow */
77 if (BldrCurrentMd
> 60) KEBUGCHECK(0);
78 return &BldrMemoryDescriptors
[BldrCurrentMd
++];
83 KiRosAddBiosBlock(ULONG Address
,
86 PBIOS_MEMORY_DESCRIPTOR BiosBlock
= BiosMemoryDescriptorList
;
88 /* Loop our BIOS Memory Descriptor List */
89 while (BiosBlock
->BlockSize
> 0)
91 /* Check if we've found a matching head block */
92 if (Address
+ Size
== BiosBlock
->BlockBase
)
94 /* Simply enlarge and rebase it */
95 BiosBlock
->BlockBase
= Address
;
96 BiosBlock
->BlockSize
+= Size
;
100 /* Check if we've found a matching tail block */
101 if (Address
== (BiosBlock
->BlockBase
+ BiosBlock
->BlockSize
))
103 /* Simply enlarge it */
104 BiosBlock
->BlockSize
+= Size
;
108 /* Nothing suitable found, try the next block */
112 /* No usable blocks found, found a free block instead */
113 if (!BiosBlock
->BlockSize
)
116 BiosBlock
->BlockBase
= Address
;
117 BiosBlock
->BlockSize
= Size
;
119 /* Create a new block and mark it as the end of the array */
121 BiosBlock
->BlockBase
= BiosBlock
->BlockSize
= 0L;
127 KiRosBuildBiosMemoryMap(VOID
)
130 ULONG BlockBegin
, BlockEnd
;
132 /* Loop the BIOS Memory Map */
133 for (j
= 0; j
< KeMemoryMapRangeCount
; j
++)
135 /* Get the start and end addresses */
136 BlockBegin
= KeMemoryMap
[j
].BaseAddrLow
;
137 BlockEnd
= KeMemoryMap
[j
].BaseAddrLow
+ KeMemoryMap
[j
].LengthLow
- 1;
139 /* Make sure this isn't a > 4GB descriptor */
140 if (!KeMemoryMap
[j
].BaseAddrHigh
)
142 /* Make sure we don't overflow */
143 if (BlockEnd
< BlockBegin
) BlockEnd
= 0xFFFFFFFF;
145 /* Check if this is free memory */
146 if (KeMemoryMap
[j
].Type
== 1)
148 /* Add it to our BIOS descriptors */
149 KiRosAddBiosBlock(BlockBegin
, BlockEnd
- BlockBegin
+ 1);
157 KiRosAllocateArcDescriptor(IN ULONG PageBegin
,
159 IN MEMORY_TYPE MemoryType
)
163 /* Loop all our descriptors */
164 for (i
= 0; i
< NumberDescriptors
; i
++)
166 /* Attempt to fing a free block that describes our region */
167 if ((MDArray
[i
].MemoryType
== MemoryFree
) &&
168 (MDArray
[i
].BasePage
<= PageBegin
) &&
169 (MDArray
[i
].BasePage
+ MDArray
[i
].PageCount
> PageBegin
) &&
170 (MDArray
[i
].BasePage
+ MDArray
[i
].PageCount
>= PageEnd
))
177 /* Check if we found no free blocks, and fail if so */
178 if (i
== NumberDescriptors
) return ENOMEM
;
180 /* Check if the block has our base address */
181 if (MDArray
[i
].BasePage
== PageBegin
)
183 /* Check if it also has our ending address */
184 if ((MDArray
[i
].BasePage
+ MDArray
[i
].PageCount
) == PageEnd
)
186 /* Then convert this region into our new memory type */
187 MDArray
[i
].MemoryType
= MemoryType
;
191 /* Otherwise, make sure we have enough descriptors */
192 if (NumberDescriptors
== 60) return ENOMEM
;
194 /* Cut this descriptor short */
195 MDArray
[i
].BasePage
= PageEnd
;
196 MDArray
[i
].PageCount
-= (PageEnd
- PageBegin
);
198 /* And allocate a new descriptor for our memory range */
199 MDArray
[NumberDescriptors
].BasePage
= PageBegin
;
200 MDArray
[NumberDescriptors
].PageCount
= PageEnd
- PageBegin
;
201 MDArray
[NumberDescriptors
].MemoryType
= MemoryType
;
205 else if ((MDArray
[i
].BasePage
+ MDArray
[i
].PageCount
) == PageEnd
)
207 /* This block has our end address, make sure we have a free block */
208 if (NumberDescriptors
== 60) return ENOMEM
;
210 /* Rebase this descriptor */
211 MDArray
[i
].PageCount
= PageBegin
- MDArray
[i
].BasePage
;
213 /* And allocate a new descriptor for our memory range */
214 MDArray
[NumberDescriptors
].BasePage
= PageBegin
;
215 MDArray
[NumberDescriptors
].PageCount
= PageEnd
- PageBegin
;
216 MDArray
[NumberDescriptors
].MemoryType
= MemoryType
;
221 /* We'll need two descriptors, make sure they're available */
222 if ((NumberDescriptors
+ 1) >= 60) return ENOMEM
;
224 /* Allocate a free memory descriptor for what follows us */
225 MDArray
[NumberDescriptors
].BasePage
= PageEnd
;
226 MDArray
[NumberDescriptors
].PageCount
= MDArray
[i
].PageCount
-
227 (PageEnd
- MDArray
[i
].BasePage
);
228 MDArray
[NumberDescriptors
].MemoryType
= MemoryFree
;
231 /* Cut down the current free descriptor */
232 MDArray
[i
].PageCount
= PageBegin
- MDArray
[i
].BasePage
;
234 /* Allocate a new memory descriptor for our memory range */
235 MDArray
[NumberDescriptors
].BasePage
= PageBegin
;
236 MDArray
[NumberDescriptors
].PageCount
= PageEnd
- PageBegin
;
237 MDArray
[NumberDescriptors
].MemoryType
= MemoryType
;
241 /* Everything went well */
242 return STATUS_SUCCESS
;
247 KiRosConfigureArcDescriptor(IN ULONG PageBegin
,
249 IN TYPE_OF_MEMORY MemoryType
)
252 ULONG BlockBegin
, BlockEnd
;
253 MEMORY_TYPE BlockType
;
254 BOOLEAN Combined
= FALSE
;
256 /* If this descriptor seems bogus, just return */
257 if (PageEnd
<= PageBegin
) return STATUS_SUCCESS
;
259 /* Loop every ARC descriptor, trying to find one we can modify */
260 for (i
= 0; i
< NumberDescriptors
; i
++)
262 /* Get its settings */
263 BlockBegin
= MDArray
[i
].BasePage
;
264 BlockEnd
= MDArray
[i
].BasePage
+ MDArray
[i
].PageCount
;
265 BlockType
= MDArray
[i
].MemoryType
;
267 /* Check if we can fit inside this block */
268 if (BlockBegin
< PageBegin
)
270 /* Check if we are larger then it */
271 if ((BlockEnd
> PageBegin
) && (BlockEnd
<= PageEnd
))
273 /* Make it end where we start */
274 BlockEnd
= PageBegin
;
277 /* Check if it ends after we do */
278 if (BlockEnd
> PageEnd
)
280 /* Make sure we can allocate a descriptor */
281 if (NumberDescriptors
== 60) return ENOMEM
;
283 /* Create a descriptor for whatever memory we're not part of */
284 MDArray
[NumberDescriptors
].MemoryType
= BlockType
;
285 MDArray
[NumberDescriptors
].BasePage
= PageEnd
;
286 MDArray
[NumberDescriptors
].PageCount
= BlockEnd
- PageEnd
;
289 /* The next block ending is now where we begin */
290 BlockEnd
= PageBegin
;
295 /* Check if the blog begins inside our range */
296 if (BlockBegin
< PageEnd
)
298 /* Check if it ends before we do */
299 if (BlockEnd
< PageEnd
)
301 /* Then make it disappear */
302 BlockEnd
= BlockBegin
;
306 /* Otherwise make it start where we end */
307 BlockBegin
= PageEnd
;
312 /* Check if the block matches us, and we haven't tried combining yet */
313 if ((BlockType
== MemoryType
) && !(Combined
))
315 /* Check if it starts where we end */
316 if (BlockBegin
== PageEnd
)
318 /* Make it start with us, and combine us */
319 BlockBegin
= PageBegin
;
322 else if (BlockEnd
== PageBegin
)
324 /* Otherwise, it ends where we begin, combine its ending */
330 /* Check the original block data matches with what we came up with */
331 if ((MDArray
[i
].BasePage
== BlockBegin
) &&
332 (MDArray
[i
].PageCount
== BlockEnd
- BlockBegin
))
338 /* Otherwise, set our new settings for this block */
339 MDArray
[i
].BasePage
= BlockBegin
;
340 MDArray
[i
].PageCount
= BlockEnd
- BlockBegin
;
342 /* Check if we are killing the block */
343 if (BlockBegin
== BlockEnd
)
345 /* Delete this block and restart the loop properly */
347 if (i
< NumberDescriptors
) MDArray
[i
] = MDArray
[NumberDescriptors
];
352 /* If we got here without combining, we need to allocate a new block */
353 if (!(Combined
) && (MemoryType
< LoaderMaximum
))
355 /* Make sure there's enough descriptors */
356 if (NumberDescriptors
== 60) return ENOMEM
;
358 /* Allocate a new block with our data */
359 MDArray
[NumberDescriptors
].MemoryType
= MemoryType
;
360 MDArray
[NumberDescriptors
].BasePage
= PageBegin
;
361 MDArray
[NumberDescriptors
].PageCount
= PageEnd
- PageBegin
;
365 /* Changes complete, return success */
366 return STATUS_SUCCESS
;
371 KiRosBuildOsMemoryMap(VOID
)
373 PBIOS_MEMORY_DESCRIPTOR MdBlock
;
374 ULONG BlockStart
, BlockEnd
, BiasedStart
, BiasedEnd
, PageStart
, PageEnd
;
375 NTSTATUS Status
= STATUS_SUCCESS
;
376 ULONG BiosPage
= 0xA0;
378 /* Loop the BIOS Memory Descriptor List */
379 MdBlock
= BiosMemoryDescriptorList
;
380 while (MdBlock
->BlockSize
)
382 /* Get the statrt and end addresses */
383 BlockStart
= MdBlock
->BlockBase
;
384 BlockEnd
= BlockStart
+ MdBlock
->BlockSize
- 1;
386 /* Align them to page boundaries */
387 BiasedStart
= BlockStart
& (PAGE_SIZE
- 1);
388 if (BiasedStart
) BlockStart
= BlockStart
+ PAGE_SIZE
- BiasedStart
;
389 BiasedEnd
= (BlockEnd
+ 1) & (ULONG
)(PAGE_SIZE
- 1);
390 if (BiasedEnd
) BlockEnd
-= BiasedEnd
;
392 /* Get the actual page numbers */
393 PageStart
= BlockStart
>> PAGE_SHIFT
;
394 PageEnd
= (BlockEnd
+ 1) >> PAGE_SHIFT
;
396 /* If we're starting at page 0, then put the BIOS page at the end */
397 if (!PageStart
) BiosPage
= PageEnd
;
399 /* Check if we did any alignment */
402 /* Mark that region as reserved */
403 Status
= KiRosConfigureArcDescriptor(PageStart
- 1,
405 MemorySpecialMemory
);
406 if (Status
!= STATUS_SUCCESS
) break;
409 /* Check if we did any alignment */
412 /* Mark that region as reserved */
413 Status
= KiRosConfigureArcDescriptor(PageEnd
- 1,
415 MemorySpecialMemory
);
416 if (Status
!= STATUS_SUCCESS
) break;
418 /* If the bios page was the last page, use the next one instead */
419 if (BiosPage
== PageEnd
) BiosPage
+= 1;
422 /* Check if the page is below the 16MB Memory hole */
423 if (PageEnd
<= 0xFC0)
425 /* It is, mark the memory a free */
426 Status
= KiRosConfigureArcDescriptor(PageStart
,
430 else if (PageStart
>= 0x1000)
432 /* It's over 16MB, so that memory gets marked as reserve */
433 Status
= KiRosConfigureArcDescriptor(PageStart
,
439 /* Check if it starts below the memory hole */
440 if (PageStart
< 0xFC0)
442 /* Mark that part as free */
443 Status
= KiRosConfigureArcDescriptor(PageStart
,
446 if (Status
!= STATUS_SUCCESS
) break;
448 /* And update the page start for the code below */
452 /* Any code in the memory hole region ends up as reserve */
453 Status
= KiRosConfigureArcDescriptor(PageStart
,
458 /* If we failed, break out, otherwise, go to the next BIOS block */
459 if (Status
!= STATUS_SUCCESS
) break;
463 /* If anything failed until now, return error code */
464 if (Status
!= STATUS_SUCCESS
) return Status
;
467 /* Set the top 16MB region as reserved */
468 Status
= KiRosConfigureArcDescriptor(0xFC0, 0x1000, MemorySpecialMemory
);
469 if (Status
!= STATUS_SUCCESS
) return Status
;
471 /* Setup the BIOS region as reserved */
472 KiRosConfigureArcDescriptor(0xA0, 0x100, LoaderMaximum
);
473 KiRosConfigureArcDescriptor(BiosPage
, 0x100, MemoryFirmwarePermanent
);
475 /* Build an entry for the IVT */
476 Status
= KiRosAllocateArcDescriptor(0, 1, MemoryFirmwarePermanent
);
477 if (Status
!= STATUS_SUCCESS
) return Status
;
480 /* Build an entry for the KPCR and KUSER_SHARED_DATA */
481 Status
= KiRosAllocateArcDescriptor(1, 3, LoaderMemoryData
);
482 if (Status
!= STATUS_SUCCESS
) return Status
;
484 /* Build an entry for the PDE and return the status */
485 Status
= KiRosAllocateArcDescriptor(KeRosLoaderBlock
->
486 PageDirectoryStart
>> PAGE_SHIFT
,
488 PageDirectoryEnd
>> PAGE_SHIFT
,
495 KiRosBuildReservedMemoryMap(VOID
)
498 ULONG BlockBegin
, BlockEnd
, BiasedPage
;
500 /* Loop the BIOS Memory Map */
501 for (j
= 0; j
< KeMemoryMapRangeCount
; j
++)
503 /* Get the start and end addresses */
504 BlockBegin
= KeMemoryMap
[j
].BaseAddrLow
;
505 BlockEnd
= BlockBegin
+ KeMemoryMap
[j
].LengthLow
- 1;
507 /* Make sure it wasn't a > 4GB descriptor */
508 if (!KeMemoryMap
[j
].BaseAddrHigh
)
510 /* Make sure it doesn't overflow */
511 if (BlockEnd
< BlockBegin
) BlockEnd
= 0xFFFFFFFF;
513 /* Check if this was free memory */
514 if (KeMemoryMap
[j
].Type
== 1)
516 /* Get the page-aligned addresses */
517 BiasedPage
= BlockBegin
& (PAGE_SIZE
- 1);
518 BlockBegin
>>= PAGE_SHIFT
;
519 if (BiasedPage
) BlockBegin
++;
520 BlockEnd
= (BlockEnd
>> PAGE_SHIFT
) + 1;
522 /* Check if the block is within the 16MB memory hole */
523 if ((BlockBegin
< 0xFC0) && (BlockEnd
>= 0xFC0))
525 /* Don't allow it to cross this boundary */
529 /* Check if the boundary is across 16MB */
530 if ((BlockEnd
> 0xFFF) && (BlockBegin
<= 0xFFF))
532 /* Don't let it cross */
536 /* Check if the block describes the memory hole */
537 if ((BlockBegin
>= 0xFC0) && (BlockEnd
<= 0xFFF))
539 /* Set this region as temporary */
540 KiRosConfigureArcDescriptor(BlockBegin
,
542 MemoryFirmwareTemporary
);
547 /* Get the page-aligned addresses */
548 BlockBegin
>>= PAGE_SHIFT
;
549 BiasedPage
= (BlockEnd
+ 1) & (PAGE_SIZE
- 1);
550 BlockEnd
>>= PAGE_SHIFT
;
551 if (BiasedPage
) BlockEnd
++;
553 /* Set this memory as reserved */
554 KiRosConfigureArcDescriptor(BlockBegin
,
556 MemorySpecialMemory
);
564 KiRosInsertNtDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor
)
566 PLIST_ENTRY ListHead
, PreviousEntry
, NextEntry
;
567 PMEMORY_ALLOCATION_DESCRIPTOR Descriptor
= NULL
, NextDescriptor
= NULL
;
569 /* Loop the memory descriptor list */
570 ListHead
= &KeLoaderBlock
->MemoryDescriptorListHead
;
571 PreviousEntry
= ListHead
;
572 NextEntry
= ListHead
->Flink
;
573 while (NextEntry
!= ListHead
)
575 /* Get the current descriptor and check if it's below ours */
576 NextDescriptor
= CONTAINING_RECORD(NextEntry
,
577 MEMORY_ALLOCATION_DESCRIPTOR
,
579 if (NewDescriptor
->BasePage
< NextDescriptor
->BasePage
) break;
581 /* It isn't, save the previous entry and descriptor, and try again */
582 PreviousEntry
= NextEntry
;
583 Descriptor
= NextDescriptor
;
584 NextEntry
= NextEntry
->Flink
;
587 /* So we found the right spot to insert. Is this free memory? */
588 if (NewDescriptor
->MemoryType
!= LoaderFree
)
590 /* It isn't, so insert us before the last descriptor */
591 InsertHeadList(PreviousEntry
, &NewDescriptor
->ListEntry
);
595 /* We're free memory. Check if the entry we found is also free memory */
596 if ((PreviousEntry
!= ListHead
) &&
597 ((Descriptor
->MemoryType
== LoaderFree
) ||
598 (Descriptor
->MemoryType
== LoaderReserve
)) &&
599 ((Descriptor
->BasePage
+ Descriptor
->PageCount
) ==
600 NewDescriptor
->BasePage
))
602 /* It's free memory, and we're right after it. Enlarge that block */
603 Descriptor
->PageCount
+= NewDescriptor
->PageCount
;
604 NewDescriptor
= Descriptor
;
608 /* Our range scan't be combined, so just insert us separately */
609 InsertHeadList(PreviousEntry
, &NewDescriptor
->ListEntry
);
612 /* Check if we merged with an existing free memory block */
613 if ((NextEntry
!= ListHead
) &&
614 ((NextDescriptor
->MemoryType
== LoaderFree
) ||
615 (NextDescriptor
->MemoryType
== LoaderReserve
)) &&
616 ((NewDescriptor
->BasePage
+ NewDescriptor
->PageCount
) ==
617 NextDescriptor
->BasePage
))
619 /* Update our own block */
620 NewDescriptor
->PageCount
+= NextDescriptor
->PageCount
;
622 /* Remove the next block */
623 RemoveEntryList(&NextDescriptor
->ListEntry
);
630 KiRosBuildNtDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor
,
631 IN MEMORY_TYPE MemoryType
,
635 PMEMORY_ALLOCATION_DESCRIPTOR Descriptor
, NextDescriptor
= NULL
;
637 TYPE_OF_MEMORY CurrentType
;
640 /* Check how many pages we'll be consuming */
641 Delta
= BasePage
- MemoryDescriptor
->BasePage
;
642 if (!(Delta
) && (PageCount
== MemoryDescriptor
->PageCount
))
644 /* We can simply convert the current descriptor into our new type */
645 MemoryDescriptor
->MemoryType
= MemoryType
;
649 /* Get the current memory type of the descriptor, and reserve it */
650 CurrentType
= MemoryDescriptor
->MemoryType
;
651 MemoryDescriptor
->MemoryType
= LoaderSpecialMemory
;
653 /* Check if we'll need another descriptor for what's left of memory */
654 UseNext
= ((BasePage
!= MemoryDescriptor
->BasePage
) &&
655 (Delta
+ PageCount
!= MemoryDescriptor
->PageCount
));
657 /* Get a descriptor */
658 Descriptor
= KiRosGetMdFromArray();
659 if (!Descriptor
) return STATUS_INSUFFICIENT_RESOURCES
;
661 /* Check if we are using another descriptor */
664 /* Allocate that one too */
665 NextDescriptor
= KiRosGetMdFromArray();
666 if (!NextDescriptor
) return STATUS_INSUFFICIENT_RESOURCES
;
669 /* Build the descriptor we got */
670 Descriptor
->MemoryType
= MemoryType
;
671 Descriptor
->BasePage
= BasePage
;
672 Descriptor
->PageCount
= PageCount
;
674 /* Check if we're starting at the same place as the old one */
675 if (BasePage
== MemoryDescriptor
->BasePage
)
677 /* Simply decrease the old descriptor and rebase it */
678 MemoryDescriptor
->BasePage
+= PageCount
;
679 MemoryDescriptor
->PageCount
-= PageCount
;
680 MemoryDescriptor
->MemoryType
= CurrentType
;
682 else if (Delta
+ PageCount
== MemoryDescriptor
->PageCount
)
684 /* We finish where the old one did, shorten it */
685 MemoryDescriptor
->PageCount
-= PageCount
;
686 MemoryDescriptor
->MemoryType
= CurrentType
;
690 /* We're inside the current block, mark our free region */
691 NextDescriptor
->MemoryType
= LoaderFree
;
692 NextDescriptor
->BasePage
= BasePage
+ PageCount
;
693 NextDescriptor
->PageCount
= MemoryDescriptor
->PageCount
-
696 /* And cut down the current descriptor */
697 MemoryDescriptor
->PageCount
= Delta
;
698 MemoryDescriptor
->MemoryType
= CurrentType
;
700 /* Finally, insert our new free descriptor into the list */
701 KiRosInsertNtDescriptor(NextDescriptor
);
704 /* Insert the descriptor we allocated */
705 KiRosInsertNtDescriptor(Descriptor
);
709 return STATUS_SUCCESS
;
712 PMEMORY_ALLOCATION_DESCRIPTOR
714 KiRosFindNtDescriptor(IN ULONG BasePage
)
716 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
= NULL
;
717 PLIST_ENTRY NextEntry
, ListHead
;
719 /* Scan the memory descriptor list */
720 ListHead
= &KeLoaderBlock
->MemoryDescriptorListHead
;
721 NextEntry
= ListHead
->Flink
;
722 while (NextEntry
!= ListHead
)
724 /* Get the current descriptor */
725 MdBlock
= CONTAINING_RECORD(NextEntry
,
726 MEMORY_ALLOCATION_DESCRIPTOR
,
729 /* Check if it can contain our memory range */
730 if ((MdBlock
->BasePage
<= BasePage
) &&
731 (MdBlock
->BasePage
+ MdBlock
->PageCount
> BasePage
))
733 /* It can, break out */
737 /* Go to the next descriptor */
738 NextEntry
= NextEntry
->Flink
;
741 /* Return the descriptor we found, if any */
747 KiRosAllocateNtDescriptor(IN TYPE_OF_MEMORY MemoryType
,
751 OUT PULONG ReturnedBase
)
753 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
754 ULONG AlignedBase
, AlignedLimit
;
755 PMEMORY_ALLOCATION_DESCRIPTOR ActiveMdBlock
;
756 ULONG ActiveAlignedBase
= 0;
757 PLIST_ENTRY NextEntry
, ListHead
;
759 /* If no information was given, make some assumptions */
760 if (!Alignment
) Alignment
= 1;
761 if (!PageCount
) PageCount
= 1;
763 /* Start looking for a matching descvriptor */
766 /* Calculate the limit of the range */
767 AlignedLimit
= PageCount
+ BasePage
;
769 /* Find a descriptor that already contains our base address */
770 MdBlock
= KiRosFindNtDescriptor(BasePage
);
774 /* If it contains our limit as well, break out early */
775 if ((MdBlock
->PageCount
+ MdBlock
->BasePage
) > AlignedLimit
) break;
778 /* Loop the memory list */
779 ActiveMdBlock
= NULL
;
780 ListHead
= &KeLoaderBlock
->MemoryDescriptorListHead
;
781 NextEntry
= ListHead
->Flink
;
782 while (NextEntry
!= ListHead
)
784 /* Get the current descriptors */
785 MdBlock
= CONTAINING_RECORD(NextEntry
,
786 MEMORY_ALLOCATION_DESCRIPTOR
,
789 /* Align the base address and our limit */
790 AlignedBase
= (MdBlock
->BasePage
+ (Alignment
- 1)) &~ Alignment
;
791 AlignedLimit
= MdBlock
->PageCount
-
795 /* Check if this is a free block that can satisfy us */
796 if ((MdBlock
->MemoryType
== LoaderFree
) &&
797 (AlignedLimit
<= MdBlock
->PageCount
) &&
798 (PageCount
<= AlignedLimit
))
800 /* It is, stop searching */
801 ActiveMdBlock
= MdBlock
;
802 ActiveAlignedBase
= AlignedBase
;
806 /* Try the next block */
807 NextEntry
= NextEntry
->Flink
;
810 /* See if we came up with an adequate block */
813 /* Generate a descriptor in it */
814 *ReturnedBase
= AlignedBase
;
815 return KiRosBuildNtDescriptor(ActiveMdBlock
,
822 /* We found a matching block, generate a descriptor with it */
823 *ReturnedBase
= BasePage
;
824 return KiRosBuildNtDescriptor(MdBlock
, MemoryType
, BasePage
, PageCount
);
829 KiRosBuildArcMemoryList(VOID
)
831 PMEMORY_ALLOCATION_DESCRIPTOR Descriptor
;
832 MEMORY_DESCRIPTOR
*Memory
;
835 /* Loop all BIOS Memory Descriptors */
836 for (i
= 0; i
< NumberDescriptors
; i
++)
838 /* Get the current descriptor */
839 Memory
= &MDArray
[i
];
841 /* Allocate an NT Memory Descriptor */
842 Descriptor
= KiRosGetMdFromArray();
843 if (!Descriptor
) return ENOMEM
;
845 /* Copy the memory type */
846 Descriptor
->MemoryType
= Memory
->MemoryType
;
847 if (Memory
->MemoryType
== MemoryFreeContiguous
)
849 /* Convert this to free */
850 Descriptor
->MemoryType
= LoaderFree
;
852 else if (Memory
->MemoryType
== MemorySpecialMemory
)
854 /* Convert this to special memory */
855 Descriptor
->MemoryType
= LoaderSpecialMemory
;
858 /* Copy the range data */
859 Descriptor
->BasePage
= Memory
->BasePage
;
860 Descriptor
->PageCount
= Memory
->PageCount
;
862 /* Insert the descriptor */
863 if (Descriptor
->PageCount
) KiRosInsertNtDescriptor(Descriptor
);
867 return STATUS_SUCCESS
;
872 KiRosFixupComponentTree(IN PCONFIGURATION_COMPONENT_DATA p
,
875 PCONFIGURATION_COMPONENT pp
;
877 /* Loop each entry */
880 /* Grab the component entry */
881 pp
= &p
->ComponentEntry
;
883 /* Fixup the pointers */
884 if (pp
->Identifier
) pp
->Identifier
= (PVOID
)((ULONG_PTR
)pp
->Identifier
+ i
);
885 if (p
->ConfigurationData
) p
->ConfigurationData
= (PVOID
)((ULONG_PTR
)p
->ConfigurationData
+ i
);
886 if (p
->Parent
) p
->Parent
= (PVOID
)((ULONG_PTR
)p
->Parent
+ i
);
887 if (p
->Sibling
) p
->Sibling
= (PVOID
)((ULONG_PTR
)p
->Sibling
+ i
);
888 if (p
->Child
) p
->Child
= (PVOID
)((ULONG_PTR
)p
->Child
+ i
);
890 /* Check if we have a child */
891 if (p
->Child
) KiRosFixupComponentTree(p
->Child
, i
);
893 /* Get to the next entry */
900 KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock
,
901 IN PLOADER_PARAMETER_BLOCK
*NtLoaderBlock
)
903 PLOADER_PARAMETER_BLOCK LoaderBlock
;
904 PLDR_DATA_TABLE_ENTRY LdrEntry
;
905 PLOADER_MODULE RosEntry
;
909 PCHAR BootPath
, HalPath
;
910 CHAR CommandLine
[256];
911 PARC_DISK_SIGNATURE RosDiskInfo
, ArcDiskInfo
;
912 PIMAGE_NT_HEADERS NtHeader
;
913 WCHAR PathToDrivers
[] = L
"\\SystemRoot\\System32\\drivers\\";
914 WCHAR PathToSystem32
[] = L
"\\SystemRoot\\System32\\";
915 WCHAR PathSetup
[] = L
"\\SystemRoot\\";
916 CHAR DriverNameLow
[256];
919 ULONG KernelBase
= RosLoaderBlock
->ModsAddr
[0].ModStart
;
922 /* First get some kernel-loader globals */
923 AcpiTableDetected
= (RosLoaderBlock
->Flags
& MB_FLAGS_ACPI_TABLE
) ? TRUE
: FALSE
;
924 MmFreeLdrMemHigher
= RosLoaderBlock
->MemHigher
;
925 MmFreeLdrPageDirectoryEnd
= RosLoaderBlock
->PageDirectoryEnd
;
926 if (!MmFreeLdrPageDirectoryEnd
) MmFreeLdrPageDirectoryEnd
= 0x40000;
928 /* Set the NT Loader block and initialize it */
929 *NtLoaderBlock
= KeLoaderBlock
= LoaderBlock
= &BldrLoaderBlock
;
930 RtlZeroMemory(LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
932 /* Set the NLS Data block */
933 LoaderBlock
->NlsData
= &BldrNlsDataBlock
;
935 /* Set the ARC Data block */
936 LoaderBlock
->ArcDiskInformation
= &BldrArcDiskInfo
;
938 /* Assume this is from FreeLDR's SetupLdr */
939 LoaderBlock
->SetupLdrBlock
= &BldrSetupBlock
;
941 /* Setup the list heads */
942 InitializeListHead(&LoaderBlock
->LoadOrderListHead
);
943 InitializeListHead(&LoaderBlock
->MemoryDescriptorListHead
);
944 InitializeListHead(&LoaderBlock
->BootDriverListHead
);
945 InitializeListHead(&LoaderBlock
->ArcDiskInformation
->DiskSignatureListHead
);
947 /* Build the free memory map, which uses BIOS Descriptors */
948 KiRosBuildBiosMemoryMap();
950 /* Build entries for ReactOS memory ranges, which uses ARC Descriptors */
951 KiRosBuildOsMemoryMap();
954 /* Build entries for the reserved map, which uses ARC Descriptors */
955 KiRosBuildReservedMemoryMap();
958 /* Now convert the BIOS and ARC Descriptors into NT Memory Descirptors */
959 KiRosBuildArcMemoryList();
961 /* Loop boot driver list */
962 for (i
= 0; i
< RosLoaderBlock
->ModsCount
; i
++)
964 /* Get the ROS loader entry */
965 RosEntry
= &RosLoaderBlock
->ModsAddr
[i
];
966 DriverName
= (PCHAR
)RosEntry
->String
;
967 ModStart
= (PVOID
)RosEntry
->ModStart
;
968 ModSize
= RosEntry
->ModEnd
- (ULONG_PTR
)ModStart
;
970 /* Check if this is any of the NLS files */
971 if (!_stricmp(DriverName
, "ansi.nls"))
974 ModStart
= RVA(ModStart
, KSEG0_BASE
);
975 LoaderBlock
->NlsData
->AnsiCodePageData
= ModStart
;
977 /* Create an MD for it */
978 KiRosAllocateNtDescriptor(LoaderNlsData
,
979 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
981 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
986 else if (!_stricmp(DriverName
, "oem.nls"))
989 ModStart
= RVA(ModStart
, KSEG0_BASE
);
990 LoaderBlock
->NlsData
->OemCodePageData
= ModStart
;
992 /* Create an MD for it */
993 KiRosAllocateNtDescriptor(LoaderNlsData
,
994 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
996 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1001 else if (!_stricmp(DriverName
, "casemap.nls"))
1003 /* Unicode Code page */
1004 ModStart
= RVA(ModStart
, KSEG0_BASE
);
1005 LoaderBlock
->NlsData
->UnicodeCodePageData
= ModStart
;
1007 /* Create an MD for it */
1008 KiRosAllocateNtDescriptor(LoaderNlsData
,
1009 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
1011 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1017 /* Check if this is the SYSTEM hive */
1018 if (!(_stricmp(DriverName
, "system")) ||
1019 !(_stricmp(DriverName
, "system.hiv")))
1021 /* Save registry data */
1022 ModStart
= RVA(ModStart
, KSEG0_BASE
);
1023 LoaderBlock
->RegistryBase
= ModStart
;
1024 LoaderBlock
->RegistryLength
= ModSize
;
1026 /* Disable setup mode */
1027 LoaderBlock
->SetupLdrBlock
= NULL
;
1029 /* Create an MD for it */
1030 KiRosAllocateNtDescriptor(LoaderRegistryData
,
1031 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
1033 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1039 /* Check if this is the HARDWARE hive */
1040 if (!(_stricmp(DriverName
, "hardware")) ||
1041 !(_stricmp(DriverName
, "hardware.hiv")))
1043 /* Create an MD for it */
1044 KiRosAllocateNtDescriptor(LoaderRegistryData
,
1045 (ULONG_PTR
)ModStart
>> PAGE_SHIFT
,
1046 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1052 /* Check if this is the kernel */
1053 if (!(_stricmp(DriverName
, "ntoskrnl.exe")))
1055 /* Create an MD for it */
1056 KiRosAllocateNtDescriptor(LoaderSystemCode
,
1057 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
1059 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1063 else if (!(_stricmp(DriverName
, "hal.dll")))
1065 /* Create an MD for the HAL */
1066 KiRosAllocateNtDescriptor(LoaderHalCode
,
1067 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
1069 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1075 /* Create an MD for any driver */
1076 KiRosAllocateNtDescriptor(LoaderBootDriver
,
1077 ((ULONG_PTR
)ModStart
&~ KSEG0_BASE
) >>
1079 (ModSize
+ PAGE_SIZE
- 1)>> PAGE_SHIFT
,
1085 ModStart
= (PVOID
)((ULONG
)ModStart
+ 0x80800000 - KernelBase
);
1088 /* Lowercase the drivername so we can check its extension later */
1089 strcpy(DriverNameLow
, DriverName
);
1090 _strlwr(DriverNameLow
);
1092 /* Setup the loader entry */
1093 LdrEntry
= &BldrModules
[i
];
1094 RtlZeroMemory(LdrEntry
, sizeof(LDR_DATA_TABLE_ENTRY
));
1096 /* Convert driver name from ANSI to Unicode */
1097 for (j
= 0; j
< strlen(DriverName
); j
++)
1099 BldrModuleStrings
[i
][j
] = DriverName
[j
];
1102 /* Setup driver name */
1103 RtlInitUnicodeString(&LdrEntry
->BaseDllName
, BldrModuleStrings
[i
]);
1105 /* Construct a correct full name */
1106 BldrModuleStringsFull
[i
][0] = 0;
1107 LdrEntry
->FullDllName
.MaximumLength
= 260 * sizeof(WCHAR
);
1108 LdrEntry
->FullDllName
.Length
= 0;
1109 LdrEntry
->FullDllName
.Buffer
= BldrModuleStringsFull
[i
];
1111 /* Guess the path */
1112 if (LoaderBlock
->SetupLdrBlock
)
1114 UNICODE_STRING TempString
;
1115 RtlInitUnicodeString(&TempString
, PathSetup
);
1116 RtlAppendUnicodeStringToString(&LdrEntry
->FullDllName
, &TempString
);
1118 else if (strstr(DriverNameLow
, ".dll") || strstr(DriverNameLow
, ".exe"))
1120 UNICODE_STRING TempString
;
1121 RtlInitUnicodeString(&TempString
, PathToSystem32
);
1122 RtlAppendUnicodeStringToString(&LdrEntry
->FullDllName
, &TempString
);
1126 UNICODE_STRING TempString
;
1127 RtlInitUnicodeString(&TempString
, PathToDrivers
);
1128 RtlAppendUnicodeStringToString(&LdrEntry
->FullDllName
, &TempString
);
1131 /* Append base name of the driver */
1132 RtlAppendUnicodeStringToString(&LdrEntry
->FullDllName
, &LdrEntry
->BaseDllName
);
1134 /* Copy data from Freeldr Module Entry */
1135 LdrEntry
->DllBase
= ModStart
;
1136 LdrEntry
->SizeOfImage
= ModSize
;
1138 /* Copy additional data */
1139 NtHeader
= RtlImageNtHeader(ModStart
);
1140 LdrEntry
->EntryPoint
= RVA(ModStart
,
1142 OptionalHeader
.AddressOfEntryPoint
);
1144 /* Initialize other data */
1145 LdrEntry
->LoadCount
= 1;
1146 LdrEntry
->Flags
= LDRP_IMAGE_DLL
|
1147 LDRP_ENTRY_PROCESSED
;
1148 if (RosEntry
->Reserved
) LdrEntry
->Flags
|= LDRP_ENTRY_INSERTED
;
1150 /* Insert it into the loader block */
1151 InsertTailList(&LoaderBlock
->LoadOrderListHead
,
1152 &LdrEntry
->InLoadOrderLinks
);
1155 /* Setup command line */
1156 LoaderBlock
->LoadOptions
= BldrCommandLine
;
1157 strcpy(BldrCommandLine
, RosLoaderBlock
->CommandLine
);
1159 /* Setup the extension block */
1160 LoaderBlock
->Extension
= &BldrExtensionBlock
;
1161 LoaderBlock
->Extension
->Size
= sizeof(LOADER_PARAMETER_EXTENSION
);
1162 LoaderBlock
->Extension
->MajorVersion
= 5;
1163 LoaderBlock
->Extension
->MinorVersion
= 2;
1165 /* FreeLDR hackllocates 1536 static pages for the initial boot images */
1166 LoaderBlock
->Extension
->LoaderPagesSpanned
= 1536 * PAGE_SIZE
;
1168 /* ReactOS always boots the kernel at 0x80800000 (just like NT 5.2) */
1169 LoaderBlock
->Extension
->LoaderPagesSpanned
+= 0x80800000 - KSEG0_BASE
;
1171 /* Now convert to pages */
1172 LoaderBlock
->Extension
->LoaderPagesSpanned
/= PAGE_SIZE
;
1174 /* Now setup the setup block if we have one */
1175 if (LoaderBlock
->SetupLdrBlock
)
1177 /* All we'll setup right now is the flag for text-mode setup */
1178 LoaderBlock
->SetupLdrBlock
->Flags
= 1;
1181 /* Make a copy of the command line */
1182 strcpy(CommandLine
, LoaderBlock
->LoadOptions
);
1184 /* Find the first \, separating the ARC path from NT path */
1185 BootPath
= strchr(CommandLine
, '\\');
1186 *BootPath
= ANSI_NULL
;
1187 strncpy(BldrArcBootPath
, CommandLine
, 63);
1188 LoaderBlock
->ArcBootDeviceName
= BldrArcBootPath
;
1190 /* The rest of the string is the NT path */
1191 HalPath
= strchr(BootPath
+ 1, ' ');
1192 *HalPath
= ANSI_NULL
;
1193 BldrNtBootPath
[0] = '\\';
1194 strncat(BldrNtBootPath
, BootPath
+ 1, 63);
1195 strcat(BldrNtBootPath
,"\\");
1196 LoaderBlock
->NtBootPathName
= BldrNtBootPath
;
1198 /* Set the HAL paths */
1199 strncpy(BldrArcHalPath
, BldrArcBootPath
, 63);
1200 LoaderBlock
->ArcHalDeviceName
= BldrArcHalPath
;
1201 strcpy(BldrNtHalPath
, "\\");
1202 LoaderBlock
->NtHalPathName
= BldrNtHalPath
;
1204 /* Use this new command line */
1205 strncpy(LoaderBlock
->LoadOptions
, HalPath
+ 2, 255);
1207 /* Parse it and change every slash to a space */
1208 BootPath
= LoaderBlock
->LoadOptions
;
1209 do {if (*BootPath
== '/') *BootPath
= ' ';} while (*BootPath
++);
1211 /* Now let's loop ARC disk information */
1212 for (i
= 0; i
< RosLoaderBlock
->DrivesCount
; i
++)
1214 /* Get the ROS loader entry */
1215 RosDiskInfo
= &RosLoaderBlock
->DrivesAddr
[i
];
1217 /* Get the ARC structure */
1218 ArcDiskInfo
= &BldrDiskInfo
[i
];
1220 /* Copy the data over */
1221 ArcDiskInfo
->Signature
= RosDiskInfo
->Signature
;
1222 ArcDiskInfo
->CheckSum
= RosDiskInfo
->CheckSum
;
1224 /* Copy the ARC Name */
1225 strcpy(BldrArcNames
[i
], RosDiskInfo
->ArcName
);
1226 ArcDiskInfo
->ArcName
= BldrArcNames
[i
];
1228 /* Insert into the list */
1229 InsertTailList(&LoaderBlock
->ArcDiskInformation
->DiskSignatureListHead
,
1230 &ArcDiskInfo
->ListEntry
);
1233 /* Copy the ARC Hardware Tree */
1234 RtlCopyMemory(BldrArcHwBuffer
, (PVOID
)RosLoaderBlock
->ArchExtra
, 16 * 1024);
1235 LoaderBlock
->ConfigurationRoot
= (PVOID
)BldrArcHwBuffer
;
1238 KiRosFixupComponentTree(LoaderBlock
->ConfigurationRoot
,
1239 (ULONG_PTR
)BldrArcHwBuffer
-
1240 RosLoaderBlock
->ArchExtra
);
1245 KiSetupSyscallHandler();
1249 KiRosPrepareForSystemStartup(IN ULONG Dummy
,
1250 IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock
)
1252 PLOADER_PARAMETER_BLOCK NtLoaderBlock
;
1253 ULONG size
, i
= 0, *ent
;
1254 #if defined(_M_IX86)
1256 PKGDTENTRY TssEntry
;
1258 /* Load the GDT and IDT */
1259 Ke386SetGlobalDescriptorTable(*(PKDESCRIPTOR
)&KiGdtDescriptor
.Limit
);
1260 Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR
)&KiIdtDescriptor
.Limit
);
1262 /* Initialize the boot TSS */
1264 TssEntry
= &KiBootGdt
[KGDT_TSS
/ sizeof(KGDTENTRY
)];
1265 TssEntry
->HighWord
.Bits
.Type
= I386_TSS
;
1266 TssEntry
->HighWord
.Bits
.Pres
= 1;
1267 TssEntry
->HighWord
.Bits
.Dpl
= 0;
1268 TssEntry
->BaseLow
= (USHORT
)((ULONG_PTR
)Tss
& 0xFFFF);
1269 TssEntry
->HighWord
.Bytes
.BaseMid
= (UCHAR
)((ULONG_PTR
)Tss
>> 16);
1270 TssEntry
->HighWord
.Bytes
.BaseHi
= (UCHAR
)((ULONG_PTR
)Tss
>> 24);
1274 // Zero bats. We might have residual bats set that will interfere with
1275 // our mapping of ofwldr.
1276 for (i
= 0; i
< 4; i
++)
1278 SetBat(i
, 0, 0, 0); SetBat(i
, 1, 0, 0);
1280 KiSetupSyscallHandler();
1281 DbgPrint("Kernel Power (%08x)\n", LoaderBlock
);
1282 DbgPrint("ArchExtra (%08x)!\n", LoaderBlock
->ArchExtra
);
1285 /* Save pointer to ROS Block */
1286 KeRosLoaderBlock
= LoaderBlock
;
1287 MmFreeLdrLastKernelAddress
= PAGE_ROUND_UP(KeRosLoaderBlock
->
1288 ModsAddr
[KeRosLoaderBlock
->
1292 MmFreeLdrFirstKrnlPhysAddr
= KeRosLoaderBlock
->ModsAddr
[0].ModStart
;
1293 MmFreeLdrLastKrnlPhysAddr
= MmFreeLdrLastKernelAddress
;
1294 DbgPrint("kernel phys = %08x-%08x\n",
1295 MmFreeLdrFirstKrnlPhysAddr
,
1296 MmFreeLdrLastKrnlPhysAddr
);
1298 MmFreeLdrFirstKrnlPhysAddr
= KeRosLoaderBlock
->ModsAddr
[0].ModStart
-
1300 MmFreeLdrLastKrnlPhysAddr
= MmFreeLdrLastKernelAddress
- KSEG0_BASE
;
1303 /* Save memory manager data */
1304 KeMemoryMapRangeCount
= 0;
1305 if (LoaderBlock
->Flags
& MB_FLAGS_MMAP_INFO
)
1307 /* We have a memory map from the nice BIOS */
1308 ent
= ((PULONG
)(LoaderBlock
->MmapAddr
- sizeof(ULONG
)));
1312 /* Map it until we run out of size */
1313 while (i
< LoaderBlock
->MmapLength
)
1315 /* Copy into the Kernel Memory Map */
1316 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1317 (PVOID
)(LoaderBlock
->MmapAddr
+ i
),
1318 sizeof(ADDRESS_RANGE
));
1320 /* Increase Memory Map Count */
1321 KeMemoryMapRangeCount
++;
1328 LoaderBlock
->MmapLength
= KeMemoryMapRangeCount
* sizeof(ADDRESS_RANGE
);
1329 LoaderBlock
->MmapAddr
= (ULONG
)KeMemoryMap
;
1333 /* Nothing from BIOS */
1334 LoaderBlock
->MmapLength
= 0;
1335 LoaderBlock
->MmapAddr
= (ULONG
)KeMemoryMap
;
1338 #if defined(_M_IX86)
1339 /* Set up the VDM Data */
1343 /* Convert the loader block */
1344 KiRosFrldrLpbToNtLpb(KeRosLoaderBlock
, &NtLoaderBlock
);
1347 DbgPrint("Finished KiRosFrldrLpbToNtLpb\n");
1350 /* Do general System Startup */
1351 KiSystemStartup(NtLoaderBlock
);