mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:15:52 +00:00
[FREELDR]
Make the DiskReadBuffer location and size dynamic. Should fix a number of issues with non-standard BIOSes. Many thanks to jeditobe for his help with testing/debugging of this issue. CORE-8899 #resolve CORE-9031 #resolve svn path=/trunk/; revision=66087
This commit is contained in:
parent
273593de7e
commit
63ae430acc
14 changed files with 376 additions and 225 deletions
|
@ -7,6 +7,7 @@
|
|||
* Timo Kreuzer
|
||||
*/
|
||||
|
||||
#define DISKREADBUFFER HEX(8E000)
|
||||
|
||||
/*
|
||||
* Layout of a FAT volume:
|
||||
|
|
|
@ -307,10 +307,10 @@ DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
|||
{
|
||||
NodeNumber = (UCHAR)i;
|
||||
|
||||
x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER);
|
||||
x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
|
||||
if (x == 0)
|
||||
{
|
||||
DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
|
||||
DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
|
||||
|
||||
TRACE("Node: %u Size %u (0x%x)\n",
|
||||
DeviceNode->Node,
|
||||
|
|
|
@ -42,6 +42,8 @@ extern CHAR reactos_arc_strings[32][256];
|
|||
static CHAR Hex[] = "0123456789abcdef";
|
||||
UCHAR PcBiosDiskCount = 0;
|
||||
CHAR PcDiskIdentifier[32][20];
|
||||
PVOID DiskReadBuffer;
|
||||
SIZE_T DiskReadBufferSize;
|
||||
|
||||
|
||||
static ARC_STATUS DiskClose(ULONG FileId)
|
||||
|
@ -119,7 +121,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
|||
ULONGLONG SectorOffset;
|
||||
|
||||
TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
|
||||
MaxSectors = PcDiskReadBufferSize / Context->SectorSize;
|
||||
MaxSectors = DiskReadBufferSize / Context->SectorSize;
|
||||
SectorOffset = Context->SectorNumber + Context->SectorOffset;
|
||||
|
||||
ret = 1;
|
||||
|
@ -134,7 +136,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
|||
Context->DriveNumber,
|
||||
SectorOffset,
|
||||
ReadSectors,
|
||||
(PVOID)DISKREADBUFFER);
|
||||
DiskReadBuffer);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
|
@ -142,7 +144,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
|||
if (Length > N)
|
||||
Length = N;
|
||||
|
||||
RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
|
||||
RtlCopyMemory(Ptr, DiskReadBuffer, Length);
|
||||
|
||||
Ptr += Length;
|
||||
N -= Length;
|
||||
|
@ -197,14 +199,14 @@ GetHarddiskInformation(
|
|||
PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80];
|
||||
|
||||
/* Read the MBR */
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||
{
|
||||
ERR("Reading MBR failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Buffer = (ULONG*)DISKREADBUFFER;
|
||||
Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
|
||||
Buffer = (ULONG*)DiskReadBuffer;
|
||||
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
|
||||
|
||||
Signature = Mbr->Signature;
|
||||
TRACE("Signature: %x\n", Signature);
|
||||
|
@ -288,13 +290,13 @@ HwInitializeBiosDisks(VOID)
|
|||
* harddisks. So, we set the buffer to known contents first, then try to
|
||||
* read. If the BIOS reports success but the buffer contents haven't
|
||||
* changed then we fail anyway */
|
||||
memset((PVOID) DISKREADBUFFER, 0xcd, 512);
|
||||
while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
||||
memset(DiskReadBuffer, 0xcd, 512);
|
||||
while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||
{
|
||||
Changed = FALSE;
|
||||
for (i = 0; ! Changed && i < 512; i++)
|
||||
{
|
||||
Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
|
||||
Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
|
||||
}
|
||||
if (! Changed)
|
||||
{
|
||||
|
@ -310,7 +312,7 @@ HwInitializeBiosDisks(VOID)
|
|||
|
||||
DiskCount++;
|
||||
DriveNumber++;
|
||||
memset((PVOID) DISKREADBUFFER, 0xcd, 512);
|
||||
memset(DiskReadBuffer, 0xcd, 512);
|
||||
}
|
||||
DiskReportError(TRUE);
|
||||
|
||||
|
@ -326,13 +328,13 @@ HwInitializeBiosDisks(VOID)
|
|||
ULONG Checksum = 0;
|
||||
|
||||
/* Read the MBR */
|
||||
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))
|
||||
{
|
||||
ERR("Reading MBR failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Buffer = (ULONG*)DISKREADBUFFER;
|
||||
Buffer = (ULONG*)DiskReadBuffer;
|
||||
|
||||
/* Calculate the MBR checksum */
|
||||
for (i = 0; i < 2048 / sizeof(ULONG); i++) Checksum += Buffer[i];
|
||||
|
|
|
@ -29,32 +29,11 @@ DBG_DEFAULT_CHANNEL(MEMORY);
|
|||
|
||||
#define MAX_BIOS_DESCRIPTORS 32
|
||||
|
||||
#define STACK_BASE_PAGE (STACKLOW / PAGE_SIZE)
|
||||
#define FREELDR_BASE_PAGE (FREELDR_BASE / PAGE_SIZE)
|
||||
#define DISKBUF_BASE_PAGE (DISKREADBUFFER / PAGE_SIZE)
|
||||
|
||||
#define STACK_PAGE_COUNT (FREELDR_BASE_PAGE - STACK_BASE_PAGE)
|
||||
#define FREELDR_PAGE_COUNT (DISKBUF_BASE_PAGE - FREELDR_BASE_PAGE)
|
||||
#define DISKBUF_PAGE_COUNT (0x10)
|
||||
#define BIOSBUF_PAGE_COUNT (1)
|
||||
|
||||
BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS];
|
||||
ULONG PcBiosMapCount;
|
||||
ULONG PcDiskReadBufferSize;
|
||||
|
||||
FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] =
|
||||
{
|
||||
{ LoaderFirmwarePermanent, 0x00, 1 }, // realmode int vectors
|
||||
{ LoaderFirmwareTemporary, 0x01, STACK_BASE_PAGE - 1 }, // freeldr stack, cmdline, BIOS call buffer
|
||||
{ LoaderOsloaderStack, STACK_BASE_PAGE, FREELDR_BASE_PAGE - STACK_BASE_PAGE }, // prot mode stack.
|
||||
{ LoaderLoadedProgram, FREELDR_BASE_PAGE, FREELDR_PAGE_COUNT }, // freeldr image
|
||||
{ LoaderFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER
|
||||
{ LoaderFirmwarePermanent, 0x9F, 0x1 }, // EBDA
|
||||
{ LoaderFirmwarePermanent, 0xA0, 0x50 }, // ROM / Video
|
||||
{ LoaderSpecialMemory, 0xF0, 0x10 }, // ROM / Video
|
||||
{ LoaderSpecialMemory, 0xFFF, 1 }, // unusable memory
|
||||
{ 0, 0, 0 }, // end of map
|
||||
};
|
||||
FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1];
|
||||
ULONG PcMapCount;
|
||||
|
||||
ULONG
|
||||
AddMemoryDescriptor(
|
||||
|
@ -186,38 +165,12 @@ PcMemGetConventionalMemorySize(VOID)
|
|||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
|
||||
BOOLEAN
|
||||
GetEbdaLocation(
|
||||
PULONG BaseAddress,
|
||||
PULONG Size)
|
||||
{
|
||||
REGS Regs;
|
||||
ULONG MapCount = 0;
|
||||
ULONGLONG RealBaseAddress, RealSize;
|
||||
TYPE_OF_MEMORY MemoryType;
|
||||
ULONG Size;
|
||||
ASSERT(PcBiosMapCount == 0);
|
||||
|
||||
TRACE("GetBiosMemoryMap()\n");
|
||||
|
||||
/* Make sure the usable memory is large enough. To do this we check the 16
|
||||
bit value at address 0x413 inside the BDA, which gives us the usable size
|
||||
in KB */
|
||||
Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
|
||||
if (Size < DISKREADBUFFER || Size - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE)
|
||||
{
|
||||
FrLdrBugCheckWithMessage(
|
||||
MEMORY_INIT_FAILURE,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n"
|
||||
"If you see this, please report to the ReactOS team!",
|
||||
Size);
|
||||
}
|
||||
PcDiskReadBufferSize = (Size - DISKREADBUFFER) & ~0xfff;
|
||||
if (PcDiskReadBufferSize > MAX_DISKREADBUFFER_SIZE)
|
||||
{
|
||||
PcDiskReadBufferSize = MAX_DISKREADBUFFER_SIZE;
|
||||
}
|
||||
TRACE("PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize);
|
||||
|
||||
/* Get the address of the Extended BIOS Data Area (EBDA).
|
||||
* Int 15h, AH=C1h
|
||||
|
@ -232,37 +185,45 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
|||
Int386(0x15, &Regs, &Regs);
|
||||
|
||||
/* If the function fails, there is no EBDA */
|
||||
if (INT386_SUCCESS(Regs))
|
||||
if (!INT386_SUCCESS(Regs))
|
||||
{
|
||||
/* Check if this is high enough */
|
||||
ULONG EbdaBase = (ULONG)Regs.w.es << 4;
|
||||
if (EbdaBase < DISKREADBUFFER || EbdaBase - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE)
|
||||
{
|
||||
FrLdrBugCheckWithMessage(
|
||||
MEMORY_INIT_FAILURE,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"The location of your EBDA is 0x%lx, which is too low!\n\n"
|
||||
"If you see this, please report to the ReactOS team!",
|
||||
EbdaBase);
|
||||
}
|
||||
if (((EbdaBase - DISKREADBUFFER) & ~0xfff) < PcDiskReadBufferSize)
|
||||
{
|
||||
PcDiskReadBufferSize = (EbdaBase - DISKREADBUFFER) & ~0xfff;
|
||||
TRACE("After EBDA check, PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize);
|
||||
}
|
||||
|
||||
/* Calculate the (max) size of the EBDA */
|
||||
Size = 0xA0000 - EbdaBase;
|
||||
|
||||
/* Add the descriptor */
|
||||
MapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
(EbdaBase / MM_PAGE_SIZE),
|
||||
(Size / MM_PAGE_SIZE),
|
||||
LoaderFirmwarePermanent);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get Base address and (maximum) size */
|
||||
*BaseAddress = (ULONG)Regs.w.es << 4;
|
||||
*Size = 0xA0000 - *BaseAddress;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
|
||||
{
|
||||
REGS Regs;
|
||||
ULONGLONG RealBaseAddress, EndAddress, RealSize;
|
||||
TYPE_OF_MEMORY MemoryType;
|
||||
ULONG Size;
|
||||
ASSERT(PcBiosMapCount == 0);
|
||||
|
||||
TRACE("GetBiosMemoryMap()\n");
|
||||
|
||||
/* Make sure the usable memory is large enough. To do this we check the 16
|
||||
bit value at address 0x413 inside the BDA, which gives us the usable size
|
||||
in KB */
|
||||
Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
|
||||
if (Size < MEMORY_MARGIN)
|
||||
{
|
||||
FrLdrBugCheckWithMessage(
|
||||
MEMORY_INIT_FAILURE,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n"
|
||||
"If you see this, please report to the ReactOS team!",
|
||||
Size);
|
||||
}
|
||||
|
||||
|
||||
/* Int 15h AX=E820h
|
||||
* Newer BIOSes - GET SYSTEM MEMORY MAP
|
||||
*
|
||||
|
@ -322,13 +283,24 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
|||
{
|
||||
MemoryType = LoaderFree;
|
||||
|
||||
/* Align up base of memory area */
|
||||
RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL);
|
||||
/* Align up base of memory range */
|
||||
RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
|
||||
PAGE_SIZE);
|
||||
|
||||
/* Calculate the length after aligning the base */
|
||||
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
||||
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
|
||||
RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL);
|
||||
/* Calculate aligned EndAddress */
|
||||
EndAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
||||
PcBiosMemoryMap[PcBiosMapCount].Length;
|
||||
EndAddress = ALIGN_DOWN_BY(EndAddress, PAGE_SIZE);
|
||||
|
||||
/* Check if there is anything left */
|
||||
if (EndAddress <= RealBaseAddress)
|
||||
{
|
||||
/* This doesn't span any page, so continue with next range */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Calculate the length of the aligned range */
|
||||
RealSize = EndAddress - RealBaseAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -338,18 +310,20 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
|||
MemoryType = LoaderSpecialMemory;
|
||||
|
||||
/* Align down base of memory area */
|
||||
RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL);
|
||||
RealBaseAddress = ALIGN_DOWN_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
|
||||
PAGE_SIZE);
|
||||
|
||||
/* Calculate the length after aligning the base */
|
||||
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
||||
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
|
||||
RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL);
|
||||
RealSize = ALIGN_UP_BY(RealSize, PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Check if we can add this descriptor */
|
||||
if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize))
|
||||
if ((RealSize >= MM_PAGE_SIZE) && (PcMapCount < MaxMemoryMapSize))
|
||||
{
|
||||
/* Add the descriptor */
|
||||
MapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
(PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE),
|
||||
(PFN_NUMBER)(RealSize / MM_PAGE_SIZE),
|
||||
|
@ -366,12 +340,72 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
|||
TRACE("End Of System Memory Map!\n\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return MapCount;
|
||||
TRACE("GetBiosMemoryMap end, PcBiosMapCount = %ld\n", PcBiosMapCount);
|
||||
return PcBiosMapCount;
|
||||
}
|
||||
|
||||
VOID
|
||||
ReserveMemory(
|
||||
ULONG_PTR BaseAddress,
|
||||
SIZE_T Size,
|
||||
TYPE_OF_MEMORY MemoryType,
|
||||
PCHAR Usage)
|
||||
{
|
||||
ULONG_PTR BasePage, PageCount;
|
||||
ULONG i;
|
||||
|
||||
BasePage = BaseAddress / PAGE_SIZE;
|
||||
PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
|
||||
|
||||
for (i = 0; i < PcMapCount; i++)
|
||||
{
|
||||
/* Check for conflicting descriptor */
|
||||
if ((PcMemoryMap[i].BasePage < BasePage + PageCount) &&
|
||||
(PcMemoryMap[i].BasePage + PcMemoryMap[i].PageCount > BasePage))
|
||||
{
|
||||
/* Check if the memory is free */
|
||||
if (PcMemoryMap[i].MemoryType != LoaderFree)
|
||||
{
|
||||
FrLdrBugCheckWithMessage(
|
||||
MEMORY_INIT_FAILURE,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Failed to reserve memory in the range 0x%Ix - 0x%Ix for %s",
|
||||
BaseAddress,
|
||||
Size,
|
||||
Usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the memory descriptor */
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
BasePage,
|
||||
PageCount,
|
||||
MemoryType);
|
||||
}
|
||||
|
||||
VOID
|
||||
SetMemory(
|
||||
ULONG_PTR BaseAddress,
|
||||
SIZE_T Size,
|
||||
TYPE_OF_MEMORY MemoryType)
|
||||
{
|
||||
ULONG_PTR BasePage, PageCount;
|
||||
|
||||
BasePage = BaseAddress / PAGE_SIZE;
|
||||
PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
|
||||
|
||||
/* Add the memory descriptor */
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
BasePage,
|
||||
PageCount,
|
||||
MemoryType);
|
||||
}
|
||||
|
||||
PFREELDR_MEMORY_DESCRIPTOR
|
||||
PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||
|
@ -379,13 +413,16 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
|||
ULONG i, EntryCount;
|
||||
ULONG ExtendedMemorySizeAtOneMB;
|
||||
ULONG ExtendedMemorySizeAtSixteenMB;
|
||||
ULONG EbdaBase, EbdaSize;
|
||||
TRACE("PcMemGetMemoryMap()\n");
|
||||
|
||||
EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS);
|
||||
|
||||
/* If the BIOS didn't provide a memory map, synthesize one */
|
||||
if (0 == EntryCount)
|
||||
if (EntryCount == 0)
|
||||
{
|
||||
GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB);
|
||||
GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB,
|
||||
&ExtendedMemorySizeAtSixteenMB);
|
||||
|
||||
/* Conventional memory */
|
||||
AddMemoryDescriptor(PcMemoryMap,
|
||||
|
@ -395,7 +432,7 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
|||
LoaderFree);
|
||||
|
||||
/* Extended memory */
|
||||
EntryCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
1024 * 1024 / PAGE_SIZE,
|
||||
ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE,
|
||||
|
@ -404,16 +441,65 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
|||
if (ExtendedMemorySizeAtSixteenMB != 0)
|
||||
{
|
||||
/* Extended memory at 16MB */
|
||||
EntryCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
0x1000000 / PAGE_SIZE,
|
||||
ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE,
|
||||
LoaderFree);
|
||||
}
|
||||
|
||||
/* Check if we have an EBDA and get it's location */
|
||||
if (GetEbdaLocation(&EbdaBase, &EbdaSize))
|
||||
{
|
||||
/* Add the descriptor */
|
||||
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||
MAX_BIOS_DESCRIPTORS,
|
||||
(EbdaBase / PAGE_SIZE),
|
||||
ADDRESS_AND_SIZE_TO_SPAN_PAGES(EbdaBase, EbdaSize),
|
||||
LoaderFirmwarePermanent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup some protected ranges */
|
||||
SetMemory(0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA
|
||||
SetMemory(0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory
|
||||
SetMemory(0x0F0000, 0x10000, LoaderSpecialMemory); // ROM
|
||||
SetMemory(0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?)
|
||||
|
||||
/* Reserve some static ranges for freeldr */
|
||||
ReserveMemory(0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area");
|
||||
ReserveMemory(STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack");
|
||||
ReserveMemory(FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image");
|
||||
|
||||
/* Default to 1 page above freeldr for the disk read buffer */
|
||||
DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE);
|
||||
DiskReadBufferSize = PAGE_SIZE;
|
||||
|
||||
/* Scan for free range above freeldr image */
|
||||
for (i = 0; i < PcMapCount; i++)
|
||||
{
|
||||
if ((PcMemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) &&
|
||||
(PcMemoryMap[i].MemoryType == LoaderFree))
|
||||
{
|
||||
/* Use this range for the disk read buffer */
|
||||
DiskReadBuffer = (PVOID)(PcMemoryMap[i].BasePage * PAGE_SIZE);
|
||||
DiskReadBufferSize = min(PcMemoryMap[i].PageCount * PAGE_SIZE,
|
||||
MAX_DISKREADBUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("DiskReadBuffer=%p, DiskReadBufferSize=%lx\n",
|
||||
DiskReadBuffer, DiskReadBufferSize);
|
||||
|
||||
/* Now reserve the range for the disk read buffer */
|
||||
ReserveMemory((ULONG_PTR)DiskReadBuffer,
|
||||
DiskReadBufferSize,
|
||||
LoaderFirmwareTemporary,
|
||||
"Disk read buffer");
|
||||
|
||||
TRACE("Dumping resulting memory map:\n");
|
||||
for (i = 0; i < EntryCount; i++)
|
||||
for (i = 0; i < PcMapCount; i++)
|
||||
{
|
||||
TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
|
||||
PcMemoryMap[i].BasePage,
|
||||
|
@ -421,9 +507,9 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
|||
MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
|
||||
}
|
||||
|
||||
*MemoryMapSize = EntryCount;
|
||||
|
||||
*MemoryMapSize = PcMapCount;
|
||||
return PcMemoryMap;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -198,17 +198,17 @@ DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
|||
while (N > 0)
|
||||
{
|
||||
Length = N;
|
||||
if (Length > PcDiskReadBufferSize)
|
||||
Length = PcDiskReadBufferSize;
|
||||
if (Length > DiskReadBufferSize)
|
||||
Length = DiskReadBufferSize;
|
||||
Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
|
||||
ret = MachDiskReadLogicalSectors(
|
||||
Context->DriveNumber,
|
||||
Context->SectorNumber + Context->SectorOffset + i,
|
||||
Sectors,
|
||||
(PVOID)DISKREADBUFFER);
|
||||
DiskReadBuffer);
|
||||
if (!ret)
|
||||
return EIO;
|
||||
RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
|
||||
RtlCopyMemory(Ptr, DiskReadBuffer, Length);
|
||||
Ptr += Length;
|
||||
*Count += Length;
|
||||
N -= Length;
|
||||
|
@ -257,14 +257,14 @@ GetHarddiskIdentifier(PCHAR Identifier,
|
|||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
|
||||
/* Read the MBR */
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||
{
|
||||
ERR("Reading MBR failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Buffer = (ULONG*)DISKREADBUFFER;
|
||||
Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
|
||||
Buffer = (ULONG*)DiskReadBuffer;
|
||||
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
|
||||
|
||||
Signature = Mbr->Signature;
|
||||
TRACE("Signature: %x\n", Signature);
|
||||
|
@ -351,13 +351,13 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
|
|||
* harddisks. So, we set the buffer to known contents first, then try to
|
||||
* read. If the BIOS reports success but the buffer contents haven't
|
||||
* changed then we fail anyway */
|
||||
memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
|
||||
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
||||
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
|
||||
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
|
||||
{
|
||||
Changed = FALSE;
|
||||
for (i = 0; ! Changed && i < PcDiskReadBufferSize; i++)
|
||||
for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
|
||||
{
|
||||
Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
|
||||
Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
|
||||
}
|
||||
if (! Changed)
|
||||
{
|
||||
|
@ -366,7 +366,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
|
|||
break;
|
||||
}
|
||||
DiskCount++;
|
||||
memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
|
||||
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
|
||||
}
|
||||
DiskReportError(TRUE);
|
||||
TRACE("BIOS reports %d harddisk%s\n",
|
||||
|
|
|
@ -119,13 +119,13 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNu
|
|||
}
|
||||
|
||||
// Now try to read in the block
|
||||
if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer))
|
||||
{
|
||||
FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA);
|
||||
FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
|
||||
RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
|
||||
|
||||
// Add it to our list of blocks managed by the cache
|
||||
InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
|
||||
|
|
|
@ -202,11 +202,11 @@ BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMA
|
|||
ULONG Index;
|
||||
|
||||
// Read master boot record
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD));
|
||||
RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD));
|
||||
|
||||
|
||||
TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
|
||||
|
|
|
@ -569,8 +569,8 @@ BOOLEAN Ext2ReadVolumeSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG S
|
|||
//{
|
||||
// return FALSE;
|
||||
//}
|
||||
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER);
|
||||
//RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
|
||||
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, DiskReadBuffer);
|
||||
//RtlCopyMemory(Buffer, DiskReadBuffer, SectorCount * DiskGeometry.BytesPerSector);
|
||||
//return ReturnValue;
|
||||
|
||||
return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
|
||||
|
@ -607,11 +607,11 @@ BOOLEAN Ext2ReadSuperBlock(VOID)
|
|||
|
||||
// Now try to read the super block
|
||||
// If this fails then abort
|
||||
if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER))
|
||||
if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
RtlCopyMemory(Ext2SuperBlock, (PVOID)((ULONG_PTR)DISKREADBUFFER + 1024), 1024);
|
||||
RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024);
|
||||
|
||||
TRACE("Dumping super block:\n");
|
||||
TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);
|
||||
|
|
|
@ -35,4 +35,4 @@ extern ULONG SecondLevelIcacheSize;
|
|||
extern ULONG SecondLevelIcacheFillSize;
|
||||
|
||||
extern ULONG gDiskReadBuffer, gFileSysBuffer;
|
||||
#define DISKREADBUFFER gDiskReadBuffer
|
||||
#define DiskReadBuffer gDiskReadBuffer
|
||||
|
|
|
@ -63,6 +63,5 @@ VOID PcHwIdle(VOID);
|
|||
|
||||
extern BIOS_MEMORY_MAP PcBiosMemoryMap[];
|
||||
extern ULONG PcBiosMapCount;
|
||||
extern ULONG PcDiskReadBufferSize;
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#endif
|
||||
|
||||
/* Memory layout */
|
||||
//#ifdef _M_AMD64
|
||||
#ifdef _M_AMD64
|
||||
#define PML4_ADDRESS HEX(1000) /* One page PML4 page table */
|
||||
#define PDP_ADDRESS HEX(2000) /* One page PDP page table */
|
||||
#define PD_ADDRESS HEX(3000) /* One page PD page table */
|
||||
//#endif
|
||||
#endif
|
||||
#define BIOSCALLBUFFER HEX(4000) /* Buffer to store temporary data for any Int386() call */
|
||||
#define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
|
||||
#define BSS_START HEX(6F00)
|
||||
|
@ -16,15 +16,13 @@
|
|||
#define STACKADDR HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or 0xF000 */
|
||||
#define FREELDR_BASE HEX(F800)
|
||||
#define FREELDR_PE_BASE HEX(10000)
|
||||
#define DISKREADBUFFER HEX(8E000) /* Buffer to store data read in from the disk via the BIOS */
|
||||
/* 9F000- 9FFFF is reserved for the EBDA */
|
||||
#define MEMORY_MARGIN HEX(90000) /* We need this much memory */
|
||||
|
||||
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFSIZE PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */
|
||||
#define MAX_FREELDR_PE_SIZE (DISKREADBUFFER - FREELDR_PE_BASE)
|
||||
#define MIN_DISKREADBUFFER_SIZE HEX(1000)
|
||||
#define MAX_DISKREADBUFFER_SIZE HEX(C000)
|
||||
#define MAX_FREELDR_PE_SIZE (MEMORY_MARGIN - FREELDR_PE_BASE - PAGE_SIZE)
|
||||
#define MAX_DISKREADBUFFER_SIZE HEX(10000)
|
||||
|
||||
/* These addresses specify the realmode "BSS section" layout */
|
||||
#define BSS_RealModeEntry (BSS_START + 0)
|
||||
|
|
|
@ -125,6 +125,8 @@ BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
|
|||
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
|
||||
extern UCHAR FrldrBootDrive;
|
||||
extern ULONG FrldrBootPartition;
|
||||
extern PVOID DiskReadBuffer;
|
||||
extern SIZE_T DiskReadBufferSize;
|
||||
|
||||
BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size);
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAdd
|
|||
|
||||
extern PVOID FrLdrDefaultHeap;
|
||||
extern PVOID FrLdrTempHeap;
|
||||
extern SIZE_T FrLdrImageSize;
|
||||
|
||||
PVOID
|
||||
FrLdrHeapCreate(
|
||||
|
|
|
@ -23,6 +23,17 @@
|
|||
|
||||
DBG_DEFAULT_CHANNEL(MEMORY);
|
||||
|
||||
PVOID PageLookupTableAddress = NULL;
|
||||
PFN_NUMBER TotalPagesInLookupTable = 0;
|
||||
PFN_NUMBER FreePagesInLookupTable = 0;
|
||||
PFN_NUMBER LastFreePageHint = 0;
|
||||
PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
|
||||
PFN_NUMBER MmHighestPhysicalPage = 0;
|
||||
|
||||
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
|
||||
ULONG BiosMemoryMapEntryCount;
|
||||
SIZE_T FrLdrImageSize;
|
||||
|
||||
#if DBG
|
||||
typedef struct
|
||||
{
|
||||
|
@ -50,18 +61,43 @@ FREELDR_MEMORY_TYPE MemoryTypeArray[] =
|
|||
{ LoaderReserve, "Reserve" },
|
||||
};
|
||||
ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
|
||||
|
||||
PCSTR
|
||||
MmGetSystemMemoryMapTypeString(
|
||||
TYPE_OF_MEMORY Type)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for (Index = 1; Index < MemoryTypeCount; Index++)
|
||||
{
|
||||
if (MemoryTypeArray[Index].Type == Type)
|
||||
{
|
||||
return MemoryTypeArray[Index].TypeString;
|
||||
}
|
||||
}
|
||||
|
||||
return MemoryTypeArray[0].TypeString;
|
||||
}
|
||||
|
||||
VOID
|
||||
DbgDumpMemoryMap(
|
||||
PFREELDR_MEMORY_DESCRIPTOR List)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
DbgPrint("Dumping Memory map:\n");
|
||||
for (i = 0; List[i].PageCount != 0; i++)
|
||||
{
|
||||
DbgPrint("%02d %08x - %08x: %s\n",
|
||||
i,
|
||||
List[i].BasePage * PAGE_SIZE,
|
||||
(List[i].BasePage + List[i].PageCount) * PAGE_SIZE,
|
||||
MmGetSystemMemoryMapTypeString(List[i].MemoryType));
|
||||
}
|
||||
DbgPrint("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
PVOID PageLookupTableAddress = NULL;
|
||||
PFN_NUMBER TotalPagesInLookupTable = 0;
|
||||
PFN_NUMBER FreePagesInLookupTable = 0;
|
||||
PFN_NUMBER LastFreePageHint = 0;
|
||||
PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
|
||||
PFN_NUMBER MmHighestPhysicalPage = 0;
|
||||
|
||||
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
|
||||
ULONG BiosMemoryMapEntryCount;
|
||||
|
||||
ULONG
|
||||
AddMemoryDescriptor(
|
||||
IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
|
||||
|
@ -70,78 +106,117 @@ AddMemoryDescriptor(
|
|||
IN PFN_NUMBER PageCount,
|
||||
IN TYPE_OF_MEMORY MemoryType)
|
||||
{
|
||||
ULONG i, c;
|
||||
PFN_NUMBER NextBase;
|
||||
TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
|
||||
BasePage, BasePage + PageCount, PageCount);
|
||||
ULONG Index, DescriptCount;
|
||||
PFN_NUMBER EndPage;
|
||||
TRACE("AddMemoryDescriptor(0x%Ix, 0x%Ix, %u)\n",
|
||||
BasePage, PageCount, MemoryType);
|
||||
|
||||
/* Scan through all existing descriptors */
|
||||
for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
|
||||
EndPage = BasePage + PageCount;
|
||||
|
||||
/* Skip over all descriptor below the new range */
|
||||
Index = 0;
|
||||
while ((List[Index].PageCount != 0) &&
|
||||
((List[Index].BasePage + List[Index].PageCount) <= BasePage))
|
||||
{
|
||||
/* Count entries completely below the new range */
|
||||
if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
|
||||
Index++;
|
||||
}
|
||||
|
||||
/* Check if the list is full */
|
||||
if (c >= MaxCount) return c;
|
||||
|
||||
/* Is there an existing descriptor starting before the new range */
|
||||
while ((i < c) && (List[i].BasePage <= BasePage))
|
||||
/* Count the descriptors */
|
||||
DescriptCount = Index;
|
||||
while (List[DescriptCount].PageCount != 0)
|
||||
{
|
||||
/* The end of the existing one is the minimum for the new range */
|
||||
NextBase = List[i].BasePage + List[i].PageCount;
|
||||
|
||||
/* Bail out, if everything is trimmed away */
|
||||
if ((BasePage + PageCount) <= NextBase) return c;
|
||||
|
||||
/* Trim the naew range at the lower end */
|
||||
PageCount -= (NextBase - BasePage);
|
||||
BasePage = NextBase;
|
||||
|
||||
/* Go to the next entry and repeat */
|
||||
i++;
|
||||
DescriptCount++;
|
||||
}
|
||||
|
||||
ASSERT(PageCount > 0);
|
||||
|
||||
/* Are there still entries above? */
|
||||
if (i < c)
|
||||
/* Check if the existing range conflicts with the new range */
|
||||
while ((List[Index].PageCount != 0) &&
|
||||
(List[Index].BasePage < EndPage))
|
||||
{
|
||||
/* Shift the following entries one up */
|
||||
RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0]));
|
||||
TRACE("AddMemoryDescriptor conflict @%lu: new=[%lx:%lx], existing=[%lx,%lx]\n",
|
||||
Index, BasePage, PageCount, List[Index].BasePage, List[Index].PageCount);
|
||||
|
||||
/* Insert the new range */
|
||||
List[i].BasePage = BasePage;
|
||||
List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage);
|
||||
List[i].MemoryType = MemoryType;
|
||||
c++;
|
||||
/*
|
||||
* We have 4 overlapping cases:
|
||||
*
|
||||
* Case (a) (b) (c) (d)
|
||||
* Existing range |---| |-----| |---| |---|
|
||||
* New range |---| |---| |-----| |---|
|
||||
*
|
||||
*/
|
||||
|
||||
TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n",
|
||||
i, List[i].BasePage, List[i].PageCount);
|
||||
|
||||
/* Check if the range was trimmed */
|
||||
if (PageCount > List[i].PageCount)
|
||||
/* Check if the existing range starts before the new range (a)/(b) */
|
||||
if (List[Index].BasePage < BasePage)
|
||||
{
|
||||
/* Recursively process the trimmed part */
|
||||
c = AddMemoryDescriptor(List,
|
||||
MaxCount,
|
||||
BasePage + List[i].PageCount,
|
||||
PageCount - List[i].PageCount,
|
||||
MemoryType);
|
||||
/* Check if the existing range extends beyond the new range (b) */
|
||||
if (List[Index].BasePage + List[Index].PageCount > EndPage)
|
||||
{
|
||||
/* Split the descriptor */
|
||||
RtlMoveMemory(&List[Index + 1],
|
||||
&List[Index],
|
||||
(DescriptCount - Index) * sizeof(List[0]));
|
||||
List[Index + 1].BasePage = EndPage;
|
||||
List[Index + 1].PageCount = List[Index].BasePage +
|
||||
List[Index].PageCount -
|
||||
List[Index + 1].BasePage;
|
||||
List[Index].PageCount = BasePage - List[Index].BasePage;
|
||||
Index++;
|
||||
DescriptCount++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Crop the existing range and continue with the next range */
|
||||
List[Index].PageCount = BasePage - List[Index].BasePage;
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
/* Check if the existing range is fully covered by the new range (c) */
|
||||
else if ((List[Index].BasePage + List[Index].PageCount) <=
|
||||
EndPage)
|
||||
{
|
||||
/* Delete this descriptor */
|
||||
RtlMoveMemory(&List[Index],
|
||||
&List[Index + 1],
|
||||
(DescriptCount - Index) * sizeof(List[0]));
|
||||
DescriptCount--;
|
||||
}
|
||||
/* Otherwise the existing range ends after the new range (d) */
|
||||
else
|
||||
{
|
||||
/* Crop the existing range at the start and bail out */
|
||||
List[Index].PageCount -= EndPage - List[Index].BasePage;
|
||||
List[Index].BasePage = EndPage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Make sure we can still add a new descriptor */
|
||||
if (DescriptCount >= MaxCount)
|
||||
{
|
||||
/* We can simply add the range here */
|
||||
TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount);
|
||||
List[i].BasePage = BasePage;
|
||||
List[i].PageCount = PageCount;
|
||||
List[i].MemoryType = MemoryType;
|
||||
c++;
|
||||
FrLdrBugCheckWithMessage(
|
||||
MEMORY_INIT_FAILURE,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Ran out of static memory descriptors!");
|
||||
}
|
||||
|
||||
/* Return the new count */
|
||||
return c;
|
||||
/* Insert the new descriptor */
|
||||
if (Index < DescriptCount)
|
||||
{
|
||||
RtlMoveMemory(&List[Index + 1],
|
||||
&List[Index],
|
||||
(DescriptCount - Index) * sizeof(List[0]));
|
||||
}
|
||||
|
||||
List[Index].BasePage = BasePage;
|
||||
List[Index].PageCount = PageCount;
|
||||
List[Index].MemoryType = MemoryType;
|
||||
DescriptCount++;
|
||||
|
||||
#ifdef DBG
|
||||
DbgDumpMemoryMap(List);
|
||||
#endif
|
||||
return DescriptCount;
|
||||
}
|
||||
|
||||
const FREELDR_MEMORY_DESCRIPTOR*
|
||||
|
@ -230,6 +305,9 @@ MmCheckFreeldrImageFile()
|
|||
OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE,
|
||||
OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment);
|
||||
}
|
||||
|
||||
/* Calculate the full image size */
|
||||
FrLdrImageSize = (ULONG_PTR)&__ImageBase + OptionalHeader->SizeOfImage - FREELDR_BASE;
|
||||
}
|
||||
|
||||
BOOLEAN MmInitializeMemoryManager(VOID)
|
||||
|
@ -287,22 +365,6 @@ BOOLEAN MmInitializeMemoryManager(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if DBG
|
||||
PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for (Index=1; Index<MemoryTypeCount; Index++)
|
||||
{
|
||||
if (MemoryTypeArray[Index].Type == Type)
|
||||
{
|
||||
return MemoryTypeArray[Index].TypeString;
|
||||
}
|
||||
}
|
||||
|
||||
return MemoryTypeArray[0].TypeString;
|
||||
}
|
||||
#endif
|
||||
|
||||
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue