mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 22:56:00 +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
|
* Timo Kreuzer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DISKREADBUFFER HEX(8E000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Layout of a FAT volume:
|
* Layout of a FAT volume:
|
||||||
|
|
|
@ -307,10 +307,10 @@ DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
||||||
{
|
{
|
||||||
NodeNumber = (UCHAR)i;
|
NodeNumber = (UCHAR)i;
|
||||||
|
|
||||||
x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER);
|
x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
|
||||||
if (x == 0)
|
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",
|
TRACE("Node: %u Size %u (0x%x)\n",
|
||||||
DeviceNode->Node,
|
DeviceNode->Node,
|
||||||
|
|
|
@ -42,6 +42,8 @@ extern CHAR reactos_arc_strings[32][256];
|
||||||
static CHAR Hex[] = "0123456789abcdef";
|
static CHAR Hex[] = "0123456789abcdef";
|
||||||
UCHAR PcBiosDiskCount = 0;
|
UCHAR PcBiosDiskCount = 0;
|
||||||
CHAR PcDiskIdentifier[32][20];
|
CHAR PcDiskIdentifier[32][20];
|
||||||
|
PVOID DiskReadBuffer;
|
||||||
|
SIZE_T DiskReadBufferSize;
|
||||||
|
|
||||||
|
|
||||||
static ARC_STATUS DiskClose(ULONG FileId)
|
static ARC_STATUS DiskClose(ULONG FileId)
|
||||||
|
@ -119,7 +121,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||||
ULONGLONG SectorOffset;
|
ULONGLONG SectorOffset;
|
||||||
|
|
||||||
TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
|
TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
|
||||||
MaxSectors = PcDiskReadBufferSize / Context->SectorSize;
|
MaxSectors = DiskReadBufferSize / Context->SectorSize;
|
||||||
SectorOffset = Context->SectorNumber + Context->SectorOffset;
|
SectorOffset = Context->SectorNumber + Context->SectorOffset;
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -134,7 +136,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||||
Context->DriveNumber,
|
Context->DriveNumber,
|
||||||
SectorOffset,
|
SectorOffset,
|
||||||
ReadSectors,
|
ReadSectors,
|
||||||
(PVOID)DISKREADBUFFER);
|
DiskReadBuffer);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -142,7 +144,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||||
if (Length > N)
|
if (Length > N)
|
||||||
Length = N;
|
Length = N;
|
||||||
|
|
||||||
RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
|
RtlCopyMemory(Ptr, DiskReadBuffer, Length);
|
||||||
|
|
||||||
Ptr += Length;
|
Ptr += Length;
|
||||||
N -= Length;
|
N -= Length;
|
||||||
|
@ -197,14 +199,14 @@ GetHarddiskInformation(
|
||||||
PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80];
|
PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80];
|
||||||
|
|
||||||
/* Read the MBR */
|
/* Read the MBR */
|
||||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
ERR("Reading MBR failed\n");
|
ERR("Reading MBR failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer = (ULONG*)DISKREADBUFFER;
|
Buffer = (ULONG*)DiskReadBuffer;
|
||||||
Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
|
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
|
||||||
|
|
||||||
Signature = Mbr->Signature;
|
Signature = Mbr->Signature;
|
||||||
TRACE("Signature: %x\n", 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
|
* 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
|
* read. If the BIOS reports success but the buffer contents haven't
|
||||||
* changed then we fail anyway */
|
* changed then we fail anyway */
|
||||||
memset((PVOID) DISKREADBUFFER, 0xcd, 512);
|
memset(DiskReadBuffer, 0xcd, 512);
|
||||||
while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
Changed = FALSE;
|
Changed = FALSE;
|
||||||
for (i = 0; ! Changed && i < 512; i++)
|
for (i = 0; ! Changed && i < 512; i++)
|
||||||
{
|
{
|
||||||
Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
|
Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
|
||||||
}
|
}
|
||||||
if (! Changed)
|
if (! Changed)
|
||||||
{
|
{
|
||||||
|
@ -310,7 +312,7 @@ HwInitializeBiosDisks(VOID)
|
||||||
|
|
||||||
DiskCount++;
|
DiskCount++;
|
||||||
DriveNumber++;
|
DriveNumber++;
|
||||||
memset((PVOID) DISKREADBUFFER, 0xcd, 512);
|
memset(DiskReadBuffer, 0xcd, 512);
|
||||||
}
|
}
|
||||||
DiskReportError(TRUE);
|
DiskReportError(TRUE);
|
||||||
|
|
||||||
|
@ -326,13 +328,13 @@ HwInitializeBiosDisks(VOID)
|
||||||
ULONG Checksum = 0;
|
ULONG Checksum = 0;
|
||||||
|
|
||||||
/* Read the MBR */
|
/* Read the MBR */
|
||||||
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER))
|
if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
ERR("Reading MBR failed\n");
|
ERR("Reading MBR failed\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer = (ULONG*)DISKREADBUFFER;
|
Buffer = (ULONG*)DiskReadBuffer;
|
||||||
|
|
||||||
/* Calculate the MBR checksum */
|
/* Calculate the MBR checksum */
|
||||||
for (i = 0; i < 2048 / sizeof(ULONG); i++) Checksum += Buffer[i];
|
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 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];
|
BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS];
|
||||||
ULONG PcBiosMapCount;
|
ULONG PcBiosMapCount;
|
||||||
ULONG PcDiskReadBufferSize;
|
|
||||||
|
|
||||||
FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] =
|
FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1];
|
||||||
{
|
ULONG PcMapCount;
|
||||||
{ 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
|
|
||||||
};
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
AddMemoryDescriptor(
|
AddMemoryDescriptor(
|
||||||
|
@ -186,38 +165,12 @@ PcMemGetConventionalMemorySize(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
ULONG
|
BOOLEAN
|
||||||
PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
|
GetEbdaLocation(
|
||||||
|
PULONG BaseAddress,
|
||||||
|
PULONG Size)
|
||||||
{
|
{
|
||||||
REGS Regs;
|
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).
|
/* Get the address of the Extended BIOS Data Area (EBDA).
|
||||||
* Int 15h, AH=C1h
|
* Int 15h, AH=C1h
|
||||||
|
@ -232,37 +185,45 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
||||||
Int386(0x15, &Regs, &Regs);
|
Int386(0x15, &Regs, &Regs);
|
||||||
|
|
||||||
/* If the function fails, there is no EBDA */
|
/* If the function fails, there is no EBDA */
|
||||||
if (INT386_SUCCESS(Regs))
|
if (!INT386_SUCCESS(Regs))
|
||||||
{
|
{
|
||||||
/* Check if this is high enough */
|
return FALSE;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Int 15h AX=E820h
|
||||||
* Newer BIOSes - GET SYSTEM MEMORY MAP
|
* Newer BIOSes - GET SYSTEM MEMORY MAP
|
||||||
*
|
*
|
||||||
|
@ -322,13 +283,24 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
||||||
{
|
{
|
||||||
MemoryType = LoaderFree;
|
MemoryType = LoaderFree;
|
||||||
|
|
||||||
/* Align up base of memory area */
|
/* Align up base of memory range */
|
||||||
RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL);
|
RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
|
||||||
|
PAGE_SIZE);
|
||||||
|
|
||||||
/* Calculate the length after aligning the base */
|
/* Calculate aligned EndAddress */
|
||||||
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
EndAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
||||||
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
|
PcBiosMemoryMap[PcBiosMapCount].Length;
|
||||||
RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -338,18 +310,20 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
|
||||||
MemoryType = LoaderSpecialMemory;
|
MemoryType = LoaderSpecialMemory;
|
||||||
|
|
||||||
/* Align down base of memory area */
|
/* 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 */
|
/* Calculate the length after aligning the base */
|
||||||
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
|
||||||
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
|
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 */
|
/* Check if we can add this descriptor */
|
||||||
if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize))
|
if ((RealSize >= MM_PAGE_SIZE) && (PcMapCount < MaxMemoryMapSize))
|
||||||
{
|
{
|
||||||
/* Add the descriptor */
|
/* Add the descriptor */
|
||||||
MapCount = AddMemoryDescriptor(PcMemoryMap,
|
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||||
MAX_BIOS_DESCRIPTORS,
|
MAX_BIOS_DESCRIPTORS,
|
||||||
(PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE),
|
(PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE),
|
||||||
(PFN_NUMBER)(RealSize / 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");
|
TRACE("End Of System Memory Map!\n\n");
|
||||||
break;
|
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
|
PFREELDR_MEMORY_DESCRIPTOR
|
||||||
PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
|
@ -379,13 +413,16 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
ULONG i, EntryCount;
|
ULONG i, EntryCount;
|
||||||
ULONG ExtendedMemorySizeAtOneMB;
|
ULONG ExtendedMemorySizeAtOneMB;
|
||||||
ULONG ExtendedMemorySizeAtSixteenMB;
|
ULONG ExtendedMemorySizeAtSixteenMB;
|
||||||
|
ULONG EbdaBase, EbdaSize;
|
||||||
|
TRACE("PcMemGetMemoryMap()\n");
|
||||||
|
|
||||||
EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS);
|
EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS);
|
||||||
|
|
||||||
/* If the BIOS didn't provide a memory map, synthesize one */
|
/* 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 */
|
/* Conventional memory */
|
||||||
AddMemoryDescriptor(PcMemoryMap,
|
AddMemoryDescriptor(PcMemoryMap,
|
||||||
|
@ -395,7 +432,7 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
LoaderFree);
|
LoaderFree);
|
||||||
|
|
||||||
/* Extended memory */
|
/* Extended memory */
|
||||||
EntryCount = AddMemoryDescriptor(PcMemoryMap,
|
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||||
MAX_BIOS_DESCRIPTORS,
|
MAX_BIOS_DESCRIPTORS,
|
||||||
1024 * 1024 / PAGE_SIZE,
|
1024 * 1024 / PAGE_SIZE,
|
||||||
ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE,
|
ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE,
|
||||||
|
@ -404,16 +441,65 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
if (ExtendedMemorySizeAtSixteenMB != 0)
|
if (ExtendedMemorySizeAtSixteenMB != 0)
|
||||||
{
|
{
|
||||||
/* Extended memory at 16MB */
|
/* Extended memory at 16MB */
|
||||||
EntryCount = AddMemoryDescriptor(PcMemoryMap,
|
PcMapCount = AddMemoryDescriptor(PcMemoryMap,
|
||||||
MAX_BIOS_DESCRIPTORS,
|
MAX_BIOS_DESCRIPTORS,
|
||||||
0x1000000 / PAGE_SIZE,
|
0x1000000 / PAGE_SIZE,
|
||||||
ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE,
|
ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE,
|
||||||
LoaderFree);
|
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");
|
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",
|
TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
|
||||||
PcMemoryMap[i].BasePage,
|
PcMemoryMap[i].BasePage,
|
||||||
|
@ -421,9 +507,9 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
|
MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
|
||||||
}
|
}
|
||||||
|
|
||||||
*MemoryMapSize = EntryCount;
|
*MemoryMapSize = PcMapCount;
|
||||||
|
|
||||||
return PcMemoryMap;
|
return PcMemoryMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -198,17 +198,17 @@ DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||||
while (N > 0)
|
while (N > 0)
|
||||||
{
|
{
|
||||||
Length = N;
|
Length = N;
|
||||||
if (Length > PcDiskReadBufferSize)
|
if (Length > DiskReadBufferSize)
|
||||||
Length = PcDiskReadBufferSize;
|
Length = DiskReadBufferSize;
|
||||||
Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
|
Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
|
||||||
ret = MachDiskReadLogicalSectors(
|
ret = MachDiskReadLogicalSectors(
|
||||||
Context->DriveNumber,
|
Context->DriveNumber,
|
||||||
Context->SectorNumber + Context->SectorOffset + i,
|
Context->SectorNumber + Context->SectorOffset + i,
|
||||||
Sectors,
|
Sectors,
|
||||||
(PVOID)DISKREADBUFFER);
|
DiskReadBuffer);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return EIO;
|
return EIO;
|
||||||
RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
|
RtlCopyMemory(Ptr, DiskReadBuffer, Length);
|
||||||
Ptr += Length;
|
Ptr += Length;
|
||||||
*Count += Length;
|
*Count += Length;
|
||||||
N -= Length;
|
N -= Length;
|
||||||
|
@ -257,14 +257,14 @@ GetHarddiskIdentifier(PCHAR Identifier,
|
||||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||||
|
|
||||||
/* Read the MBR */
|
/* Read the MBR */
|
||||||
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
ERR("Reading MBR failed\n");
|
ERR("Reading MBR failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer = (ULONG*)DISKREADBUFFER;
|
Buffer = (ULONG*)DiskReadBuffer;
|
||||||
Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
|
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
|
||||||
|
|
||||||
Signature = Mbr->Signature;
|
Signature = Mbr->Signature;
|
||||||
TRACE("Signature: %x\n", 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
|
* 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
|
* read. If the BIOS reports success but the buffer contents haven't
|
||||||
* changed then we fail anyway */
|
* changed then we fail anyway */
|
||||||
memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
|
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
|
||||||
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
|
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
Changed = FALSE;
|
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)
|
if (! Changed)
|
||||||
{
|
{
|
||||||
|
@ -366,7 +366,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DiskCount++;
|
DiskCount++;
|
||||||
memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize);
|
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
|
||||||
}
|
}
|
||||||
DiskReportError(TRUE);
|
DiskReportError(TRUE);
|
||||||
TRACE("BIOS reports %d harddisk%s\n",
|
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
|
// 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->BlockData, TAG_CACHE_DATA);
|
||||||
FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
|
FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
|
||||||
return NULL;
|
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
|
// Add it to our list of blocks managed by the cache
|
||||||
InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
|
InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
|
||||||
|
|
|
@ -202,11 +202,11 @@ BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMA
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
// Read master boot record
|
// Read master boot record
|
||||||
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
|
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
return FALSE;
|
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);
|
TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
|
||||||
|
|
|
@ -569,8 +569,8 @@ BOOLEAN Ext2ReadVolumeSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG S
|
||||||
//{
|
//{
|
||||||
// return FALSE;
|
// return FALSE;
|
||||||
//}
|
//}
|
||||||
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER);
|
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, DiskReadBuffer);
|
||||||
//RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
|
//RtlCopyMemory(Buffer, DiskReadBuffer, SectorCount * DiskGeometry.BytesPerSector);
|
||||||
//return ReturnValue;
|
//return ReturnValue;
|
||||||
|
|
||||||
return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
|
return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
|
||||||
|
@ -607,11 +607,11 @@ BOOLEAN Ext2ReadSuperBlock(VOID)
|
||||||
|
|
||||||
// Now try to read the super block
|
// Now try to read the super block
|
||||||
// If this fails then abort
|
// If this fails then abort
|
||||||
if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER))
|
if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
RtlCopyMemory(Ext2SuperBlock, (PVOID)((ULONG_PTR)DISKREADBUFFER + 1024), 1024);
|
RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024);
|
||||||
|
|
||||||
TRACE("Dumping super block:\n");
|
TRACE("Dumping super block:\n");
|
||||||
TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);
|
TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);
|
||||||
|
|
|
@ -35,4 +35,4 @@ extern ULONG SecondLevelIcacheSize;
|
||||||
extern ULONG SecondLevelIcacheFillSize;
|
extern ULONG SecondLevelIcacheFillSize;
|
||||||
|
|
||||||
extern ULONG gDiskReadBuffer, gFileSysBuffer;
|
extern ULONG gDiskReadBuffer, gFileSysBuffer;
|
||||||
#define DISKREADBUFFER gDiskReadBuffer
|
#define DiskReadBuffer gDiskReadBuffer
|
||||||
|
|
|
@ -63,6 +63,5 @@ VOID PcHwIdle(VOID);
|
||||||
|
|
||||||
extern BIOS_MEMORY_MAP PcBiosMemoryMap[];
|
extern BIOS_MEMORY_MAP PcBiosMemoryMap[];
|
||||||
extern ULONG PcBiosMapCount;
|
extern ULONG PcBiosMapCount;
|
||||||
extern ULONG PcDiskReadBufferSize;
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Memory layout */
|
/* Memory layout */
|
||||||
//#ifdef _M_AMD64
|
#ifdef _M_AMD64
|
||||||
#define PML4_ADDRESS HEX(1000) /* One page PML4 page table */
|
#define PML4_ADDRESS HEX(1000) /* One page PML4 page table */
|
||||||
#define PDP_ADDRESS HEX(2000) /* One page PDP page table */
|
#define PDP_ADDRESS HEX(2000) /* One page PDP page table */
|
||||||
#define PD_ADDRESS HEX(3000) /* One page PD 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 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 STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
|
||||||
#define BSS_START HEX(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 STACKADDR HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or 0xF000 */
|
||||||
#define FREELDR_BASE HEX(F800)
|
#define FREELDR_BASE HEX(F800)
|
||||||
#define FREELDR_PE_BASE HEX(10000)
|
#define FREELDR_PE_BASE HEX(10000)
|
||||||
#define DISKREADBUFFER HEX(8E000) /* Buffer to store data read in from the disk via the BIOS */
|
#define MEMORY_MARGIN HEX(90000) /* We need this much memory */
|
||||||
/* 9F000- 9FFFF is reserved for the EBDA */
|
|
||||||
|
|
||||||
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
|
#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 BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */
|
||||||
#define BIOSCALLBUFSIZE PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */
|
#define BIOSCALLBUFSIZE PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */
|
||||||
#define MAX_FREELDR_PE_SIZE (DISKREADBUFFER - FREELDR_PE_BASE)
|
#define MAX_FREELDR_PE_SIZE (MEMORY_MARGIN - FREELDR_PE_BASE - PAGE_SIZE)
|
||||||
#define MIN_DISKREADBUFFER_SIZE HEX(1000)
|
#define MAX_DISKREADBUFFER_SIZE HEX(10000)
|
||||||
#define MAX_DISKREADBUFFER_SIZE HEX(C000)
|
|
||||||
|
|
||||||
/* These addresses specify the realmode "BSS section" layout */
|
/* These addresses specify the realmode "BSS section" layout */
|
||||||
#define BSS_RealModeEntry (BSS_START + 0)
|
#define BSS_RealModeEntry (BSS_START + 0)
|
||||||
|
|
|
@ -125,6 +125,8 @@ BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
|
||||||
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
|
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
|
||||||
extern UCHAR FrldrBootDrive;
|
extern UCHAR FrldrBootDrive;
|
||||||
extern ULONG FrldrBootPartition;
|
extern ULONG FrldrBootPartition;
|
||||||
|
extern PVOID DiskReadBuffer;
|
||||||
|
extern SIZE_T DiskReadBufferSize;
|
||||||
|
|
||||||
BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size);
|
BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size);
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAdd
|
||||||
|
|
||||||
extern PVOID FrLdrDefaultHeap;
|
extern PVOID FrLdrDefaultHeap;
|
||||||
extern PVOID FrLdrTempHeap;
|
extern PVOID FrLdrTempHeap;
|
||||||
|
extern SIZE_T FrLdrImageSize;
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
FrLdrHeapCreate(
|
FrLdrHeapCreate(
|
||||||
|
|
|
@ -23,6 +23,17 @@
|
||||||
|
|
||||||
DBG_DEFAULT_CHANNEL(MEMORY);
|
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
|
#if DBG
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -50,18 +61,43 @@ FREELDR_MEMORY_TYPE MemoryTypeArray[] =
|
||||||
{ LoaderReserve, "Reserve" },
|
{ LoaderReserve, "Reserve" },
|
||||||
};
|
};
|
||||||
ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
|
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
|
#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
|
ULONG
|
||||||
AddMemoryDescriptor(
|
AddMemoryDescriptor(
|
||||||
IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
|
IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
|
||||||
|
@ -70,78 +106,117 @@ AddMemoryDescriptor(
|
||||||
IN PFN_NUMBER PageCount,
|
IN PFN_NUMBER PageCount,
|
||||||
IN TYPE_OF_MEMORY MemoryType)
|
IN TYPE_OF_MEMORY MemoryType)
|
||||||
{
|
{
|
||||||
ULONG i, c;
|
ULONG Index, DescriptCount;
|
||||||
PFN_NUMBER NextBase;
|
PFN_NUMBER EndPage;
|
||||||
TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
|
TRACE("AddMemoryDescriptor(0x%Ix, 0x%Ix, %u)\n",
|
||||||
BasePage, BasePage + PageCount, PageCount);
|
BasePage, PageCount, MemoryType);
|
||||||
|
|
||||||
/* Scan through all existing descriptors */
|
EndPage = BasePage + PageCount;
|
||||||
for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
|
|
||||||
|
/* 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 */
|
Index++;
|
||||||
if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the list is full */
|
/* Count the descriptors */
|
||||||
if (c >= MaxCount) return c;
|
DescriptCount = Index;
|
||||||
|
while (List[DescriptCount].PageCount != 0)
|
||||||
/* Is there an existing descriptor starting before the new range */
|
|
||||||
while ((i < c) && (List[i].BasePage <= BasePage))
|
|
||||||
{
|
{
|
||||||
/* The end of the existing one is the minimum for the new range */
|
DescriptCount++;
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(PageCount > 0);
|
/* Check if the existing range conflicts with the new range */
|
||||||
|
while ((List[Index].PageCount != 0) &&
|
||||||
/* Are there still entries above? */
|
(List[Index].BasePage < EndPage))
|
||||||
if (i < c)
|
|
||||||
{
|
{
|
||||||
/* Shift the following entries one up */
|
TRACE("AddMemoryDescriptor conflict @%lu: new=[%lx:%lx], existing=[%lx,%lx]\n",
|
||||||
RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0]));
|
Index, BasePage, PageCount, List[Index].BasePage, List[Index].PageCount);
|
||||||
|
|
||||||
/* Insert the new range */
|
/*
|
||||||
List[i].BasePage = BasePage;
|
* We have 4 overlapping cases:
|
||||||
List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage);
|
*
|
||||||
List[i].MemoryType = MemoryType;
|
* Case (a) (b) (c) (d)
|
||||||
c++;
|
* Existing range |---| |-----| |---| |---|
|
||||||
|
* New range |---| |---| |-----| |---|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n",
|
/* Check if the existing range starts before the new range (a)/(b) */
|
||||||
i, List[i].BasePage, List[i].PageCount);
|
if (List[Index].BasePage < BasePage)
|
||||||
|
|
||||||
/* Check if the range was trimmed */
|
|
||||||
if (PageCount > List[i].PageCount)
|
|
||||||
{
|
{
|
||||||
/* Recursively process the trimmed part */
|
/* Check if the existing range extends beyond the new range (b) */
|
||||||
c = AddMemoryDescriptor(List,
|
if (List[Index].BasePage + List[Index].PageCount > EndPage)
|
||||||
MaxCount,
|
{
|
||||||
BasePage + List[i].PageCount,
|
/* Split the descriptor */
|
||||||
PageCount - List[i].PageCount,
|
RtlMoveMemory(&List[Index + 1],
|
||||||
MemoryType);
|
&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 */
|
FrLdrBugCheckWithMessage(
|
||||||
TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount);
|
MEMORY_INIT_FAILURE,
|
||||||
List[i].BasePage = BasePage;
|
__FILE__,
|
||||||
List[i].PageCount = PageCount;
|
__LINE__,
|
||||||
List[i].MemoryType = MemoryType;
|
"Ran out of static memory descriptors!");
|
||||||
c++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the new count */
|
/* Insert the new descriptor */
|
||||||
return c;
|
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*
|
const FREELDR_MEMORY_DESCRIPTOR*
|
||||||
|
@ -230,6 +305,9 @@ MmCheckFreeldrImageFile()
|
||||||
OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE,
|
OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE,
|
||||||
OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment);
|
OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the full image size */
|
||||||
|
FrLdrImageSize = (ULONG_PTR)&__ImageBase + OptionalHeader->SizeOfImage - FREELDR_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MmInitializeMemoryManager(VOID)
|
BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
|
@ -287,22 +365,6 @@ BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
return TRUE;
|
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)
|
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue