From 0972356c55e3077439668287cdf8cfacaa8fed65 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 27 Sep 2011 22:43:52 +0000 Subject: [PATCH] [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 --- .../boot/freeldr/freeldr/arch/i386/pcmem.c | 47 ++++++++++++++----- .../freeldr/include/arch/pc/x86common.h | 1 + .../boot/freeldr/freeldr/windows/peloader.c | 2 +- .../boot/freeldr/freeldr/windows/wlmemory.c | 37 +++++++++++++-- 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c index 53900d6ed94..e6cb2de5357 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -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, diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h index 44a24c4e047..b2205f0d138 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h @@ -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) diff --git a/reactos/boot/freeldr/freeldr/windows/peloader.c b/reactos/boot/freeldr/freeldr/windows/peloader.c index af2861f5209..cd115b7a398 100644 --- a/reactos/boot/freeldr/freeldr/windows/peloader.c +++ b/reactos/boot/freeldr/freeldr/windows/peloader.c @@ -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) { diff --git a/reactos/boot/freeldr/freeldr/windows/wlmemory.c b/reactos/boot/freeldr/freeldr/windows/wlmemory.c index 92c8b119575..be59059acd4 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlmemory.c +++ b/reactos/boot/freeldr/freeldr/windows/wlmemory.c @@ -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!