reactos/ntoskrnl/ke/freeldr.c

1415 lines
48 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/freeldr.c
* PURPOSE: FreeLDR Bootstrap Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#define NDEBUG
#include <debug.h>
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_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 Loader Data */
PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
ADDRESS_RANGE KeMemoryMap[64];
ULONG KeMemoryMapRangeCount;
/* 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 }, };
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_X86_)
/* The Boot TSS */
KTSS KiBootTss;
/* Old boot style IDT */
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
KIDTENTRY KiBootIdt[256];
/* The Boot GDT */
KGDTENTRY KiBootGdt[256] =
{
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_NULL */
{0xffff, 0x0000, {{0x00, 0x9b, 0xcf, 0x00}}}, /* KGDT_R0_CODE */
{0xffff, 0x0000, {{0x00, 0x93, 0xcf, 0x00}}}, /* KGDT_R0_DATA */
{0xffff, 0x0000, {{0x00, 0xfb, 0xcf, 0x00}}}, /* KGDT_R3_CODE */
{0xffff, 0x0000, {{0x00, 0xf3, 0xcf, 0x00}}}, /* KGDT_R3_DATA*/
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_TSS */
{0x0001, 0xf000, {{0xdf, 0x93, 0xc0, 0xff}}}, /* KGDT_R0_PCR */
{0x0fff, 0x0000, {{0x00, 0xf3, 0x40, 0x00}}}, /* KGDT_R3_TEB */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_UNUSED */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_LDT */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_DF_TSS */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}} /* KGDT_NMI_TSS */
};
/* GDT Descriptor */
KDESCRIPTOR KiGdtDescriptor = {0, sizeof(KiBootGdt) - 1, (ULONG)KiBootGdt};
#endif
/* 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;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_X86_)
/* 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
/* 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;
}
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_X86_)
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);
}
}
}
}
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#endif
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 */
ARM Port Memory Management Checkpoint: - Implemented and defined the MMU-OS architecture for the ARM port. The details are too long for a commit message, but we have decided to replicate the x86 NT memory manager layout. We've defined a PTE_BASE at 0xC0000000 just like on x86, and we use a PDE_BASE at 0xC1000000. Unlike the x86, we can't use PDE-PTE self-mapping because ARM has different formats (and sizes!) for PDE vs PTEs! We emulate the behavior however (which adds a small performance hit) and the Mm porting is thus at least 10 times easier. - Moved serial port to 0xE0000000 for now. - We now parse the board memory map from u-boot. - Added memory allocation code to FreeLDR -- we now build a full ARC memory map for the kernel. - FreeLDR allocates page tables and sets up the initial support for our memory layout (see comments for some lengthier explenations) - Allocations made by FreeLDR for loading ReactOS are now made from a "shared heap" page that's also marked in the memory map. - Registry and NLS data are now being put into the loader block. - We now create a loader entry for the kernel (but not anything else -- we'll have to parse the list properly later). - Defined correct _HARDWARE_PTE_ARM and _MMPTE_HARDWARE for ARM. - ARM_COARSE_PAGE_TABLE is now 4KB instead of 1KB, going against the architecture! We do this for proper OS support of the PTE_BASE. - Fixed build due to KiSystemStartulReal change. - Fixed a bug on the x86 build when creating memory allocation descriptors. Memory corruption could occur in certain scenarios. - Implemented significant portions of the ARM memory manager code in the kernel: - MmGetPageDirectory. - MmDeletePageTable (for the kernel address space only). - MmIsPagePresent (for the kernel address space only). - MmCreateVirtualMappingForKernel. - MmCreateVirtualMapping (calls MmCreateVirtualMappingUnsafe). - MmCreateVirtualMappingUnsafe (for the kernel address space only). - MmSetPageProtect (unused on ARM). - MmCreateHyperspaceMapping. - MmDeleteHyperspaceMapping. - MmInitGlobalKernelPageDirectory. - MmInitPageDirectoryMap. - With the above, this means we now go well inside MmInit1: the PFN database is setup and works, memory areas are functional, and non-paged pool is fully working. - We currently hit a data abort during paged pool setup -- this is to be expected, since we don't have any exception handlers yet. These are coming up next -- we have to start handling crashes (and page faults). svn path=/trunk/; revision=32640
2008-03-10 17:27:14 +00:00
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 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
KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
IN PLOADER_PARAMETER_BLOCK *NtLoaderBlock)
{
PLOADER_PARAMETER_BLOCK LoaderBlock;
PLDR_DATA_TABLE_ENTRY LdrEntry;
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;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_PPC_)
ULONG KernelBase = RosLoaderBlock->ModsAddr[0].ModStart;
#endif
/* Set the NT Loader block and initialize it */
*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;
/* Setup the list heads */
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();
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_X86_)
/* 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 < RosLoaderBlock->ModsCount; i++)
{
/* Get the ROS loader entry */
RosEntry = &RosLoaderBlock->ModsAddr[i];
DriverName = (PCHAR)RosEntry->String;
ModStart = (PVOID)RosEntry->ModStart;
ModSize = RosEntry->ModEnd - (ULONG_PTR)ModStart;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_PPC_)
ModStart -= KernelBase;
#endif
/* Check if this is any of the NLS files */
if (!_stricmp(DriverName, "ansi.nls"))
{
/* ANSI Code page */
LoaderBlock->NlsData->AnsiCodePageData = KERNEL_RVA(ModStart);
/* Create an MD for it */
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 = KERNEL_RVA(ModStart);
/* Create an MD for it */
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 = KERNEL_RVA(ModStart);
/* Create an MD for it */
KiRosAllocateNtDescriptor(LoaderNlsData,
KERNEL_DESCRIPTOR_PAGE(ModStart),
(ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
0,
&Base);
continue;
}
/* Check if this is the SYSTEM hive */
if (!(_stricmp(DriverName, "system")) ||
!(_stricmp(DriverName, "system.hiv")))
{
/* Save registry data */
LoaderBlock->RegistryBase = KERNEL_RVA(ModStart);
LoaderBlock->RegistryLength = ModSize;
/* Disable setup mode */
LoaderBlock->SetupLdrBlock = NULL;
/* Create an MD for it */
KiRosAllocateNtDescriptor(LoaderRegistryData,
KERNEL_DESCRIPTOR_PAGE(ModStart),
(ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT,
0,
&Base);
continue;
}
/* Check if this is the HARDWARE hive */
if (!(_stricmp(DriverName, "hardware")) ||
!(_stricmp(DriverName, "hardware.hiv")))
{
/* Create an MD for it */
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);
}
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_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));
/* Convert driver name from ANSI to Unicode */
for (j = 0; j < strlen(DriverName); j++)
{
BldrModuleStrings[i][j] = DriverName[j];
}
/* Setup driver name */
RtlInitUnicodeString(&LdrEntry->BaseDllName, 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 |
LDRP_ENTRY_PROCESSED;
if (RosEntry->Reserved) LdrEntry->Flags |= LDRP_ENTRY_INSERTED;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
/* Check if this is HAL */
if (!(_stricmp(DriverName, "hal.dll")))
{
/* Check if there is a second entry already */
if (LoaderBlock->LoadOrderListHead.Flink->Flink !=
&LoaderBlock->LoadOrderListHead)
{
PLIST_ENTRY OldSecondEntry;
/* Get the second entry */
OldSecondEntry =
LoaderBlock->LoadOrderListHead.Flink->Flink;
/* Set up our entry correctly */
LdrEntry->InLoadOrderLinks.Flink = OldSecondEntry;
LdrEntry->InLoadOrderLinks.Blink = OldSecondEntry->Blink;
/* Make the first entry (always the kernel) point to us */
LoaderBlock->LoadOrderListHead.Flink->Flink =
&LdrEntry->InLoadOrderLinks;
/* Make the old entry point back to us and continue looping */
OldSecondEntry->Blink = &LdrEntry->InLoadOrderLinks;
continue;
}
}
/* Insert it into the loader block */
InsertTailList(&LoaderBlock->LoadOrderListHead,
&LdrEntry->InLoadOrderLinks);
}
/* Now mark the remainder of the FreeLDR 6MB area as "in use" */
KiRosAllocateNtDescriptor(LoaderMemoryData,
KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
KERNEL_DESCRIPTOR_PAGE((0x80800000 + 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, RosLoaderBlock->CommandLine);
/* Setup the extension block */
LoaderBlock->Extension = &BldrExtensionBlock;
LoaderBlock->Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
LoaderBlock->Extension->MajorVersion = 5;
LoaderBlock->Extension->MinorVersion = 2;
/* 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;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
/* Check if FreeLdr detected a ACPI table */
if (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE)
{
/* Set the pointer to something for compatibility */
LoaderBlock->Extension->AcpiTable = (PVOID)1;
}
/* 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 = SETUPLDR_TEXT_MODE;
}
/* Make a copy of the command line */
strcpy(CommandLine, LoaderBlock->LoadOptions);
/* Find the first \, separating the ARC path from NT path */
BootPath = strchr(CommandLine, '\\');
*BootPath = ANSI_NULL;
strncpy(BldrArcBootPath, CommandLine, 63);
LoaderBlock->ArcBootDeviceName = BldrArcBootPath;
/* The rest of the string is the NT path */
HalPath = strchr(BootPath + 1, ' ');
*HalPath = ANSI_NULL;
BldrNtBootPath[0] = '\\';
strncat(BldrNtBootPath, BootPath + 1, 63);
strcat(BldrNtBootPath,"\\");
LoaderBlock->NtBootPathName = BldrNtBootPath;
/* Set the HAL paths */
strncpy(BldrArcHalPath, BldrArcBootPath, 63);
LoaderBlock->ArcHalDeviceName = BldrArcHalPath;
strcpy(BldrNtHalPath, "\\");
LoaderBlock->NtHalPathName = BldrNtHalPath;
/* Use this new command line */
strncpy(LoaderBlock->LoadOptions, HalPath + 2, 255);
/* 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
NTAPI
KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
{
PLOADER_PARAMETER_BLOCK NtLoaderBlock;
ULONG size, i = 0, *ent;
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
#if defined(_X86_)
PKTSS Tss;
PKGDTENTRY TssEntry;
KDESCRIPTOR IdtDescriptor;
__sidt(&IdtDescriptor.Limit);
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
RtlCopyMemory(KiBootIdt, (PVOID)IdtDescriptor.Base, IdtDescriptor.Limit + 1);
IdtDescriptor.Base = (ULONG)&KiBootIdt;
IdtDescriptor.Limit = sizeof(KiBootIdt) - 1;
/* Load the GDT and IDT */
Ke386SetGlobalDescriptorTable(&KiGdtDescriptor.Limit);
__lidt(&IdtDescriptor.Limit);
/* Initialize the boot TSS */
Tss = &KiBootTss;
TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)];
TssEntry->HighWord.Bits.Type = I386_TSS;
TssEntry->HighWord.Bits.Pres = 1;
TssEntry->HighWord.Bits.Dpl = 0;
TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
/* Set the TSS selector */
Ke386SetTr(KGDT_TSS);
#endif
#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;
/* Save memory manager data */
KeMemoryMapRangeCount = 0;
if (LoaderBlock->Flags & MB_FLAGS_MMAP_INFO)
{
/* We have a memory map from the nice BIOS */
ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG)));
size = *ent;
i = 0;
/* Map it until we run out of size */
while (i < LoaderBlock->MmapLength)
{
/* Copy into the Kernel Memory Map */
memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
(PVOID)(LoaderBlock->MmapAddr + i),
sizeof(ADDRESS_RANGE));
/* Increase Memory Map Count */
KeMemoryMapRangeCount++;
/* Increase Size */
i += size;
}
/* Save data */
LoaderBlock->MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
}
else
{
/* Nothing from BIOS */
LoaderBlock->MmapLength = 0;
LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
}
/* Convert the loader block */
KiRosFrldrLpbToNtLpb(KeRosLoaderBlock, &NtLoaderBlock);
#if defined(_M_PPC)
DbgPrint("Finished KiRosFrldrLpbToNtLpb\n");
#endif
/* Do general System Startup */
KiSystemStartup(NtLoaderBlock);
}