/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-
-#define NDEBUG
+//#define NDEBUG
#include <debug.h>
+#ifdef _M_PPC
+#include <ppcmmu/mmu.h>
+#define KERNEL_RVA(x) RVA(x,0x80800000)
+#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) + KernelBase) >> PAGE_SHIFT)
+#else
+#define KERNEL_RVA(x) RVA(x,KSEG0_BASE)
+#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) & ~KSEG0_BASE) >> PAGE_SHIFT)
+#endif
+
+typedef struct _BIOS_MEMORY_DESCRIPTOR
+{
+ ULONG BlockBase;
+ ULONG BlockSize;
+} BIOS_MEMORY_DESCRIPTOR, *PBIOS_MEMORY_DESCRIPTOR;
+
/* GLOBALS *******************************************************************/
-/* FreeLDR Module Data */
-LOADER_MODULE KeLoaderModules[64];
-ULONG KeLoaderModuleCount;
-static CHAR KeLoaderModuleStrings[64][256];
+/* Function pointer for early debug prints */
+ULONG (*FrLdrDbgPrint)(const char *Format, ...);
-/* FreeLDR Memory Data */
+/* FreeLDR Loader Data */
+PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
+BOOLEAN AcpiTableDetected = FALSE;
ADDRESS_RANGE KeMemoryMap[64];
ULONG KeMemoryMapRangeCount;
-ULONG_PTR MmFreeLdrFirstKrnlPhysAddr, MmFreeLdrLastKrnlPhysAddr;
-ULONG_PTR MmFreeLdrLastKernelAddress;
-ULONG MmFreeLdrMemHigher;
-ULONG MmFreeLdrPageDirectoryEnd;
-/* FreeLDR Loader Data */
-ROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
-static CHAR KeLoaderCommandLine[256];
-BOOLEAN AcpiTableDetected;
-
-/* FreeLDR PE Hack Data */
-extern LDR_DATA_TABLE_ENTRY HalModuleObject;
-
-/* NT Loader Data */
-LOADER_PARAMETER_BLOCK BldrLoaderBlock;
-LOADER_PARAMETER_EXTENSION BldrExtensionBlock;
-CHAR BldrCommandLine[256];
-CHAR BldrArcBootPath[64];
-CHAR BldrArcHalPath[64];
-CHAR BldrNtHalPath[64];
-CHAR BldrNtBootPath[64];
-LDR_DATA_TABLE_ENTRY BldrModules[64];
-MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64];
-WCHAR BldrModuleStrings[64][260];
-NLS_DATA_BLOCK BldrNlsDataBlock;
-SETUP_LOADER_BLOCK BldrSetupBlock;
-struct _boot_infos_t *BootInfo;
+/* NT Loader Module/Descriptor Count */
+ULONG BldrCurrentMd;
+ULONG BldrCurrentMod;
+
+/* NT Loader Data. Eats up about 100KB! */
+LOADER_PARAMETER_BLOCK BldrLoaderBlock; // 0x0000
+LOADER_PARAMETER_EXTENSION BldrExtensionBlock; // 0x0060
+CHAR BldrCommandLine[256]; // 0x00DC
+CHAR BldrArcBootPath[64]; // 0x01DC
+CHAR BldrArcHalPath[64]; // 0x021C
+CHAR BldrNtHalPath[64]; // 0x025C
+CHAR BldrNtBootPath[64]; // 0x029C
+LDR_DATA_TABLE_ENTRY BldrModules[64]; // 0x02DC
+MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[60]; // 0x14DC
+WCHAR BldrModuleStrings[64][260]; // 0x19DC
+WCHAR BldrModuleStringsFull[64][260]; // 0x9BDC
+NLS_DATA_BLOCK BldrNlsDataBlock; // 0x11DDC
+SETUP_LOADER_BLOCK BldrSetupBlock; // 0x11DE8
+ARC_DISK_INFORMATION BldrArcDiskInfo; // 0x12134
+CHAR BldrArcNames[32][256]; // 0x1213C
+ARC_DISK_SIGNATURE BldrDiskInfo[32]; // 0x1413C
+CHAR BldrArcHwBuffer[16 * 1024]; // 0x1843C
+
+/* BIOS Memory Map */
+BIOS_MEMORY_DESCRIPTOR BiosMemoryDescriptors[16] = { { 0, 0 }, };
+PBIOS_MEMORY_DESCRIPTOR BiosMemoryDescriptorList = BiosMemoryDescriptors;
+
+/* ARC Memory Map */
+ULONG NumberDescriptors = 0;
+MEMORY_DESCRIPTOR MDArray[60] = { { 0, 0, 0 }, };
-#ifdef _M_PPC
-#include "font.h"
-boot_infos_t PpcEarlybootInfo;
+/* FUNCTIONS *****************************************************************/
+
+PMEMORY_ALLOCATION_DESCRIPTOR
+NTAPI
+KiRosGetMdFromArray(VOID)
+{
+ /* Return the next MD from the list, but make sure we don't overflow */
+ if (BldrCurrentMd > 60) ASSERT(FALSE);
+ return &BldrMemoryDescriptors[BldrCurrentMd++];
+}
+
+VOID
+NTAPI
+KiRosAddBiosBlock(ULONG Address,
+ ULONG Size)
+{
+ PBIOS_MEMORY_DESCRIPTOR BiosBlock = BiosMemoryDescriptorList;
+
+ /* Loop our BIOS Memory Descriptor List */
+ while (BiosBlock->BlockSize > 0)
+ {
+ /* Check if we've found a matching head block */
+ if (Address + Size == BiosBlock->BlockBase)
+ {
+ /* Simply enlarge and rebase it */
+ BiosBlock->BlockBase = Address;
+ BiosBlock->BlockSize += Size;
+ break;
+ }
+
+ /* Check if we've found a matching tail block */
+ if (Address == (BiosBlock->BlockBase + BiosBlock->BlockSize))
+ {
+ /* Simply enlarge it */
+ BiosBlock->BlockSize += Size;
+ break;
+ }
+
+ /* Nothing suitable found, try the next block */
+ BiosBlock++;
+ }
+
+ /* No usable blocks found, found a free block instead */
+ if (!BiosBlock->BlockSize)
+ {
+ /* Write our data */
+ BiosBlock->BlockBase = Address;
+ BiosBlock->BlockSize = Size;
+
+ /* Create a new block and mark it as the end of the array */
+ BiosBlock++;
+ BiosBlock->BlockBase = BiosBlock->BlockSize = 0L;
+ }
+}
+
+VOID
+NTAPI
+KiRosBuildBiosMemoryMap(VOID)
+{
+ ULONG BlockBegin, BlockEnd;
+ ULONG j;
+
+ /* Loop the BIOS Memory Map */
+ for (j = 0; j < KeMemoryMapRangeCount; j++)
+ {
+ /* Get the start and end addresses */
+ BlockBegin = KeMemoryMap[j].BaseAddrLow;
+ BlockEnd = KeMemoryMap[j].BaseAddrLow + KeMemoryMap[j].LengthLow - 1;
+
+ /* Make sure this isn't a > 4GB descriptor */
+ if (!KeMemoryMap[j].BaseAddrHigh)
+ {
+ /* Make sure we don't overflow */
+ if (BlockEnd < BlockBegin) BlockEnd = 0xFFFFFFFF;
+
+ /* Check if this is free memory */
+ if (KeMemoryMap[j].Type == 1)
+ {
+ /* Add it to our BIOS descriptors */
+ KiRosAddBiosBlock(BlockBegin, BlockEnd - BlockBegin + 1);
+ }
+ }
+ }
+}
+
+NTSTATUS
+NTAPI
+KiRosAllocateArcDescriptor(IN ULONG PageBegin,
+ IN ULONG PageEnd,
+ IN MEMORY_TYPE MemoryType)
+{
+ ULONG i;
+
+ /* Loop all our descriptors */
+ for (i = 0; i < NumberDescriptors; i++)
+ {
+ /* Attempt to fing a free block that describes our region */
+ if ((MDArray[i].MemoryType == MemoryFree) &&
+ (MDArray[i].BasePage <= PageBegin) &&
+ (MDArray[i].BasePage + MDArray[i].PageCount > PageBegin) &&
+ (MDArray[i].BasePage + MDArray[i].PageCount >= PageEnd))
+ {
+ /* Found one! */
+ break;
+ }
+ }
+
+ /* Check if we found no free blocks, and fail if so */
+ if (i == NumberDescriptors) return ENOMEM;
+
+ /* Check if the block has our base address */
+ if (MDArray[i].BasePage == PageBegin)
+ {
+ /* Check if it also has our ending address */
+ if ((MDArray[i].BasePage + MDArray[i].PageCount) == PageEnd)
+ {
+ /* Then convert this region into our new memory type */
+ MDArray[i].MemoryType = MemoryType;
+ }
+ else
+ {
+ /* Otherwise, make sure we have enough descriptors */
+ if (NumberDescriptors == 60) return ENOMEM;
+
+ /* Cut this descriptor short */
+ MDArray[i].BasePage = PageEnd;
+ MDArray[i].PageCount -= (PageEnd - PageBegin);
+
+ /* And allocate a new descriptor for our memory range */
+ MDArray[NumberDescriptors].BasePage = PageBegin;
+ MDArray[NumberDescriptors].PageCount = PageEnd - PageBegin;
+ MDArray[NumberDescriptors].MemoryType = MemoryType;
+ NumberDescriptors++;
+ }
+ }
+ else if ((MDArray[i].BasePage + MDArray[i].PageCount) == PageEnd)
+ {
+ /* This block has our end address, make sure we have a free block */
+ if (NumberDescriptors == 60) return ENOMEM;
+
+ /* Rebase this descriptor */
+ MDArray[i].PageCount = PageBegin - MDArray[i].BasePage;
+
+ /* And allocate a new descriptor for our memory range */
+ MDArray[NumberDescriptors].BasePage = PageBegin;
+ MDArray[NumberDescriptors].PageCount = PageEnd - PageBegin;
+ MDArray[NumberDescriptors].MemoryType = MemoryType;
+ NumberDescriptors++;
+ }
+ else
+ {
+ /* We'll need two descriptors, make sure they're available */
+ if ((NumberDescriptors + 1) >= 60) return ENOMEM;
+
+ /* Allocate a free memory descriptor for what follows us */
+ MDArray[NumberDescriptors].BasePage = PageEnd;
+ MDArray[NumberDescriptors].PageCount = MDArray[i].PageCount -
+ (PageEnd - MDArray[i].BasePage);
+ MDArray[NumberDescriptors].MemoryType = MemoryFree;
+ NumberDescriptors++;
+
+ /* Cut down the current free descriptor */
+ MDArray[i].PageCount = PageBegin - MDArray[i].BasePage;
+
+ /* Allocate a new memory descriptor for our memory range */
+ MDArray[NumberDescriptors].BasePage = PageBegin;
+ MDArray[NumberDescriptors].PageCount = PageEnd - PageBegin;
+ MDArray[NumberDescriptors].MemoryType = MemoryType;
+ NumberDescriptors++;
+ }
+
+ /* Everything went well */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KiRosConfigureArcDescriptor(IN ULONG PageBegin,
+ IN ULONG PageEnd,
+ IN TYPE_OF_MEMORY MemoryType)
+{
+ ULONG i;
+ ULONG BlockBegin, BlockEnd;
+ MEMORY_TYPE BlockType;
+ BOOLEAN Combined = FALSE;
+
+ /* If this descriptor seems bogus, just return */
+ if (PageEnd <= PageBegin) return STATUS_SUCCESS;
+
+ /* Loop every ARC descriptor, trying to find one we can modify */
+ for (i = 0; i < NumberDescriptors; i++)
+ {
+ /* Get its settings */
+ BlockBegin = MDArray[i].BasePage;
+ BlockEnd = MDArray[i].BasePage + MDArray[i].PageCount;
+ BlockType = MDArray[i].MemoryType;
+
+ /* Check if we can fit inside this block */
+ if (BlockBegin < PageBegin)
+ {
+ /* Check if we are larger then it */
+ if ((BlockEnd > PageBegin) && (BlockEnd <= PageEnd))
+ {
+ /* Make it end where we start */
+ BlockEnd = PageBegin;
+ }
+
+ /* Check if it ends after we do */
+ if (BlockEnd > PageEnd)
+ {
+ /* Make sure we can allocate a descriptor */
+ if (NumberDescriptors == 60) return ENOMEM;
+
+ /* Create a descriptor for whatever memory we're not part of */
+ MDArray[NumberDescriptors].MemoryType = BlockType;
+ MDArray[NumberDescriptors].BasePage = PageEnd;
+ MDArray[NumberDescriptors].PageCount = BlockEnd - PageEnd;
+ NumberDescriptors++;
+
+ /* The next block ending is now where we begin */
+ BlockEnd = PageBegin;
+ }
+ }
+ else
+ {
+ /* Check if the blog begins inside our range */
+ if (BlockBegin < PageEnd)
+ {
+ /* Check if it ends before we do */
+ if (BlockEnd < PageEnd)
+ {
+ /* Then make it disappear */
+ BlockEnd = BlockBegin;
+ }
+ else
+ {
+ /* Otherwise make it start where we end */
+ BlockBegin = PageEnd;
+ }
+ }
+ }
+
+ /* Check if the block matches us, and we haven't tried combining yet */
+ if (((TYPE_OF_MEMORY)BlockType == MemoryType) && !(Combined))
+ {
+ /* Check if it starts where we end */
+ if (BlockBegin == PageEnd)
+ {
+ /* Make it start with us, and combine us */
+ BlockBegin = PageBegin;
+ Combined = TRUE;
+ }
+ else if (BlockEnd == PageBegin)
+ {
+ /* Otherwise, it ends where we begin, combine its ending */
+ BlockEnd = PageEnd;
+ Combined = TRUE;
+ }
+ }
+
+ /* Check the original block data matches with what we came up with */
+ if ((MDArray[i].BasePage == BlockBegin) &&
+ (MDArray[i].PageCount == BlockEnd - BlockBegin))
+ {
+ /* Then skip it */
+ continue;
+ }
+
+ /* Otherwise, set our new settings for this block */
+ MDArray[i].BasePage = BlockBegin;
+ MDArray[i].PageCount = BlockEnd - BlockBegin;
+
+ /* Check if we are killing the block */
+ if (BlockBegin == BlockEnd)
+ {
+ /* Delete this block and restart the loop properly */
+ NumberDescriptors--;
+ if (i < NumberDescriptors) MDArray[i] = MDArray[NumberDescriptors];
+ i--;
+ }
+ }
+
+ /* If we got here without combining, we need to allocate a new block */
+ if (!(Combined) && (MemoryType < LoaderMaximum))
+ {
+ /* Make sure there's enough descriptors */
+ if (NumberDescriptors == 60) return ENOMEM;
+
+ /* Allocate a new block with our data */
+ MDArray[NumberDescriptors].MemoryType = MemoryType;
+ MDArray[NumberDescriptors].BasePage = PageBegin;
+ MDArray[NumberDescriptors].PageCount = PageEnd - PageBegin;
+ NumberDescriptors++;
+ }
+
+ /* Changes complete, return success */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KiRosBuildOsMemoryMap(VOID)
+{
+ PBIOS_MEMORY_DESCRIPTOR MdBlock;
+ ULONG BlockStart, BlockEnd, BiasedStart, BiasedEnd, PageStart, PageEnd;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG BiosPage = 0xA0;
+
+ /* Loop the BIOS Memory Descriptor List */
+ MdBlock = BiosMemoryDescriptorList;
+ while (MdBlock->BlockSize)
+ {
+ /* Get the statrt and end addresses */
+ BlockStart = MdBlock->BlockBase;
+ BlockEnd = BlockStart + MdBlock->BlockSize - 1;
+
+ /* Align them to page boundaries */
+ BiasedStart = BlockStart & (PAGE_SIZE - 1);
+ if (BiasedStart) BlockStart = BlockStart + PAGE_SIZE - BiasedStart;
+ BiasedEnd = (BlockEnd + 1) & (ULONG)(PAGE_SIZE - 1);
+ if (BiasedEnd) BlockEnd -= BiasedEnd;
+
+ /* Get the actual page numbers */
+ PageStart = BlockStart >> PAGE_SHIFT;
+ PageEnd = (BlockEnd + 1) >> PAGE_SHIFT;
+
+ /* If we're starting at page 0, then put the BIOS page at the end */
+ if (!PageStart) BiosPage = PageEnd;
+
+ /* Check if we did any alignment */
+ if (BiasedStart)
+ {
+ /* Mark that region as reserved */
+ Status = KiRosConfigureArcDescriptor(PageStart - 1,
+ PageStart,
+ MemorySpecialMemory);
+ if (Status != STATUS_SUCCESS) break;
+ }
+
+ /* Check if we did any alignment */
+ if (BiasedEnd)
+ {
+ /* Mark that region as reserved */
+ Status = KiRosConfigureArcDescriptor(PageEnd - 1,
+ PageEnd,
+ MemorySpecialMemory);
+ if (Status != STATUS_SUCCESS) break;
+
+ /* If the bios page was the last page, use the next one instead */
+ if (BiosPage == PageEnd) BiosPage += 1;
+ }
+
+ /* Check if the page is below the 16MB Memory hole */
+ if (PageEnd <= 0xFC0)
+ {
+ /* It is, mark the memory a free */
+ Status = KiRosConfigureArcDescriptor(PageStart,
+ PageEnd,
+ LoaderFree);
+ }
+ else if (PageStart >= 0x1000)
+ {
+ /* It's over 16MB, so that memory gets marked as reserve */
+ Status = KiRosConfigureArcDescriptor(PageStart,
+ PageEnd,
+ LoaderFree);
+ }
+ else
+ {
+ /* Check if it starts below the memory hole */
+ if (PageStart < 0xFC0)
+ {
+ /* Mark that part as free */
+ Status = KiRosConfigureArcDescriptor(PageStart,
+ 0xFC0,
+ MemoryFree);
+ if (Status != STATUS_SUCCESS) break;
+
+ /* And update the page start for the code below */
+ PageStart = 0xFC0;
+ }
+
+ /* Any code in the memory hole region ends up as reserve */
+ Status = KiRosConfigureArcDescriptor(PageStart,
+ PageEnd,
+ LoaderFree);
+ }
+
+ /* If we failed, break out, otherwise, go to the next BIOS block */
+ if (Status != STATUS_SUCCESS) break;
+ MdBlock++;
+ }
+
+ /* If anything failed until now, return error code */
+ if (Status != STATUS_SUCCESS) return Status;
+
+#ifdef _M_IX86
+ /* Set the top 16MB region as reserved */
+ Status = KiRosConfigureArcDescriptor(0xFC0, 0x1000, MemorySpecialMemory);
+ if (Status != STATUS_SUCCESS) return Status;
+
+ /* Setup the BIOS region as reserved */
+ KiRosConfigureArcDescriptor(0xA0, 0x100, LoaderMaximum);
+ KiRosConfigureArcDescriptor(BiosPage, 0x100, MemoryFirmwarePermanent);
+
+ /* Build an entry for the IVT */
+ Status = KiRosAllocateArcDescriptor(0, 1, MemoryFirmwarePermanent);
+ if (Status != STATUS_SUCCESS) return Status;
#endif
-#define KSEG0_BASE 0x80000000
+ /* Build an entry for the KPCR and KUSER_SHARED_DATA */
+ Status = KiRosAllocateArcDescriptor(1, 3, LoaderStartupPcrPage);
+ if (Status != STATUS_SUCCESS) return Status;
+
+ /* Build an entry for the PDE and return the status */
+ Status = KiRosAllocateArcDescriptor(KeRosLoaderBlock->
+ PageDirectoryStart >> PAGE_SHIFT,
+ KeRosLoaderBlock->
+ PageDirectoryEnd >> PAGE_SHIFT,
+ LoaderMemoryData);
+ return Status;
+}
-/* FUNCTIONS *****************************************************************/
+VOID
+NTAPI
+KiRosBuildReservedMemoryMap(VOID)
+{
+ ULONG j;
+ ULONG BlockBegin, BlockEnd, BiasedPage;
+
+ /* Loop the BIOS Memory Map */
+ for (j = 0; j < KeMemoryMapRangeCount; j++)
+ {
+ /* Get the start and end addresses */
+ BlockBegin = KeMemoryMap[j].BaseAddrLow;
+ BlockEnd = BlockBegin + KeMemoryMap[j].LengthLow - 1;
+
+ /* Make sure it wasn't a > 4GB descriptor */
+ if (!KeMemoryMap[j].BaseAddrHigh)
+ {
+ /* Make sure it doesn't overflow */
+ if (BlockEnd < BlockBegin) BlockEnd = 0xFFFFFFFF;
+
+ /* Check if this was free memory */
+ if (KeMemoryMap[j].Type == 1)
+ {
+ /* Get the page-aligned addresses */
+ BiasedPage = BlockBegin & (PAGE_SIZE - 1);
+ BlockBegin >>= PAGE_SHIFT;
+ if (BiasedPage) BlockBegin++;
+ BlockEnd = (BlockEnd >> PAGE_SHIFT) + 1;
+
+ /* Check if the block is within the 16MB memory hole */
+ if ((BlockBegin < 0xFC0) && (BlockEnd >= 0xFC0))
+ {
+ /* Don't allow it to cross this boundary */
+ BlockBegin = 0xFC0;
+ }
+
+ /* Check if the boundary is across 16MB */
+ if ((BlockEnd > 0xFFF) && (BlockBegin <= 0xFFF))
+ {
+ /* Don't let it cross */
+ BlockEnd = 0xFFF;
+ }
+
+ /* Check if the block describes the memory hole */
+ if ((BlockBegin >= 0xFC0) && (BlockEnd <= 0xFFF))
+ {
+ /* Set this region as temporary */
+ KiRosConfigureArcDescriptor(BlockBegin,
+ BlockEnd,
+ MemoryFirmwareTemporary);
+ }
+ }
+ else
+ {
+ /* Get the page-aligned addresses */
+ BlockBegin >>= PAGE_SHIFT;
+ BiasedPage = (BlockEnd + 1) & (PAGE_SIZE - 1);
+ BlockEnd >>= PAGE_SHIFT;
+ if (BiasedPage) BlockEnd++;
+
+ /* Set this memory as reserved */
+ KiRosConfigureArcDescriptor(BlockBegin,
+ BlockEnd + 1,
+ MemorySpecialMemory);
+ }
+ }
+ }
+}
+
+VOID
+NTAPI
+KiRosInsertNtDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
+{
+ PLIST_ENTRY ListHead, PreviousEntry, NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor = NULL, NextDescriptor = NULL;
+
+ /* Loop the memory descriptor list */
+ ListHead = &KeLoaderBlock->MemoryDescriptorListHead;
+ PreviousEntry = ListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current descriptor and check if it's below ours */
+ NextDescriptor = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+ if (NewDescriptor->BasePage < NextDescriptor->BasePage) break;
+
+ /* It isn't, save the previous entry and descriptor, and try again */
+ PreviousEntry = NextEntry;
+ Descriptor = NextDescriptor;
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* So we found the right spot to insert. Is this free memory? */
+ if (NewDescriptor->MemoryType != LoaderFree)
+ {
+ /* It isn't, so insert us before the last descriptor */
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+ else
+ {
+ /* We're free memory. Check if the entry we found is also free memory */
+ if ((PreviousEntry != ListHead) &&
+ ((Descriptor->MemoryType == LoaderFree) ||
+ (Descriptor->MemoryType == LoaderReserve)) &&
+ ((Descriptor->BasePage + Descriptor->PageCount) ==
+ NewDescriptor->BasePage))
+ {
+ /* It's free memory, and we're right after it. Enlarge that block */
+ Descriptor->PageCount += NewDescriptor->PageCount;
+ NewDescriptor = Descriptor;
+ }
+ else
+ {
+ /* Our range scan't be combined, so just insert us separately */
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+
+ /* Check if we merged with an existing free memory block */
+ if ((NextEntry != ListHead) &&
+ ((NextDescriptor->MemoryType == LoaderFree) ||
+ (NextDescriptor->MemoryType == LoaderReserve)) &&
+ ((NewDescriptor->BasePage + NewDescriptor->PageCount) ==
+ NextDescriptor->BasePage))
+ {
+ /* Update our own block */
+ NewDescriptor->PageCount += NextDescriptor->PageCount;
+
+ /* Remove the next block */
+ RemoveEntryList(&NextDescriptor->ListEntry);
+ }
+ }
+}
+
+NTSTATUS
+NTAPI
+KiRosBuildNtDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor,
+ IN MEMORY_TYPE MemoryType,
+ IN ULONG BasePage,
+ IN ULONG PageCount)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor, NextDescriptor = NULL;
+ LONG Delta;
+ TYPE_OF_MEMORY CurrentType;
+ BOOLEAN UseNext;
+
+ /* Check how many pages we'll be consuming */
+ Delta = BasePage - MemoryDescriptor->BasePage;
+ if (!(Delta) && (PageCount == MemoryDescriptor->PageCount))
+ {
+ /* We can simply convert the current descriptor into our new type */
+ MemoryDescriptor->MemoryType = MemoryType;
+ }
+ else
+ {
+ /* Get the current memory type of the descriptor, and reserve it */
+ CurrentType = MemoryDescriptor->MemoryType;
+ MemoryDescriptor->MemoryType = LoaderSpecialMemory;
+
+ /* Check if we'll need another descriptor for what's left of memory */
+ UseNext = ((BasePage != MemoryDescriptor->BasePage) &&
+ (Delta + PageCount != MemoryDescriptor->PageCount));
+
+ /* Get a descriptor */
+ Descriptor = KiRosGetMdFromArray();
+ if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Check if we are using another descriptor */
+ if (UseNext)
+ {
+ /* Allocate that one too */
+ NextDescriptor = KiRosGetMdFromArray();
+ if (!NextDescriptor) return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Build the descriptor we got */
+ Descriptor->MemoryType = MemoryType;
+ Descriptor->BasePage = BasePage;
+ Descriptor->PageCount = PageCount;
+
+ /* Check if we're starting at the same place as the old one */
+ if (BasePage == MemoryDescriptor->BasePage)
+ {
+ /* Simply decrease the old descriptor and rebase it */
+ MemoryDescriptor->BasePage += PageCount;
+ MemoryDescriptor->PageCount -= PageCount;
+ MemoryDescriptor->MemoryType = CurrentType;
+ }
+ else if (Delta + PageCount == MemoryDescriptor->PageCount)
+ {
+ /* We finish where the old one did, shorten it */
+ MemoryDescriptor->PageCount -= PageCount;
+ MemoryDescriptor->MemoryType = CurrentType;
+ }
+ else
+ {
+ /* We're inside the current block, mark our free region */
+ NextDescriptor->MemoryType = LoaderFree;
+ NextDescriptor->BasePage = BasePage + PageCount;
+ NextDescriptor->PageCount = MemoryDescriptor->PageCount -
+ (PageCount + Delta);
+
+ /* And cut down the current descriptor */
+ MemoryDescriptor->PageCount = Delta;
+ MemoryDescriptor->MemoryType = CurrentType;
+
+ /* Finally, insert our new free descriptor into the list */
+ KiRosInsertNtDescriptor(NextDescriptor);
+ }
+
+ /* Insert the descriptor we allocated */
+ KiRosInsertNtDescriptor(Descriptor);
+ }
+
+ /* Return success */
+ return STATUS_SUCCESS;
+}
+
+PMEMORY_ALLOCATION_DESCRIPTOR
+NTAPI
+KiRosFindNtDescriptor(IN ULONG BasePage)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock = NULL;
+ PLIST_ENTRY NextEntry, ListHead;
+
+ /* Scan the memory descriptor list */
+ ListHead = &KeLoaderBlock->MemoryDescriptorListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current descriptor */
+ MdBlock = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ /* Check if it can contain our memory range */
+ if ((MdBlock->BasePage <= BasePage) &&
+ (MdBlock->BasePage + MdBlock->PageCount > BasePage))
+ {
+ /* It can, break out */
+ break;
+ }
+
+ /* Go to the next descriptor */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Return the descriptor we found, if any */
+ return MdBlock;
+}
+
+NTSTATUS
+NTAPI
+KiRosAllocateNtDescriptor(IN TYPE_OF_MEMORY MemoryType,
+ IN ULONG BasePage,
+ IN ULONG PageCount,
+ IN ULONG Alignment,
+ OUT PULONG ReturnedBase)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+ ULONG AlignedBase, AlignedLimit;
+ PMEMORY_ALLOCATION_DESCRIPTOR ActiveMdBlock;
+ ULONG ActiveAlignedBase = 0;
+ PLIST_ENTRY NextEntry, ListHead;
+
+ /* If no information was given, make some assumptions */
+ if (!Alignment) Alignment = 1;
+ if (!PageCount) PageCount = 1;
+
+ /* Start looking for a matching descvriptor */
+ do
+ {
+ /* Calculate the limit of the range */
+ AlignedLimit = PageCount + BasePage;
+
+ /* Find a descriptor that already contains our base address */
+ MdBlock = KiRosFindNtDescriptor(BasePage);
+
+ if (MdBlock)
+ {
+ /* If it contains our limit as well, break out early */
+ if ((MdBlock->PageCount + MdBlock->BasePage) >= AlignedLimit) break;
+ }
+
+ /* Loop the memory list */
+ ActiveMdBlock = NULL;
+ ListHead = &KeLoaderBlock->MemoryDescriptorListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current descriptors */
+ MdBlock = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ /* Align the base address and our limit */
+ AlignedBase = (MdBlock->BasePage + (Alignment - 1)) &~ Alignment;
+ AlignedLimit = MdBlock->PageCount -
+ AlignedBase +
+ MdBlock->BasePage;
+
+ /* Check if this is a free block that can satisfy us */
+ if ((MdBlock->MemoryType == LoaderFree) &&
+ (AlignedLimit <= MdBlock->PageCount) &&
+ (PageCount <= AlignedLimit))
+ {
+ /* It is, stop searching */
+ ActiveMdBlock = MdBlock;
+ ActiveAlignedBase = AlignedBase;
+ break;
+ }
+
+ /* Try the next block */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* See if we came up with an adequate block */
+ if (ActiveMdBlock)
+ {
+ /* Generate a descriptor in it */
+ *ReturnedBase = AlignedBase;
+ return KiRosBuildNtDescriptor(ActiveMdBlock,
+ MemoryType,
+ ActiveAlignedBase,
+ PageCount);
+ }
+ } while (TRUE);
+
+ /* We found a matching block, generate a descriptor with it */
+ *ReturnedBase = BasePage;
+ return KiRosBuildNtDescriptor(MdBlock, MemoryType, BasePage, PageCount);
+}
+
+NTSTATUS
+NTAPI
+KiRosBuildArcMemoryList(VOID)
+{
+ PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
+ MEMORY_DESCRIPTOR *Memory;
+ ULONG i;
+
+ /* Loop all BIOS Memory Descriptors */
+ for (i = 0; i < NumberDescriptors; i++)
+ {
+ /* Get the current descriptor */
+ Memory = &MDArray[i];
+
+ /* Allocate an NT Memory Descriptor */
+ Descriptor = KiRosGetMdFromArray();
+ if (!Descriptor) return ENOMEM;
+
+ /* Copy the memory type */
+ Descriptor->MemoryType = Memory->MemoryType;
+ if (Memory->MemoryType == MemoryFreeContiguous)
+ {
+ /* Convert this to free */
+ Descriptor->MemoryType = LoaderFree;
+ }
+ else if (Memory->MemoryType == MemorySpecialMemory)
+ {
+ /* Convert this to special memory */
+ Descriptor->MemoryType = LoaderSpecialMemory;
+ }
+
+ /* Copy the range data */
+ Descriptor->BasePage = Memory->BasePage;
+ Descriptor->PageCount = Memory->PageCount;
+
+ /* Insert the descriptor */
+ if (Descriptor->PageCount) KiRosInsertNtDescriptor(Descriptor);
+ }
+
+ /* All went well */
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+KiRosFixupComponentTree(IN PCONFIGURATION_COMPONENT_DATA p,
+ IN ULONG_PTR i)
+{
+ PCONFIGURATION_COMPONENT pp;
+
+ /* Loop each entry */
+ while (p)
+ {
+ /* Grab the component entry */
+ pp = &p->ComponentEntry;
+
+ /* Fixup the pointers */
+ if (pp->Identifier) pp->Identifier = (PVOID)((ULONG_PTR)pp->Identifier + i);
+ if (p->ConfigurationData) p->ConfigurationData = (PVOID)((ULONG_PTR)p->ConfigurationData + i);
+ if (p->Parent) p->Parent = (PVOID)((ULONG_PTR)p->Parent + i);
+ if (p->Sibling) p->Sibling = (PVOID)((ULONG_PTR)p->Sibling + i);
+ if (p->Child) p->Child = (PVOID)((ULONG_PTR)p->Child + i);
+
+ /* Check if we have a child */
+ if (p->Child) KiRosFixupComponentTree(p->Child, i);
+
+ /* Get to the next entry */
+ p = p->Sibling;
+ }
+}
VOID
NTAPI
{
PLOADER_PARAMETER_BLOCK LoaderBlock;
PLDR_DATA_TABLE_ENTRY LdrEntry;
- PMEMORY_ALLOCATION_DESCRIPTOR MdEntry;
- PLOADER_MODULE RosEntry;
+ PLOADER_MODULE RosEntry = NULL;
ULONG i, j, ModSize;
PVOID ModStart;
PCHAR DriverName;
PCHAR BootPath, HalPath;
CHAR CommandLine[256];
+ PARC_DISK_SIGNATURE RosDiskInfo, ArcDiskInfo;
+ PIMAGE_NT_HEADERS NtHeader;
+ WCHAR PathToDrivers[] = L"\\SystemRoot\\System32\\drivers\\";
+ WCHAR PathToSystem32[] = L"\\SystemRoot\\System32\\";
+ WCHAR PathSetup[] = L"\\SystemRoot\\";
+ CHAR DriverNameLow[256];
+ ULONG Base;
+#ifdef _M_PPC
+ ULONG KernelBase = RosLoaderBlock->ModsAddr[0].ModStart;
+#endif
/* First get some kernel-loader globals */
AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
- MmFreeLdrMemHigher = RosLoaderBlock->MemHigher;
- MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd;
- KeLoaderModuleCount = RosLoaderBlock->ModsCount;
/* Set the NT Loader block and initialize it */
- *NtLoaderBlock = LoaderBlock = &BldrLoaderBlock;
+ *NtLoaderBlock = KeLoaderBlock = LoaderBlock = &BldrLoaderBlock;
RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
/* Set the NLS Data block */
LoaderBlock->NlsData = &BldrNlsDataBlock;
+ /* Set the ARC Data block */
+ LoaderBlock->ArcDiskInformation = &BldrArcDiskInfo;
+
/* Assume this is from FreeLDR's SetupLdr */
LoaderBlock->SetupLdrBlock = &BldrSetupBlock;
InitializeListHead(&LoaderBlock->LoadOrderListHead);
InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
InitializeListHead(&LoaderBlock->BootDriverListHead);
+ InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+
+ /* Build the free memory map, which uses BIOS Descriptors */
+ KiRosBuildBiosMemoryMap();
+
+ /* Build entries for ReactOS memory ranges, which uses ARC Descriptors */
+ KiRosBuildOsMemoryMap();
+
+#if defined(_M_IX86) || defined(_M_AMD64)
+ /* Build entries for the reserved map, which uses ARC Descriptors */
+ KiRosBuildReservedMemoryMap();
+#endif
+
+ /* Now convert the BIOS and ARC Descriptors into NT Memory Descirptors */
+ KiRosBuildArcMemoryList();
/* Loop boot driver list */
- for (i = 0; i < KeLoaderModuleCount; i++)
+ for (i = 0; i < RosLoaderBlock->ModsCount; i++)
{
/* Get the ROS loader entry */
- RosEntry = &KeLoaderModules[i];
+ RosEntry = &RosLoaderBlock->ModsAddr[i];
DriverName = (PCHAR)RosEntry->String;
ModStart = (PVOID)RosEntry->ModStart;
ModSize = RosEntry->ModEnd - (ULONG_PTR)ModStart;
+#ifdef _M_PPC
+ ModStart -= KernelBase;
+#endif
+
/* Check if this is any of the NLS files */
if (!_stricmp(DriverName, "ansi.nls"))
{
/* ANSI Code page */
- LoaderBlock->NlsData->AnsiCodePageData = ModStart;
+ LoaderBlock->NlsData->AnsiCodePageData = KERNEL_RVA(ModStart);
/* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderNlsData;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
+ KiRosAllocateNtDescriptor(LoaderNlsData,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
continue;
}
else if (!_stricmp(DriverName, "oem.nls"))
{
/* OEM Code page */
- LoaderBlock->NlsData->OemCodePageData = ModStart;
+ LoaderBlock->NlsData->OemCodePageData = KERNEL_RVA(ModStart);
/* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderNlsData;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
+ KiRosAllocateNtDescriptor(LoaderNlsData,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
continue;
}
else if (!_stricmp(DriverName, "casemap.nls"))
{
/* Unicode Code page */
- LoaderBlock->NlsData->UnicodeCodePageData = ModStart;
+ LoaderBlock->NlsData->UnicodeCodePageData = KERNEL_RVA(ModStart);
/* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderNlsData;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
+ KiRosAllocateNtDescriptor(LoaderNlsData,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
continue;
}
!(_stricmp(DriverName, "system.hiv")))
{
/* Save registry data */
- LoaderBlock->RegistryBase = ModStart;
+ LoaderBlock->RegistryBase = KERNEL_RVA(ModStart);
LoaderBlock->RegistryLength = ModSize;
/* Disable setup mode */
LoaderBlock->SetupLdrBlock = NULL;
/* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderRegistryData;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
+ KiRosAllocateNtDescriptor(LoaderRegistryData,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
continue;
}
!(_stricmp(DriverName, "hardware.hiv")))
{
/* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderRegistryData;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
+ KiRosAllocateNtDescriptor(LoaderRegistryData,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
continue;
}
+ /* Check if this is the kernel */
+ if (!(_stricmp(DriverName, "ntoskrnl.exe")))
+ {
+ /* Create an MD for it */
+ KiRosAllocateNtDescriptor(LoaderSystemCode,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
+ }
+ else if (!(_stricmp(DriverName, "hal.dll")))
+ {
+ /* Create an MD for the HAL */
+ KiRosAllocateNtDescriptor(LoaderHalCode,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
+ }
+ else
+ {
+ /* Create an MD for any driver */
+ KiRosAllocateNtDescriptor(LoaderBootDriver,
+ KERNEL_DESCRIPTOR_PAGE(ModStart),
+ (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
+ 0,
+ &Base);
+ }
+
+#ifdef _M_PPC
+ ModStart += 0x80800000;
+#endif
+
+ /* Lowercase the drivername so we can check its extension later */
+ strcpy(DriverNameLow, DriverName);
+ _strlwr(DriverNameLow);
+
/* Setup the loader entry */
LdrEntry = &BldrModules[i];
RtlZeroMemory(LdrEntry, sizeof(LDR_DATA_TABLE_ENTRY));
/* Setup driver name */
RtlInitUnicodeString(&LdrEntry->BaseDllName, BldrModuleStrings[i]);
- RtlInitUnicodeString(&LdrEntry->FullDllName, BldrModuleStrings[i]);
+
+ /* Construct a correct full name */
+ BldrModuleStringsFull[i][0] = 0;
+ LdrEntry->FullDllName.MaximumLength = 260 * sizeof(WCHAR);
+ LdrEntry->FullDllName.Length = 0;
+ LdrEntry->FullDllName.Buffer = BldrModuleStringsFull[i];
+
+ /* Guess the path */
+ if (LoaderBlock->SetupLdrBlock)
+ {
+ UNICODE_STRING TempString;
+ RtlInitUnicodeString(&TempString, PathSetup);
+ RtlAppendUnicodeStringToString(&LdrEntry->FullDllName, &TempString);
+ }
+ else if (strstr(DriverNameLow, ".dll") || strstr(DriverNameLow, ".exe"))
+ {
+ UNICODE_STRING TempString;
+ RtlInitUnicodeString(&TempString, PathToSystem32);
+ RtlAppendUnicodeStringToString(&LdrEntry->FullDllName, &TempString);
+ }
+ else /* .sys */
+ {
+ UNICODE_STRING TempString;
+ RtlInitUnicodeString(&TempString, PathToDrivers);
+ RtlAppendUnicodeStringToString(&LdrEntry->FullDllName, &TempString);
+ }
+
+ /* Append base name of the driver */
+ RtlAppendUnicodeStringToString(&LdrEntry->FullDllName, &LdrEntry->BaseDllName);
/* Copy data from Freeldr Module Entry */
LdrEntry->DllBase = ModStart;
LdrEntry->SizeOfImage = ModSize;
+ /* Copy additional data */
+ NtHeader = RtlImageNtHeader(ModStart);
+ LdrEntry->EntryPoint = RVA(ModStart,
+ NtHeader->
+ OptionalHeader.AddressOfEntryPoint);
+
/* Initialize other data */
LdrEntry->LoadCount = 1;
LdrEntry->Flags = LDRP_IMAGE_DLL |
/* Insert it into the loader block */
InsertTailList(&LoaderBlock->LoadOrderListHead,
&LdrEntry->InLoadOrderLinks);
-
- /* Check if this is the kernel */
- if (!(_stricmp(DriverName, "ntoskrnl.exe")))
- {
- /* Create an MD for it */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderSystemCode;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
- }
- else if (!(_stricmp(DriverName, "hal.dll")))
- {
- /* The HAL actually gets loaded somewhere else */
- ModStart = HalModuleObject.DllBase;
-
- /* Create an MD for the HAL */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderHalCode;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
- }
- else
- {
- /* Create an MD for any driver */
- MdEntry = &BldrMemoryDescriptors[i];
- MdEntry->MemoryType = LoaderBootDriver;
- MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
- MdEntry->PageCount = ModSize >> PAGE_SHIFT;
- InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
- &MdEntry->ListEntry);
- }
+ }
+
+ /* Now mark the remainder of the FreeLDR 6MB area as "in use" */
+ KiRosAllocateNtDescriptor(LoaderMemoryData,
+ KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
+ KERNEL_DESCRIPTOR_PAGE((RosLoaderBlock->KernelBase + 0x600000)) -
+ KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
+ 0,
+ &Base);
+
+ //
+ // Check if we have a ramdisk
+ //
+ if ((RosLoaderBlock->RdAddr) && (RosLoaderBlock->RdLength))
+ {
+ //
+ // Build a descriptor for it
+ //
+ KiRosAllocateNtDescriptor(LoaderXIPRom,
+ KERNEL_DESCRIPTOR_PAGE(RosLoaderBlock->RdAddr),
+ (RosLoaderBlock->RdLength + PAGE_SIZE - 1) >> PAGE_SHIFT,
+ 0,
+ &Base);
}
/* Setup command line */
LoaderBlock->LoadOptions = BldrCommandLine;
- strcpy(BldrCommandLine, KeLoaderCommandLine);
+ strcpy(BldrCommandLine, RosLoaderBlock->CommandLine);
/* Setup the extension block */
LoaderBlock->Extension = &BldrExtensionBlock;
LoaderBlock->Extension->MajorVersion = 5;
LoaderBlock->Extension->MinorVersion = 2;
+
+// FIXME FIXME FIXME NOW!!!!
+
+ /* FreeLDR hackllocates 1536 static pages for the initial boot images */
+ LoaderBlock->Extension->LoaderPagesSpanned = 1536 * PAGE_SIZE;
+
+ /* ReactOS always boots the kernel at 0x80800000 (just like NT 5.2) */
+ LoaderBlock->Extension->LoaderPagesSpanned += 0x80800000 - KSEG0_BASE;
+
+ /* Now convert to pages */
+ LoaderBlock->Extension->LoaderPagesSpanned /= PAGE_SIZE;
+
/* Now setup the setup block if we have one */
if (LoaderBlock->SetupLdrBlock)
{
/* All we'll setup right now is the flag for text-mode setup */
- LoaderBlock->SetupLdrBlock->Flags = 1;
+ LoaderBlock->SetupLdrBlock->Flags = SETUPLDR_TEXT_MODE;
}
/* Make a copy of the command line */
/* Parse it and change every slash to a space */
BootPath = LoaderBlock->LoadOptions;
do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++);
+
+ /* Now let's loop ARC disk information */
+ for (i = 0; i < RosLoaderBlock->DrivesCount; i++)
+ {
+ /* Get the ROS loader entry */
+ RosDiskInfo = &RosLoaderBlock->DrivesAddr[i];
+
+ /* Get the ARC structure */
+ ArcDiskInfo = &BldrDiskInfo[i];
+
+ /* Copy the data over */
+ ArcDiskInfo->Signature = RosDiskInfo->Signature;
+ ArcDiskInfo->CheckSum = RosDiskInfo->CheckSum;
+
+ /* Copy the ARC Name */
+ strcpy(BldrArcNames[i], RosDiskInfo->ArcName);
+ ArcDiskInfo->ArcName = BldrArcNames[i];
+
+ /* Insert into the list */
+ InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
+ &ArcDiskInfo->ListEntry);
+ }
+
+ /* Copy the ARC Hardware Tree */
+ RtlCopyMemory(BldrArcHwBuffer, (PVOID)RosLoaderBlock->ArchExtra, 16 * 1024);
+ LoaderBlock->ConfigurationRoot = (PVOID)BldrArcHwBuffer;
+
+ /* Apply fixups */
+ KiRosFixupComponentTree(LoaderBlock->ConfigurationRoot,
+ (ULONG_PTR)BldrArcHwBuffer -
+ RosLoaderBlock->ArchExtra);
}
+VOID
+NTAPI
+KiSetupSyscallHandler();
+
VOID
FASTCALL
KiRosPrepareForSystemStartup(IN ULONG Dummy,
IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
{
- ULONG i;
- ULONG size;
- ULONG StartKernelBase;
- ULONG HalBase;
- ULONG DriverBase;
- ULONG DriverSize;
PLOADER_PARAMETER_BLOCK NtLoaderBlock;
- CHAR* s;
-#ifdef _M_IX86
+ ULONG size, i = 0, *ent;
+#if defined(_M_IX86)
PKTSS Tss;
PKGDTENTRY TssEntry;
-#endif
-#ifdef _M_PPC
- {
- __asm__("ori 0,0,0");
- char *nk = "ntoskrnl is here";
- boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra;
- memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(PpcEarlybootInfo));
- PpcEarlybootInfo.dispFont = BootDigits;
- BootInfo = (struct _boot_infos_t *)&PpcEarlybootInfo;
- DrawNumber(BootInfo, 0x1234abcd, 10, 100);
- DrawNumber(BootInfo, (ULONG)nk, 10 , 150);
- DrawString(BootInfo, nk, 100, 150);
- __asm__("ori 0,0,0");
- }
-#endif
-#ifdef _M_IX86
/* Load the GDT and IDT */
- Ke386SetGlobalDescriptorTable(KiGdtDescriptor);
- Ke386SetInterruptDescriptorTable(KiIdtDescriptor);
+ Ke386SetGlobalDescriptorTable(*(PKDESCRIPTOR)&KiGdtDescriptor.Limit);
+ Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR)&KiIdtDescriptor.Limit);
/* Initialize the boot TSS */
Tss = &KiBootTss;
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
#endif
- DrawNumber(BootInfo, 0xb0071f03, 190, 90);
- DrawNumber(BootInfo, (ULONG)BootInfo, 190, 100);
+#if defined(_M_PPC)
+ // Zero bats. We might have residual bats set that will interfere with
+ // our mapping of ofwldr.
+ for (i = 0; i < 4; i++)
+ {
+ SetBat(i, 0, 0, 0); SetBat(i, 1, 0, 0);
+ }
+ KiSetupSyscallHandler();
+ DbgPrint("Kernel Power (%08x)\n", LoaderBlock);
+ DbgPrint("ArchExtra (%08x)!\n", LoaderBlock->ArchExtra);
+#endif
+
+ /* Save pointer to ROS Block */
+ KeRosLoaderBlock = LoaderBlock;
- /* Copy the Loader Block Data locally since Low-Memory will be wiped */
- memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK));
- memcpy(&KeLoaderModules[0],
- (PVOID)KeRosLoaderBlock.ModsAddr,
- sizeof(LOADER_MODULE) * KeRosLoaderBlock.ModsCount);
- KeRosLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
+ /* Get debugging function */
+ FrLdrDbgPrint = LoaderBlock->FrLdrDbgPrint;
- /* Check for BIOS memory map */
+ /* Save memory manager data */
KeMemoryMapRangeCount = 0;
- if (KeRosLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
+ if (LoaderBlock->Flags & MB_FLAGS_MMAP_INFO)
{
/* We have a memory map from the nice BIOS */
- size = *((PULONG)(KeRosLoaderBlock.MmapAddr - sizeof(ULONG)));
+ ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG))); // FIXME: this is ugly
+ size = *ent;
i = 0;
/* Map it until we run out of size */
- while (i < KeRosLoaderBlock.MmapLength)
+ while (i < LoaderBlock->MmapLength)
{
/* Copy into the Kernel Memory Map */
memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
- (PVOID)(KeRosLoaderBlock.MmapAddr + i),
+ (PVOID)(LoaderBlock->MmapAddr + i),
sizeof(ADDRESS_RANGE));
/* Increase Memory Map Count */
}
/* Save data */
- KeRosLoaderBlock.MmapLength = KeMemoryMapRangeCount *
- sizeof(ADDRESS_RANGE);
- KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+ LoaderBlock->MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
+ LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
}
else
{
/* Nothing from BIOS */
- KeRosLoaderBlock.MmapLength = 0;
- KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+ LoaderBlock->MmapLength = 0;
+ LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
}
- /* Save the Base Address */
- MmSystemRangeStart = (PVOID)KeRosLoaderBlock.KernelBase;
-
- /* Set the Command Line */
- strcpy(KeLoaderCommandLine, (PCHAR)LoaderBlock->CommandLine);
- KeRosLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
-
- /* Get the address of ntoskrnl in openfirmware memory */
- StartKernelBase = KeLoaderModules[0].ModStart;
-
- /* Create a block for each module */
- for (i = 0; i < KeRosLoaderBlock.ModsCount; i++)
- {
- /* Check if we have to copy the path or not */
- if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0)
- {
- strcpy(KeLoaderModuleStrings[i], s + 1);
- }
- else
- {
- strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
- }
-
-#ifdef _M_PPC
- if(i == 0) {
- DrawNumber(BootInfo, KeLoaderModules[i].ModStart, 10, 200);
- DrawNumber(BootInfo, KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart, 100, 200);
- DrawNumber(BootInfo, KeLoaderModules[i].ModEnd, 190, 200);
- DrawNumber(BootInfo, KeLoaderModules[i+1].ModStart, 10, 210);
- DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd - KeLoaderModules[i+1].ModStart, 100, 210);
- DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd, 190, 210);
- }
- KeLoaderModules[i].ModStart += KSEG0_BASE - StartKernelBase;
- KeLoaderModules[i].ModEnd += KSEG0_BASE - StartKernelBase;
-#else
- /* Substract the base Address in Physical Memory */
- KeLoaderModules[i].ModStart -= 0x200000;
-
- /* Add the Kernel Base Address in Virtual Memory */
- KeLoaderModules[i].ModStart += KSEG0_BASE;
-
- /* Substract the base Address in Physical Memory */
- KeLoaderModules[i].ModEnd -= 0x200000;
-
- /* Add the Kernel Base Address in Virtual Memory */
- KeLoaderModules[i].ModEnd += KSEG0_BASE;
-#endif
-
- /* Select the proper String */
- KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
- }
-
- /* Choose last module address as the final kernel address */
- MmFreeLdrLastKernelAddress =
- PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd);
-
-#ifndef _M_PPC
- /* Select the HAL Base */
- HalBase = KeLoaderModules[1].ModStart;
-
- /* Choose Driver Base */
- DriverBase = MmFreeLdrLastKernelAddress;
- LdrHalBase = (ULONG_PTR)DriverBase;
-#else
- HalBase = KeLoaderModules[1].ModStart;
- DriverBase = MmFreeLdrLastKernelAddress;
- LdrHalBase = KeLoaderModules[1].ModStart;
-#endif
-
- /* Initialize Module Management */
- LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart);
-
- /* Load HAL.DLL with the PE Loader */
- LdrSafePEProcessModule((PVOID)HalBase,
- (PVOID)DriverBase,
- (PVOID)KeLoaderModules[0].ModStart,
- &DriverSize);
-
- //
- //
- // HACK HACK HACK WHEN WILL YOU PEOPLE FIX FREELDR?!?!?!
- // FREELDR SENDS US AN ***INVALID*** HAL PE HEADER!!!
- // WE READ IT IN LdrInitModuleManagement ABOVE!!!
- // WE SET .SizeOfImage TO A *GARBAGE* VALUE!!!
- //
- // This dirty hack fixes it, and should make symbol lookup work too.
- //
- HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject.
- DllBase)->
- OptionalHeader.SizeOfImage;
-
- /* Increase the last kernel address with the size of HAL */
- MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize);
-
-#ifdef _M_IX86
- /* Now select the final beginning and ending Kernel Addresses */
- MmFreeLdrFirstKrnlPhysAddr = KeLoaderModules[0].ModStart -
- KSEG0_BASE + 0x200000;
- MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress -
- KSEG0_BASE + 0x200000;
-#endif
-
- /* Setup the IDT */
- KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP!
- KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL
-
- /* Load the Kernel with the PE Loader */
- LdrSafePEProcessModule((PVOID)KeLoaderModules[0].ModStart,
- (PVOID)KeLoaderModules[0].ModStart,
- (PVOID)DriverBase,
- &DriverSize);
+ /* Convert the loader block */
+ KiRosFrldrLpbToNtLpb(KeRosLoaderBlock, &NtLoaderBlock);
- /* Sets up the VDM Data */
-#ifdef _M_IX86
- NtEarlyInitVdm();
+#if defined(_M_PPC)
+ DbgPrint("Finished KiRosFrldrLpbToNtLpb\n");
#endif
- /* Convert the loader block */
- KiRosFrldrLpbToNtLpb(&KeRosLoaderBlock, &NtLoaderBlock);
-
/* Do general System Startup */
- KiSystemStartup(NtLoaderBlock);
+ KiSystemStartupReal(NtLoaderBlock);
}
/* EOF */