mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 20:36:26 +00:00
- Do not ignore BIOS memory map anymore. Private BIOS ranges (such as ACPI, SMBIOS, VideoROM, etc) are not assumed "free" anymore (which would result in hardware failure, crashes and/or corrupted memory).
- Enhance the FreeLDR 2 NTLDR Compatibility Layer: * Use a special routine for grabbing static memory descriptors, so that if we ever run out, we will bugcheck. * The descriptors need to contain physical addresses, not virtual. Do proper fixups to handle this. * Add a "Free" memory descriptor for all memory on the system. This needs to be fragmented later. * Add memory descriptors for each reserved entry in the BIOS memory map. * Add memory descriptors for the PDE and KPCR pages that FreeLDR allocates. * Add a memory descriptor for page 0, which is reserved. * Add a memory descriptor for the Video frame buffer at 0xA0000. This is the location on most systems, and also the location that ReactOS hard-codes in other Mm code. - Bug found and NTLDR memory descriptor analysis by Alex. svn path=/trunk/; revision=28537
This commit is contained in:
parent
9ec7d785cb
commit
37ae229f62
4 changed files with 178 additions and 19 deletions
|
@ -599,7 +599,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
|||
if (LoaderBlock.MmapLength)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
|
||||
LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
|
||||
reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
|
||||
for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
|
||||
|
|
|
@ -23,6 +23,12 @@ ULONG MmFreeLdrPageDirectoryEnd;
|
|||
/* FreeLDR Loader Data */
|
||||
PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
|
||||
BOOLEAN AcpiTableDetected;
|
||||
ADDRESS_RANGE KeMemoryMap[64];
|
||||
ULONG KeMemoryMapRangeCount;
|
||||
|
||||
/* NT Loader Module/Descriptor Count */
|
||||
ULONG BldrCurrentMd;
|
||||
ULONG BldrCurrentMod;
|
||||
|
||||
/* NT Loader Data. Eats up about 80KB! */
|
||||
LOADER_PARAMETER_BLOCK BldrLoaderBlock; // 0x0000
|
||||
|
@ -45,6 +51,15 @@ ARC_DISK_SIGNATURE BldrDiskInfo[32]; // 0x1413C
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR
|
||||
NTAPI
|
||||
KiRosGetMdFromArray(VOID)
|
||||
{
|
||||
/* Return the next MD from the list, but make sure we don't overflow */
|
||||
if (BldrCurrentMd > 64) KEBUGCHECK(0);
|
||||
return &BldrMemoryDescriptors[BldrCurrentMd++];
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
||||
|
@ -69,6 +84,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
|
||||
MmFreeLdrMemHigher = RosLoaderBlock->MemHigher;
|
||||
MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd;
|
||||
if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000;
|
||||
|
||||
/* Set the NT Loader block and initialize it */
|
||||
*NtLoaderBlock = LoaderBlock = &BldrLoaderBlock;
|
||||
|
@ -89,6 +105,64 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
InitializeListHead(&LoaderBlock->BootDriverListHead);
|
||||
InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
|
||||
|
||||
/* Create one large blob of free memory */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderFree;
|
||||
MdEntry->BasePage = 0;
|
||||
MdEntry->PageCount = MmFreeLdrMemHigher / 4;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry);
|
||||
|
||||
/*
|
||||
* FIXME: Instead of just "inserting" MDs into the list,
|
||||
* we need to make then be "consumed" from the Free Descriptor.
|
||||
* This will happen soon (and also ensure a sorted list).
|
||||
*/
|
||||
|
||||
/* Loop the BIOS Memory Map */
|
||||
for (j = 0; j < KeMemoryMapRangeCount; j++)
|
||||
{
|
||||
/* Check if this is a reserved entry */
|
||||
if (KeMemoryMap[j].Type == 2)
|
||||
{
|
||||
/* It is, build an entry for it */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderSpecialMemory;
|
||||
MdEntry->BasePage = KeMemoryMap[j].BaseAddrLow >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (KeMemoryMap[j].LengthLow + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/* Page 0 is reserved: build an entry for it */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderFirmwarePermanent;
|
||||
MdEntry->BasePage = 0;
|
||||
MdEntry->PageCount = 1;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry);
|
||||
|
||||
/* Build an entry for the KPCR (which we put in page 1) */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderMemoryData;
|
||||
MdEntry->BasePage = 1;
|
||||
MdEntry->PageCount = 1;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry);
|
||||
|
||||
/* Build an entry for the PDE */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderMemoryData;
|
||||
MdEntry->BasePage = (ULONG_PTR)MmGetPageDirectory() >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (MmFreeLdrPageDirectoryEnd -
|
||||
(ULONG_PTR)MmGetPageDirectory()) / PAGE_SIZE;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry);
|
||||
|
||||
/* Mark Video ROM as reserved */
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderFirmwarePermanent;
|
||||
MdEntry->BasePage = 0xA0000 >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (0xE8000 - 0xA0000) / PAGE_SIZE;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry);
|
||||
|
||||
/* Loop boot driver list */
|
||||
for (i = 0; i < RosLoaderBlock->ModsCount; i++)
|
||||
{
|
||||
|
@ -106,9 +180,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
LoaderBlock->NlsData->AnsiCodePageData = ModStart;
|
||||
|
||||
/* Create an MD for it */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderNlsData;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -121,9 +195,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
LoaderBlock->NlsData->OemCodePageData = ModStart;
|
||||
|
||||
/* Create an MD for it */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderNlsData;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -136,9 +210,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
LoaderBlock->NlsData->UnicodeCodePageData = ModStart;
|
||||
|
||||
/* Create an MD for it */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderNlsData;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -158,9 +232,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
LoaderBlock->SetupLdrBlock = NULL;
|
||||
|
||||
/* Create an MD for it */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderRegistryData;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -173,9 +247,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
{
|
||||
/* Create an MD for it */
|
||||
ModStart = RVA(ModStart, KSEG0_BASE);
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderRegistryData;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -186,9 +260,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
if (!(_stricmp(DriverName, "ntoskrnl.exe")))
|
||||
{
|
||||
/* Create an MD for it */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderSystemCode;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -196,9 +270,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
else if (!(_stricmp(DriverName, "hal.dll")))
|
||||
{
|
||||
/* Create an MD for the HAL */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderHalCode;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -206,9 +280,9 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
|||
else
|
||||
{
|
||||
/* Create an MD for any driver */
|
||||
MdEntry = &BldrMemoryDescriptors[i];
|
||||
MdEntry = KiRosGetMdFromArray();
|
||||
MdEntry->MemoryType = LoaderBootDriver;
|
||||
MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT;
|
||||
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
|
||||
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
|
||||
&MdEntry->ListEntry);
|
||||
|
@ -356,6 +430,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
|||
IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
PLOADER_PARAMETER_BLOCK NtLoaderBlock;
|
||||
ULONG size, i;
|
||||
#if defined(_M_IX86)
|
||||
PKTSS Tss;
|
||||
PKGDTENTRY TssEntry;
|
||||
|
@ -387,6 +462,39 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
|||
KSEG0_BASE;
|
||||
MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - KSEG0_BASE;
|
||||
|
||||
KeMemoryMapRangeCount = 0;
|
||||
if (LoaderBlock->Flags & MB_FLAGS_MMAP_INFO)
|
||||
{
|
||||
/* We have a memory map from the nice BIOS */
|
||||
size = *((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG)));
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86)
|
||||
/* Set up the VDM Data */
|
||||
NtEarlyInitVdm();
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
KSPIN_LOCK KiFreezeExecutionLock;
|
||||
KSPIN_LOCK Ki486CompatibilityLock;
|
||||
|
||||
/* BIOS Memory Map. Not NTLDR-compliant yet */
|
||||
extern ULONG KeMemoryMapRangeCount;
|
||||
extern ADDRESS_RANGE KeMemoryMap[64];
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
|
@ -536,8 +540,8 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
|||
MmInit1(MmFreeLdrFirstKrnlPhysAddr,
|
||||
MmFreeLdrLastKrnlPhysAddr,
|
||||
MmFreeLdrLastKernelAddress,
|
||||
NULL,
|
||||
0,
|
||||
KeMemoryMap,
|
||||
KeMemoryMapRangeCount,
|
||||
4096);
|
||||
|
||||
/* Set basic CPU Features that user mode can read */
|
||||
|
|
|
@ -301,6 +301,34 @@ MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
|
|||
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
||||
}
|
||||
|
||||
PCHAR
|
||||
MemType[] = {
|
||||
"ExceptionBlock ", // ?
|
||||
"SystemBlock ", // ?
|
||||
"Free ",
|
||||
"Bad ", // used
|
||||
"LoadedProgram ", // == Free
|
||||
"FirmwareTemporary ", // == Free
|
||||
"FirmwarePermanent ", // == Bad
|
||||
"OsloaderHeap ", // used
|
||||
"OsloaderStack ", // == Free
|
||||
"SystemCode ",
|
||||
"HalCode ",
|
||||
"BootDriver ", // not used
|
||||
"ConsoleInDriver ", // ?
|
||||
"ConsoleOutDriver ", // ?
|
||||
"StartupDpcStack ", // ?
|
||||
"StartupKernelStack", // ?
|
||||
"StartupPanicStack ", // ?
|
||||
"StartupPcrPage ", // ?
|
||||
"StartupPdrPage ", // ?
|
||||
"RegistryData ", // used
|
||||
"MemoryData ", // not used
|
||||
"NlsData ", // used
|
||||
"SpecialMemory ", // == Bad
|
||||
"BBTMemory " // == Bad
|
||||
};
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
|
@ -324,6 +352,25 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
|
|||
LastKrnlPhysAddr,
|
||||
LastKernelAddress);
|
||||
|
||||
/* Dump memory descriptors */
|
||||
{
|
||||
PLIST_ENTRY NextEntry;
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR Md;
|
||||
ULONG TotalPages = 0;
|
||||
|
||||
DPRINT1("Base\t\tLength\t\tType\n");
|
||||
for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
|
||||
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
|
||||
NextEntry = NextEntry->Flink)
|
||||
{
|
||||
Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
|
||||
DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
|
||||
TotalPages += Md->PageCount;
|
||||
}
|
||||
|
||||
DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
|
||||
}
|
||||
|
||||
/* Set the page directory */
|
||||
PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue