[FREELDR]

- Modify some memory types to match what windows uses
- Modify PcMemGetBiosMemoryMap, so that is crops free memory to page alignment, while extending non-free memory to page alignment. This way we don't loose small firmware descriptors like the one for the extended bios data area enumerated by the bios. Fixes a warning from win 2003 about not owned memory.
- Modify MempAddMemoryBlock to map LoaderFirmwarePermanent into kernel space like ntldr, but don't map page 0! ntldr doesn't do that either. Also map LoaderXIPRom.
- After generating memory descriptors from the page lookup table, add any descriptor from the bios memory table, that is higher than MmHigestPhysical address, so we don't loose high rom descriptors. Do not map beyond LoaderPagesSpanned.

svn path=/trunk/; revision=53878
This commit is contained in:
Timo Kreuzer 2011-09-27 22:43:52 +00:00
parent bed4f24279
commit 0972356c55
4 changed files with 70 additions and 17 deletions

View file

@ -39,7 +39,7 @@ DBG_DEFAULT_CHANNEL(MEMORY);
#define FILEBUF_PAGE_COUNT (DISKBUF_BASE_PAGE - FILEBUF_BASE_PAGE)
#define DISKBUF_PAGE_COUNT (1)
#define STACK_PAGE_COUNT (STACK_END_PAGE - STACK_BASE_PAGE)
#define BIOSBUF_PAGE_COUNT (0xA0 - BIOSBUF_BASE_PAGE)
#define BIOSBUF_PAGE_COUNT (1)
BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS];
ULONG PcBiosMapCount;
@ -53,7 +53,8 @@ FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] =
{ LoaderFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER
{ LoaderOsloaderStack, STACK_BASE_PAGE, STACK_PAGE_COUNT }, // prot mode stack.
{ LoaderFirmwareTemporary, BIOSBUF_BASE_PAGE, BIOSBUF_PAGE_COUNT }, // BIOSCALLBUFFER
{ LoaderFirmwarePermanent, 0xA0, 0x60 }, // ROM / Video
{ LoaderFirmwarePermanent, 0xA0, 0x50 }, // ROM / Video
{ LoaderSpecialMemory, 0xF0, 0x10 }, // ROM / Video
{ LoaderSpecialMemory, 0xFFF, 1 }, // unusable memory
{ 0, 0, 0 }, // end of map
};
@ -194,6 +195,7 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
REGS Regs;
ULONG MapCount = 0;
ULONGLONG RealBaseAddress, RealSize;
TYPE_OF_MEMORY MemoryType;
ASSERT(PcBiosMapCount == 0);
TRACE("GetBiosMemoryMap()\n");
@ -252,21 +254,40 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi
TRACE("Reserved: 0x%x\n", PcBiosMemoryMap[PcBiosMapCount].Reserved);
TRACE("\n");
/* Align up base of memory area */
RealBaseAddress = ROUND_UP(PcBiosMemoryMap[PcBiosMapCount].BaseAddress, MM_PAGE_SIZE);
RealSize = PcBiosMemoryMap[PcBiosMapCount].Length -
(RealBaseAddress - PcBiosMemoryMap[PcBiosMapCount].BaseAddress);
/* Check if this is free memory */
if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryUsable)
{
MemoryType = LoaderFree;
/* Align up base of memory area */
RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
MM_PAGE_SIZE);
/* Calculate the length after aligning the base */
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
RealSize = ALIGN_DOWN_BY(RealSize, MM_PAGE_SIZE);
}
else
{
if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryReserved)
MemoryType = LoaderFirmwarePermanent;
else
MemoryType = LoaderSpecialMemory;
/* Align down base of memory area */
RealBaseAddress = ALIGN_DOWN_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
MM_PAGE_SIZE);
/* Calculate the length after aligning the base */
RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
RealSize = ALIGN_UP_BY(RealSize, MM_PAGE_SIZE);
}
/* Check if we can add this descriptor */
if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize))
{
TYPE_OF_MEMORY MemoryType;
if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryUsable)
MemoryType = LoaderFree;
else
MemoryType = LoaderFirmwarePermanent;
/* Add the descriptor */
MapCount = AddMemoryDescriptor(PcMemoryMap,
MAX_BIOS_DESCRIPTORS,

View file

@ -22,6 +22,7 @@
#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 */
/* These addresses specify the realmode "BSS section" layout */
#define BSS_RealModeEntry (BSS_START + 0)

View file

@ -735,7 +735,7 @@ WinLdrpLoadAndScanReferencedDll(PLOADER_PARAMETER_BLOCK WinLdrBlock,
//Print(L"Loading referenced DLL: %s\n", FullDllName);
/* Load the image */
Status = WinLdrLoadImage(FullDllName, LoaderSystemCode, &BasePA);
Status = WinLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
if (!Status)
{

View file

@ -48,6 +48,10 @@ static VOID
WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor);
extern PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
extern ULONG BiosMemoryMapEntryCount;
extern ULONG MmLowestPhysicalPage;
extern ULONG MmHighestPhysicalPage;
/* GLOBALS ***************************************************************/
@ -108,20 +112,32 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
Mad[MadCount].PageCount = PageCount;
Mad[MadCount].MemoryType = Type;
//
// Add descriptor
//
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
/* Make sure we don't map too high */
if (BasePage + PageCount > LoaderPagesSpanned) return;
/* Special handling for page 0 */
if (BasePage == 0)
{
/* If its only one page, ignore it! */
if (PageCount == 1) return;
/* Otherwise, skip first page */
BasePage++;
PageCount--;
}
switch (Type)
{
/* Pages used by the loader */
case LoaderLoadedProgram:
case LoaderOsloaderStack:
case LoaderFirmwareTemporary:
case LoaderFirmwarePermanent:
/* Map these pages into user mode */
Status = MempSetupPaging(BasePage, PageCount, FALSE);
break;
@ -129,6 +145,7 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Pages used by the kernel */
case LoaderExceptionBlock:
case LoaderSystemBlock:
case LoaderFirmwarePermanent:
case LoaderSystemCode:
case LoaderHalCode:
case LoaderBootDriver:
@ -142,6 +159,7 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
case LoaderRegistryData:
case LoaderMemoryData:
case LoaderNlsData:
case LoaderXIPRom:
case LoaderOsloaderHeap: // FIXME
/* Map these pages into kernel mode */
Status = MempSetupPaging(BasePage, PageCount, TRUE);
@ -160,7 +178,6 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
// FIXME: not known (not used anyway)
case LoaderReserve:
case LoaderXIPRom:
case LoaderLargePageFiller:
case LoaderErrorLogMemory:
break;
@ -293,6 +310,20 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
}
#endif
/* Now we need to add high descriptors from the bios memory map */
for (i = 0; i < BiosMemoryMapEntryCount; i++)
{
/* Check if its higher than the lookup table */
if (BiosMemoryMap->BasePage > MmHighestPhysicalPage)
{
/* Copy this descriptor */
MempAddMemoryBlock(LoaderBlock,
BiosMemoryMap->BasePage,
BiosMemoryMap->PageCount,
BiosMemoryMap->MemoryType);
}
}
TRACE("MadCount: %d\n", MadCount);
WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!