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