mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 00:50:23 +00:00
Remove MachGetMemoryMap() and replace it by ArcGetMemoryDescriptor(). Rework memory initialization to use it.
As a bonus, we're not limited anymore to 32 memory descriptors, and having more than 4GB of RAM doesn't lead to out of bounds accesses svn path=/trunk/; revision=40710
This commit is contained in:
parent
5ce8637a17
commit
54a86cf16f
9 changed files with 337 additions and 354 deletions
|
@ -1,130 +1,5 @@
|
||||||
/*
|
/* No need to duplicate code ; import the i386 version */
|
||||||
* FreeLoader
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Eric Kohl
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <freeldr.h>
|
#include "../i386/hwacpi.c"
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
BOOLEAN AcpiPresent = FALSE;
|
|
||||||
|
|
||||||
static PRSDP_DESCRIPTOR
|
|
||||||
FindAcpiBios(VOID)
|
|
||||||
{
|
|
||||||
PUCHAR Ptr;
|
|
||||||
|
|
||||||
/* Find the 'Root System Descriptor Table Pointer' */
|
|
||||||
Ptr = (PUCHAR)0xE0000;
|
|
||||||
while ((ULONG_PTR)Ptr < 0x100000)
|
|
||||||
{
|
|
||||||
if (!memcmp(Ptr, "RSD PTR ", 8))
|
|
||||||
{
|
|
||||||
DbgPrint((DPRINT_HWDETECT, "ACPI supported\n"));
|
|
||||||
|
|
||||||
return (PRSDP_DESCRIPTOR)Ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ptr = (PUCHAR)((ULONG_PTR)Ptr + 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgPrint((DPRINT_HWDETECT, "ACPI not supported\n"));
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
|
||||||
{
|
|
||||||
PCONFIGURATION_COMPONENT_DATA BiosKey;
|
|
||||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
|
||||||
PRSDP_DESCRIPTOR Rsdp;
|
|
||||||
PACPI_BIOS_DATA AcpiBiosData;
|
|
||||||
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
|
||||||
ULONG BiosMemoryMapEntryCount, TableSize;
|
|
||||||
|
|
||||||
Rsdp = FindAcpiBios();
|
|
||||||
|
|
||||||
if (Rsdp)
|
|
||||||
{
|
|
||||||
/* Set up the flag in the loader block */
|
|
||||||
AcpiPresent = TRUE;
|
|
||||||
LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
|
|
||||||
|
|
||||||
/* Create new bus key */
|
|
||||||
FldrCreateComponentKey(SystemKey,
|
|
||||||
L"MultifunctionAdapter",
|
|
||||||
*BusNumber,
|
|
||||||
AdapterClass,
|
|
||||||
MultiFunctionAdapter,
|
|
||||||
&BiosKey);
|
|
||||||
|
|
||||||
/* Set 'Component Information' */
|
|
||||||
FldrSetComponentInformation(BiosKey,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
|
|
||||||
/* Get BIOS memory map */
|
|
||||||
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
|
||||||
BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap,
|
|
||||||
sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
|
|
||||||
|
|
||||||
/* Calculate the table size */
|
|
||||||
TableSize = BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP) +
|
|
||||||
sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP);
|
|
||||||
|
|
||||||
/* Set 'Configuration Data' value */
|
|
||||||
PartialResourceList =
|
|
||||||
MmHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
|
|
||||||
memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
|
|
||||||
PartialResourceList->Version = 0;
|
|
||||||
PartialResourceList->Revision = 0;
|
|
||||||
PartialResourceList->Count = 1;
|
|
||||||
|
|
||||||
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
|
|
||||||
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
|
|
||||||
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
|
|
||||||
PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize;
|
|
||||||
|
|
||||||
/* Fill the table */
|
|
||||||
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
|
|
||||||
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
|
|
||||||
AcpiBiosData->Count = BiosMemoryMapEntryCount;
|
|
||||||
memcpy(AcpiBiosData->MemoryMap, BiosMemoryMap,
|
|
||||||
BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP));
|
|
||||||
|
|
||||||
DbgPrint((DPRINT_HWDETECT, "RSDT %p, data size %x\n", Rsdp->rsdt_physical_address,
|
|
||||||
TableSize));
|
|
||||||
|
|
||||||
FldrSetConfigurationData(BiosKey,
|
|
||||||
PartialResourceList,
|
|
||||||
sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Increment bus number */
|
|
||||||
(*BusNumber)++;
|
|
||||||
|
|
||||||
/* Set 'Identifier' value */
|
|
||||||
FldrSetIdentifier(BiosKey, "ACPI BIOS");
|
|
||||||
MmFreeMemory(PartialResourceList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -83,7 +83,7 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
||||||
|
|
||||||
/* Get BIOS memory map */
|
/* Get BIOS memory map */
|
||||||
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
||||||
BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap,
|
BiosMemoryMapEntryCount = PcMemGetMemoryMap(BiosMemoryMap,
|
||||||
sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
|
sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
|
||||||
|
|
||||||
/* Calculate the table size */
|
/* Calculate the table size */
|
||||||
|
|
|
@ -59,6 +59,7 @@ typedef struct tagMACHVTBL
|
||||||
VOID (*Beep)(VOID);
|
VOID (*Beep)(VOID);
|
||||||
VOID (*PrepareForReactOS)(IN BOOLEAN Setup);
|
VOID (*PrepareForReactOS)(IN BOOLEAN Setup);
|
||||||
|
|
||||||
|
MEMORY_DESCRIPTOR* (*GetMemoryDescriptor)(MEMORY_DESCRIPTOR* Current);
|
||||||
ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
|
ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
|
||||||
|
|
||||||
BOOLEAN (*DiskGetBootVolume)(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
|
BOOLEAN (*DiskGetBootVolume)(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
|
||||||
|
@ -98,7 +99,7 @@ VOID MachVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
|
||||||
VOID MachVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue);
|
VOID MachVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue);
|
||||||
VOID MachVideoSync(VOID);
|
VOID MachVideoSync(VOID);
|
||||||
VOID MachBeep(VOID);
|
VOID MachBeep(VOID);
|
||||||
ULONG MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
|
MEMORY_DESCRIPTOR* ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current);
|
||||||
BOOLEAN MachDiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
|
BOOLEAN MachDiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MachDiskGetSystemVolume(char *SystemPath,
|
MachDiskGetSystemVolume(char *SystemPath,
|
||||||
|
@ -138,7 +139,6 @@ VOID MachPrepareForReactOS(IN BOOLEAN Setup);
|
||||||
#define MachVideoSync() MachVtbl.VideoSync()
|
#define MachVideoSync() MachVtbl.VideoSync()
|
||||||
#define MachBeep() MachVtbl.Beep()
|
#define MachBeep() MachVtbl.Beep()
|
||||||
#define MachPrepareForReactOS(a) MachVtbl.PrepareForReactOS(a)
|
#define MachPrepareForReactOS(a) MachVtbl.PrepareForReactOS(a)
|
||||||
#define MachGetMemoryMap(MMap, Size) MachVtbl.GetMemoryMap((MMap), (Size))
|
|
||||||
#define MachDiskGetBootVolume(Drv, Start, Cnt, FsType) MachVtbl.DiskGetBootVolume((Drv), (Start), (Cnt), (FsType))
|
#define MachDiskGetBootVolume(Drv, Start, Cnt, FsType) MachVtbl.DiskGetBootVolume((Drv), (Start), (Cnt), (FsType))
|
||||||
#define MachDiskGetSystemVolume(SysPath, RemPath, Dev, Drv, Start, Cnt, FsType) MachVtbl.DiskGetSystemVolume((SysPath), (RemPath), (Dev), (Drv), (Start), (Cnt), (FsType))
|
#define MachDiskGetSystemVolume(SysPath, RemPath, Dev, Drv, Start, Cnt, FsType) MachVtbl.DiskGetSystemVolume((SysPath), (RemPath), (Dev), (Drv), (Start), (Cnt), (FsType))
|
||||||
#define MachDiskGetBootPath(Path, Size) MachVtbl.DiskGetBootPath((Path), (Size))
|
#define MachDiskGetBootPath(Path, Size) MachVtbl.DiskGetBootPath((Path), (Size))
|
||||||
|
|
|
@ -88,21 +88,18 @@ extern ULONG FreePagesInLookupTable;
|
||||||
extern ULONG LastFreePageHint;
|
extern ULONG LastFreePageHint;
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type);
|
PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ULONG MmGetPageNumberFromAddress(PVOID Address); // Returns the page number that contains a linear address
|
ULONG MmGetPageNumberFromAddress(PVOID Address); // Returns the page number that contains a linear address
|
||||||
PVOID MmGetEndAddressOfAnyMemory(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Returns the last address of memory from the memory map
|
ULONG MmGetAddressablePageCountIncludingHoles(VOID); // Returns the count of addressable pages from address zero including any memory holes and reserved memory regions
|
||||||
ULONG MmGetAddressablePageCountIncludingHoles(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Returns the count of addressable pages from address zero including any memory holes and reserved memory regions
|
PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount); // Returns the address for a memory chunk big enough to hold the page lookup table (starts search from end of memory)
|
||||||
PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Returns the address for a memory chunk big enough to hold the page lookup table (starts search from end of memory)
|
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Inits the page lookup table according to the memory types in the memory map
|
||||||
VOID MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Sorts the BIOS_MEMORY_MAP array so the first element corresponds to the first address in memory
|
|
||||||
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Inits the page lookup table according to the memory types in the memory map
|
|
||||||
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated); // Marks the specified pages as allocated or free in the lookup table
|
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated); // Marks the specified pages as allocated or free in the lookup table
|
||||||
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType); // Allocates the specified pages in the lookup table
|
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType); // Allocates the specified pages in the lookup table
|
||||||
ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table
|
ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table
|
||||||
ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd); // Returns the page number of the first available page range from the beginning or end of memory
|
ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd); // Returns the page number of the first available page range from the beginning or end of memory
|
||||||
ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage); // Returns the page number of the first available page range before the specified page
|
ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage); // Returns the page number of the first available page range before the specified page
|
||||||
VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount); // Removes entries in the memory map that describe memory above 4G
|
|
||||||
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount); // Sets the LastFreePageHint to the last usable page of memory
|
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount); // Sets the LastFreePageHint to the last usable page of memory
|
||||||
BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount); // Returns TRUE if the specified pages of memory are available, otherwise FALSE
|
BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount); // Returns TRUE if the specified pages of memory are available, otherwise FALSE
|
||||||
VOID MmSetMemoryType(PVOID MemoryAddress, ULONG MemorySize, TYPE_OF_MEMORY NewType); // Use with EXTREME caution!
|
VOID MmSetMemoryType(PVOID MemoryAddress, ULONG MemorySize, TYPE_OF_MEMORY NewType); // Use with EXTREME caution!
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#undef MachVideoSync
|
#undef MachVideoSync
|
||||||
#undef MachBeep
|
#undef MachBeep
|
||||||
#undef MachPrepareForReactOS
|
#undef MachPrepareForReactOS
|
||||||
#undef MachGetMemoryMap
|
|
||||||
#undef MachDiskGetBootVolume
|
#undef MachDiskGetBootVolume
|
||||||
#undef MachDiskGetSystemVolume
|
#undef MachDiskGetSystemVolume
|
||||||
#undef MachDiskGetBootPath
|
#undef MachDiskGetBootPath
|
||||||
|
@ -153,10 +152,176 @@ MachPrepareForReactOS(IN BOOLEAN Setup)
|
||||||
MachVtbl.PrepareForReactOS(Setup);
|
MachVtbl.PrepareForReactOS(Setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
typedef struct
|
||||||
MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
|
|
||||||
{
|
{
|
||||||
return MachVtbl.GetMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
|
MEMORY_DESCRIPTOR m;
|
||||||
|
ULONG Index;
|
||||||
|
BOOLEAN GeneratedDescriptor;
|
||||||
|
} MEMORY_DESCRIPTOR_INT;
|
||||||
|
static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
|
||||||
|
{
|
||||||
|
#if defined (__i386__) || defined (_M_AMD64)
|
||||||
|
{ { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
|
||||||
|
{ { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
|
||||||
|
{ { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
|
||||||
|
{ { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
|
||||||
|
{ { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
|
||||||
|
{ { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
|
||||||
|
{ { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
|
||||||
|
{ { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
|
||||||
|
#elif __arm__
|
||||||
|
{ { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // arm exception handlers
|
||||||
|
{ { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // arm board block + freeldr stack + cmdline
|
||||||
|
{ { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
MEMORY_DESCRIPTOR*
|
||||||
|
ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current)
|
||||||
|
{
|
||||||
|
MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
|
||||||
|
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
||||||
|
static ULONG BiosMemoryMapEntryCount;
|
||||||
|
static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
|
||||||
|
static BOOLEAN MemoryMapInitialized = FALSE;
|
||||||
|
ULONG i, j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Does machine provide an override for this function?
|
||||||
|
//
|
||||||
|
if (MachVtbl.GetMemoryDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Yes. Use it instead
|
||||||
|
//
|
||||||
|
return MachVtbl.GetMemoryDescriptor(Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it is the first time we're called
|
||||||
|
//
|
||||||
|
if (!MemoryMapInitialized)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Get the machine generated memory map
|
||||||
|
//
|
||||||
|
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
||||||
|
BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
|
||||||
|
sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the entries to our structure
|
||||||
|
//
|
||||||
|
for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Is it suitable memory?
|
||||||
|
//
|
||||||
|
if (BiosMemoryMap[i].Type != BiosMemoryUsable)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No. Process next descriptor
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy this memory descriptor
|
||||||
|
//
|
||||||
|
BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
|
||||||
|
BiosMemoryDescriptors[j].m.BasePage = BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE;
|
||||||
|
BiosMemoryDescriptors[j].m.PageCount = BiosMemoryMap[i].Length / MM_PAGE_SIZE;
|
||||||
|
BiosMemoryDescriptors[j].Index = j;
|
||||||
|
BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remember how much descriptors we found
|
||||||
|
//
|
||||||
|
BiosMemoryMapEntryCount = j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mark memory map as already retrieved and initialized
|
||||||
|
//
|
||||||
|
MemoryMapInitialized = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
|
||||||
|
|
||||||
|
if (Current == NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// First descriptor requested
|
||||||
|
//
|
||||||
|
if (BiosMemoryMapEntryCount > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first generated memory descriptor
|
||||||
|
//
|
||||||
|
return &BiosMemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else if (sizeof(MemoryDescriptors) > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first fixed memory descriptor
|
||||||
|
//
|
||||||
|
return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Strange case, we have no memory descriptor
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CurrentDescriptor->GeneratedDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Current entry is a generated descriptor
|
||||||
|
//
|
||||||
|
if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return next generated descriptor
|
||||||
|
//
|
||||||
|
return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
||||||
|
}
|
||||||
|
else if (sizeof(MemoryDescriptors) > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first fixed memory descriptor
|
||||||
|
//
|
||||||
|
return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No fixed memory descriptor; end of memory map
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Current entry is a fixed descriptor
|
||||||
|
//
|
||||||
|
if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return next fixed descriptor
|
||||||
|
//
|
||||||
|
return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No more fixed memory descriptor; end of memory map
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeLoader
|
* FreeLoader
|
||||||
* Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org>
|
* Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org>
|
||||||
|
* Copyright (C) 2006-2009 Hervé Poussineau <hpoussin@reactos.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,19 +24,24 @@
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Type;
|
MEMORY_TYPE Type;
|
||||||
UCHAR TypeString[20];
|
PCSTR TypeString;
|
||||||
} FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE;
|
} FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE;
|
||||||
|
|
||||||
ULONG MemoryTypeCount = 5;
|
|
||||||
FREELDR_MEMORY_TYPE MemoryTypeArray[] =
|
FREELDR_MEMORY_TYPE MemoryTypeArray[] =
|
||||||
{
|
{
|
||||||
{ 0, "Unknown Memory" },
|
{ MemoryMaximum, "Unknown memory" },
|
||||||
{ BiosMemoryUsable, "Usable Memory" },
|
{ MemoryExceptionBlock, "Exception block" },
|
||||||
{ BiosMemoryReserved, "Reserved Memory" },
|
{ MemorySystemBlock, "System block" },
|
||||||
{ BiosMemoryAcpiReclaim, "ACPI Reclaim Memory" },
|
{ MemoryFree, "Free memory" },
|
||||||
{ BiosMemoryAcpiNvs, "ACPI NVS Memory" },
|
{ MemoryBad, "Bad memory" },
|
||||||
|
{ MemoryLoadedProgram, "Loaded program" },
|
||||||
|
{ MemoryFirmwareTemporary, "Firmware temporary" },
|
||||||
|
{ MemoryFirmwarePermanent, "Firmware permanent" },
|
||||||
|
{ MemoryFreeContiguous, "Free contiguous memory" },
|
||||||
|
{ MemorySpecialMemory, "Special memory" },
|
||||||
};
|
};
|
||||||
|
ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PVOID PageLookupTableAddress = NULL;
|
PVOID PageLookupTableAddress = NULL;
|
||||||
|
@ -48,39 +54,27 @@ extern ULONG_PTR MmHeapStart;
|
||||||
|
|
||||||
BOOLEAN MmInitializeMemoryManager(VOID)
|
BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
{
|
{
|
||||||
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
|
||||||
ULONG BiosMemoryMapEntryCount;
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
ULONG Index;
|
MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "Initializing Memory Manager.\n");
|
DPRINTM(DPRINT_MEMORY, "Initializing Memory Manager.\n");
|
||||||
|
|
||||||
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
|
||||||
|
|
||||||
BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap, sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
|
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
// Dump the system memory map
|
// Dump the system memory map
|
||||||
if (BiosMemoryMapEntryCount != 0)
|
|
||||||
{
|
|
||||||
DPRINTM(DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n");
|
DPRINTM(DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n");
|
||||||
for (Index=0; Index<BiosMemoryMapEntryCount; Index++)
|
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
||||||
{
|
{
|
||||||
DPRINTM(DPRINT_MEMORY, "%x%x\t %x%x\t %s\n", BiosMemoryMap[Index].BaseAddress, BiosMemoryMap[Index].Length, MmGetSystemMemoryMapTypeString(BiosMemoryMap[Index].Type));
|
DPRINTM(DPRINT_MEMORY, "%x\t %x\t %s\n",
|
||||||
}
|
MemoryDescriptor->BasePage * MM_PAGE_SIZE,
|
||||||
|
MemoryDescriptor->PageCount * MM_PAGE_SIZE,
|
||||||
|
MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we got the system memory map then fixup invalid entries
|
|
||||||
if (BiosMemoryMapEntryCount != 0)
|
|
||||||
{
|
|
||||||
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find address for the page lookup table
|
// Find address for the page lookup table
|
||||||
TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, BiosMemoryMapEntryCount);
|
TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles();
|
||||||
PageLookupTableAddress = MmFindLocationForPageLookupTable(BiosMemoryMap, BiosMemoryMapEntryCount);
|
PageLookupTableAddress = MmFindLocationForPageLookupTable(TotalPagesInLookupTable);
|
||||||
LastFreePageHint = TotalPagesInLookupTable;
|
LastFreePageHint = TotalPagesInLookupTable;
|
||||||
|
|
||||||
if (PageLookupTableAddress == 0)
|
if (PageLookupTableAddress == 0)
|
||||||
|
@ -93,25 +87,9 @@ BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the page lookup table
|
// Initialize the page lookup table
|
||||||
MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable, BiosMemoryMap, BiosMemoryMapEntryCount);
|
MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
|
||||||
MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
|
MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
|
||||||
|
|
||||||
// Add machine-dependent stuff
|
|
||||||
#if defined (__i386__) || defined (_M_AMD64)
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // realmode int vectors
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // freeldr stack + cmdline
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages)
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x78, 8, LoaderOsloaderStack); // prot mode stack. BIOSCALLBUFFER
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x80, 0x10, LoaderOsloaderHeap); // File system read buffer. FILESYSBUFFER
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x90, 0x10, LoaderOsloaderHeap); // Disk read buffer for int 13h. DISKREADBUFFER
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0xA0, 0x60, LoaderFirmwarePermanent); // ROM / Video
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0xFFF, 1, LoaderSpecialMemory); // unusable memory
|
|
||||||
#elif __arm__
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // arm exception handlers
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // arm board block + freeldr stack + cmdline
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
|
FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
|
||||||
|
|
||||||
MmInitializeHeap(PageLookupTableAddress);
|
MmInitializeHeap(PageLookupTableAddress);
|
||||||
|
@ -151,7 +129,7 @@ VOID MmInitializeHeap(PVOID PageLookupTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type)
|
PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
|
||||||
{
|
{
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
|
@ -172,90 +150,92 @@ ULONG MmGetPageNumberFromAddress(PVOID Address)
|
||||||
return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
|
return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID MmGetEndAddressOfAnyMemory(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
|
ULONG MmGetAddressablePageCountIncludingHoles(VOID)
|
||||||
{
|
{
|
||||||
ULONGLONG MaxStartAddressSoFar;
|
MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
||||||
ULONGLONG EndAddressOfMemory;
|
ULONG EndPage = 0;
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
MaxStartAddressSoFar = 0;
|
//
|
||||||
EndAddressOfMemory = 0;
|
// Go through the whole memory map to get max address
|
||||||
for (Index=0; Index<MapCount; Index++)
|
//
|
||||||
|
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
||||||
{
|
{
|
||||||
if (MaxStartAddressSoFar <= BiosMemoryMap[Index].BaseAddress)
|
//
|
||||||
|
// Check if we got a higher end page address
|
||||||
|
//
|
||||||
|
if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > EndPage)
|
||||||
{
|
{
|
||||||
MaxStartAddressSoFar = BiosMemoryMap[Index].BaseAddress;
|
//
|
||||||
EndAddressOfMemory = (MaxStartAddressSoFar + BiosMemoryMap[Index].Length);
|
// Yes, remember it
|
||||||
if (EndAddressOfMemory > 0xFFFFFFFF)
|
//
|
||||||
{
|
EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
|
||||||
EndAddressOfMemory = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returning 0x%x\n", (ULONG)EndAddressOfMemory);
|
DPRINTM(DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", EndPage);
|
||||||
|
|
||||||
return (PVOID)(ULONG_PTR)EndAddressOfMemory;
|
return EndPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG MmGetAddressablePageCountIncludingHoles(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
|
PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
|
||||||
{
|
{
|
||||||
ULONG PageCount;
|
MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
||||||
ULONGLONG EndAddress;
|
|
||||||
|
|
||||||
EndAddress = (ULONGLONG)(ULONG_PTR)MmGetEndAddressOfAnyMemory(BiosMemoryMap, MapCount);
|
|
||||||
|
|
||||||
// Since MmGetEndAddressOfAnyMemory() won't
|
|
||||||
// return addresses higher than 0xFFFFFFFF
|
|
||||||
// then we need to adjust the end address
|
|
||||||
// to 0x100000000 so we don't get an
|
|
||||||
// off-by-one error
|
|
||||||
if (EndAddress >= 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
EndAddress = 0x100000000LL;
|
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returned 0xFFFFFFFF, correcting to be 0x100000000.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
PageCount = (EndAddress / MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning %d\n", PageCount);
|
|
||||||
|
|
||||||
return PageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
|
|
||||||
{
|
|
||||||
ULONG TotalPageCount;
|
|
||||||
ULONG PageLookupTableSize;
|
ULONG PageLookupTableSize;
|
||||||
PVOID PageLookupTableMemAddress;
|
ULONG PageLookupTablePages;
|
||||||
int Index;
|
ULONG PageLookupTableStartPage = 0;
|
||||||
BIOS_MEMORY_MAP TempBiosMemoryMap[32];
|
PVOID PageLookupTableMemAddress = NULL;
|
||||||
|
|
||||||
TotalPageCount = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, MapCount);
|
//
|
||||||
|
// Calculate how much pages we need to keep the page lookup table
|
||||||
|
//
|
||||||
PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
|
PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
|
||||||
PageLookupTableMemAddress = 0;
|
PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;
|
||||||
|
|
||||||
RtlCopyMemory(TempBiosMemoryMap, BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
//
|
||||||
MmSortBiosMemoryMap(TempBiosMemoryMap, MapCount);
|
// Search the highest memory block big enough to contain lookup table
|
||||||
|
//
|
||||||
// Find a place, starting from the highest memory
|
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
||||||
// (thus leaving low memory for kernel/drivers)
|
|
||||||
for (Index=(MapCount-1); Index>=0; Index--)
|
|
||||||
{
|
{
|
||||||
// If this is usable memory with a big enough length
|
//
|
||||||
// then we'll put our page lookup table here
|
// Is it suitable memory?
|
||||||
|
//
|
||||||
// skip if this is not usable region
|
if (MemoryDescriptor->MemoryType != MemoryFree)
|
||||||
if (TempBiosMemoryMap[Index].Type != BiosMemoryUsable)
|
{
|
||||||
|
//
|
||||||
|
// No. Process next descriptor
|
||||||
|
//
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TempBiosMemoryMap[Index].Length >= PageLookupTableSize)
|
|
||||||
{
|
|
||||||
PageLookupTableMemAddress = (PVOID)(ULONG_PTR)
|
|
||||||
(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is the block big enough?
|
||||||
|
//
|
||||||
|
if (MemoryDescriptor->PageCount < PageLookupTablePages)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No. Process next descriptor
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is it at a higher address than previous suitable address?
|
||||||
|
//
|
||||||
|
if (MemoryDescriptor->BasePage < PageLookupTableStartPage)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No. Process next descriptor
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Memory block is more suitable than the previous one
|
||||||
|
//
|
||||||
|
PageLookupTableStartPage = MemoryDescriptor->BasePage;
|
||||||
|
PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
|
||||||
|
(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
|
||||||
|
- PageLookupTableSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
|
DPRINTM(DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
|
||||||
|
@ -263,70 +243,60 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map
|
||||||
return PageLookupTableMemAddress;
|
return PageLookupTableMemAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
|
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
|
||||||
{
|
{
|
||||||
ULONG Index;
|
MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
||||||
ULONG LoopCount;
|
TYPE_OF_MEMORY MemoryMapPageAllocated;
|
||||||
BIOS_MEMORY_MAP TempMapItem;
|
|
||||||
|
|
||||||
// Loop once for each entry in the memory map minus one
|
|
||||||
// On each loop iteration go through and sort the memory map
|
|
||||||
for (LoopCount=0; LoopCount<(MapCount-1); LoopCount++)
|
|
||||||
{
|
|
||||||
for (Index=0; Index<(MapCount-1); Index++)
|
|
||||||
{
|
|
||||||
if (BiosMemoryMap[Index].BaseAddress > BiosMemoryMap[Index+1].BaseAddress)
|
|
||||||
{
|
|
||||||
TempMapItem = BiosMemoryMap[Index];
|
|
||||||
BiosMemoryMap[Index] = BiosMemoryMap[Index+1];
|
|
||||||
BiosMemoryMap[Index+1] = TempMapItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
|
|
||||||
{
|
|
||||||
ULONG MemoryMapStartPage;
|
|
||||||
ULONG MemoryMapEndPage;
|
|
||||||
ULONG MemoryMapPageCount;
|
|
||||||
ULONG MemoryMapPageAllocated;
|
|
||||||
ULONG PageLookupTableStartPage;
|
ULONG PageLookupTableStartPage;
|
||||||
ULONG PageLookupTablePageCount;
|
ULONG PageLookupTablePageCount;
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
DPRINTM(DPRINT_MEMORY, "MmInitPageLookupTable()\n");
|
DPRINTM(DPRINT_MEMORY, "MmInitPageLookupTable()\n");
|
||||||
|
|
||||||
|
//
|
||||||
// Mark every page as allocated initially
|
// Mark every page as allocated initially
|
||||||
// We will go through and mark pages again according to the memory map
|
// We will go through and mark pages again according to the memory map
|
||||||
// But this will mark any holes not described in the map as allocated
|
// But this will mark any holes not described in the map as allocated
|
||||||
|
//
|
||||||
MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent);
|
MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent);
|
||||||
|
|
||||||
for (Index=0; Index<MapCount; Index++)
|
//
|
||||||
|
// Parse the whole memory map
|
||||||
|
//
|
||||||
|
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
||||||
{
|
{
|
||||||
MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)(ULONG_PTR)BiosMemoryMap[Index].BaseAddress);
|
//
|
||||||
MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(ULONG_PTR)(BiosMemoryMap[Index].BaseAddress + BiosMemoryMap[Index].Length - 1));
|
// Convert ARC memory type to loader memory type
|
||||||
MemoryMapPageCount = (MemoryMapEndPage - MemoryMapStartPage) + 1;
|
//
|
||||||
|
switch (MemoryDescriptor->MemoryType)
|
||||||
switch (BiosMemoryMap[Index].Type)
|
|
||||||
{
|
{
|
||||||
case BiosMemoryUsable:
|
case MemoryFree:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Allocatable memory
|
||||||
|
//
|
||||||
MemoryMapPageAllocated = LoaderFree;
|
MemoryMapPageAllocated = LoaderFree;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case BiosMemoryAcpiReclaim:
|
default:
|
||||||
case BiosMemoryAcpiNvs:
|
{
|
||||||
|
//
|
||||||
|
// Put something sensible here, which won't be overwritten
|
||||||
|
//
|
||||||
MemoryMapPageAllocated = LoaderSpecialMemory;
|
MemoryMapPageAllocated = LoaderSpecialMemory;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
MemoryMapPageAllocated = LoaderSpecialMemory;
|
|
||||||
}
|
}
|
||||||
DPRINTM(DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryMapStartPage, MemoryMapPageCount);
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTable, MemoryMapStartPage, MemoryMapPageCount, MemoryMapPageAllocated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mark used pages in the lookup table
|
||||||
|
//
|
||||||
|
DPRINTM(DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount);
|
||||||
|
MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryMapPageAllocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// Mark the pages that the lookup table occupies as reserved
|
// Mark the pages that the lookup table occupies as reserved
|
||||||
|
//
|
||||||
PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
|
PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
|
||||||
PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
|
PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
|
||||||
DPRINTM(DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
|
DPRINTM(DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
|
||||||
|
@ -474,30 +444,6 @@ ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
|
|
||||||
{
|
|
||||||
UINT32 Index;
|
|
||||||
UINT32 Index2;
|
|
||||||
|
|
||||||
// Loop through each entry in the array
|
|
||||||
for (Index=0; Index<*MapCount; Index++)
|
|
||||||
{
|
|
||||||
// If the entry type isn't usable then remove
|
|
||||||
// it from the memory map (this will help reduce
|
|
||||||
// the size of our lookup table)
|
|
||||||
if (BiosMemoryMap[Index].Type != BiosMemoryUsable)
|
|
||||||
{
|
|
||||||
// Slide every entry after this down one
|
|
||||||
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
|
|
||||||
{
|
|
||||||
BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
|
|
||||||
}
|
|
||||||
(*MapCount)--;
|
|
||||||
Index--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
|
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
|
||||||
{
|
{
|
||||||
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
|
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
|
||||||
|
|
|
@ -642,7 +642,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||||
LoaderBlock.DrivesAddr = reactos_arc_disk_info;
|
LoaderBlock.DrivesAddr = reactos_arc_disk_info;
|
||||||
LoaderBlock.RdAddr = (ULONG_PTR)gRamDiskBase;
|
LoaderBlock.RdAddr = (ULONG_PTR)gRamDiskBase;
|
||||||
LoaderBlock.RdLength = gRamDiskSize;
|
LoaderBlock.RdLength = gRamDiskSize;
|
||||||
LoaderBlock.MmapLength = (SIZE_T)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
LoaderBlock.MmapLength = (SIZE_T)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
||||||
if (LoaderBlock.MmapLength)
|
if (LoaderBlock.MmapLength)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
|
@ -72,7 +72,7 @@ VOID LoadReactOSSetup(VOID)
|
||||||
LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
|
LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
|
||||||
LoaderBlock.ModsCount = 0;
|
LoaderBlock.ModsCount = 0;
|
||||||
LoaderBlock.ModsAddr = reactos_modules;
|
LoaderBlock.ModsAddr = reactos_modules;
|
||||||
LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
LoaderBlock.MmapLength = (unsigned long)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
||||||
if (LoaderBlock.MmapLength)
|
if (LoaderBlock.MmapLength)
|
||||||
{
|
{
|
||||||
#if defined (_M_IX86) || defined (_M_AMD64)
|
#if defined (_M_IX86) || defined (_M_AMD64)
|
||||||
|
|
|
@ -269,7 +269,7 @@ WinLdrLoadImage(IN PCHAR FileName,
|
||||||
CHAR ProgressString[256];
|
CHAR ProgressString[256];
|
||||||
|
|
||||||
/* Inform user we are loading files */
|
/* Inform user we are loading files */
|
||||||
sprintf(ProgressString, "Loading %s...", FileName);
|
sprintf(ProgressString, "Loading %s...", strchr(FileName, '\\') + 1);
|
||||||
UiDrawProgressBarCenter(1, 100, ProgressString);
|
UiDrawProgressBarCenter(1, 100, ProgressString);
|
||||||
|
|
||||||
/* Open the image file */
|
/* Open the image file */
|
||||||
|
|
Loading…
Reference in a new issue