diff --git a/freeldr/CHANGELOG b/freeldr/CHANGELOG index 43ff3a19c72..57bf86faa4d 100644 --- a/freeldr/CHANGELOG +++ b/freeldr/CHANGELOG @@ -1,3 +1,8 @@ +Changes in v1.3.1 (6/8/2002) + +- Implemented MmAllocateMemoryAtAddress() +- Fixed Linux boot code to go through the memory manager to allocate memory at 1MB + Changes in v1.3 (6/5/2002) - Added protected mode exception handling in case FreeLoader crashes diff --git a/freeldr/freeldr/include/mm.h b/freeldr/freeldr/include/mm.h index 8633c006a53..7249e6fe480 100644 --- a/freeldr/freeldr/include/mm.h +++ b/freeldr/freeldr/include/mm.h @@ -48,19 +48,12 @@ ULONG GetBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32]); // Fills mem_map stru - - - - - - - //BOOL MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength); BOOL MmInitializeMemoryManager(VOID); PVOID MmAllocateMemory(ULONG MemorySize); VOID MmFreeMemory(PVOID MemoryPointer); //PVOID MmAllocateLowMemory(ULONG MemorySize); //VOID MmFreeLowMemory(PVOID MemoryPointer); -//PVOID MmAllocateMemoryFrom1Mb(ULONG MemorySize); +PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress); #endif // defined __MEMORY_H diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index 66da3bd30b1..f12ced86ab8 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -22,7 +22,7 @@ /* just some stuff */ -#define VERSION "FreeLoader v1.3" +#define VERSION "FreeLoader v1.3.1" #define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer " #define AUTHOR_EMAIL "" #define BY_AUTHOR "by Brian Palmer" @@ -36,7 +36,7 @@ // #define FREELOADER_MAJOR_VERSION 1 #define FREELOADER_MINOR_VERSION 3 -#define FREELOADER_PATCH_VERSION 0 +#define FREELOADER_PATCH_VERSION 1 PUCHAR GetFreeLoaderVersionString(VOID); diff --git a/freeldr/freeldr/linuxboot.c b/freeldr/freeldr/linuxboot.c index 06cf522876a..617362dbb88 100644 --- a/freeldr/freeldr/linuxboot.c +++ b/freeldr/freeldr/linuxboot.c @@ -41,6 +41,8 @@ UCHAR LinuxInitrdName[260]; BOOL LinuxHasInitrd = FALSE; UCHAR LinuxCommandLine[260] = ""; ULONG LinuxCommandLineSize = 0; +PVOID LinuxKernelLoadAddress = NULL; +PVOID LinuxInitrdLoadAddress = NULL; VOID LoadAndBootLinux(PUCHAR OperatingSystemName) { @@ -150,9 +152,19 @@ LinuxBootFailed: { MmFreeMemory(LinuxSetupSector); } + if (LinuxKernelLoadAddress != NULL) + { + MmFreeMemory(LinuxKernelLoadAddress); + } + if (LinuxInitrdLoadAddress != NULL) + { + MmFreeMemory(LinuxInitrdLoadAddress); + } LinuxBootSector = NULL; LinuxSetupSector = NULL; + LinuxKernelLoadAddress = NULL; + LinuxInitrdLoadAddress = NULL; SetupSectorSize = 0; NewStyleLinuxKernel = FALSE; LinuxKernelSize = 0; @@ -320,9 +332,9 @@ BOOL LinuxReadSetupSector(PFILE LinuxKernelFile) BOOL LinuxReadKernel(PFILE LinuxKernelFile) { - PVOID LoadAddress = (PVOID)LINUX_KERNEL_LOAD_ADDRESS; ULONG BytesLoaded; UCHAR StatusText[260]; + PVOID LoadAddress; sprintf(StatusText, "Loading %s", LinuxKernelName); UiDrawStatusText(StatusText); @@ -331,6 +343,15 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile) // Calc kernel size LinuxKernelSize = GetFileSize(LinuxKernelFile) - (512 + SetupSectorSize); + // Allocate memory for Linux kernel + LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS); + if (LinuxKernelLoadAddress != (PVOID)LINUX_KERNEL_LOAD_ADDRESS) + { + return FALSE; + } + + LoadAddress = LinuxKernelLoadAddress; + // Read linux kernel to 0x100000 (1mb) SetFilePointer(LinuxKernelFile, 512 + SetupSectorSize); for (BytesLoaded=0; BytesLoadedRamdiskAddress = LinuxInitrdLoadAddress; + LinuxSetupSector->RamdiskAddress = (ULONG)LinuxInitrdLoadAddress; LinuxSetupSector->RamdiskSize = LinuxInitrdSize; // Read in the ramdisk diff --git a/freeldr/freeldr/mm/mem.h b/freeldr/freeldr/mm/mem.h index 94e5c0d8cce..71a392ddfd3 100644 --- a/freeldr/freeldr/mm/mem.h +++ b/freeldr/freeldr/mm/mem.h @@ -59,6 +59,7 @@ VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded); // Returns the page number of the first available page range from the end of memory VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], PULONG MapCount); // Removes entries in the memory map that describe memory above 4G -VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCountVOID); // Sets the LastFreePageHint to the last usable page of memory +VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount); // Sets the LastFreePageHint to the last usable page of memory +BOOL MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount); // Returns TRUE if the specified pages of memory are available, otherwise FALSE #endif // defined __MEM_H diff --git a/freeldr/freeldr/mm/meminit.c b/freeldr/freeldr/mm/meminit.c index 8a26b24de90..b7b6bf1cd65 100644 --- a/freeldr/freeldr/mm/meminit.c +++ b/freeldr/freeldr/mm/meminit.c @@ -400,3 +400,31 @@ VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount) } } } + +BOOL MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount) +{ + PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable; + ULONG StartPage; + ULONG Index; + + StartPage = MmGetPageNumberFromAddress(PageAddress); + + // Make sure they aren't trying to go past the + // end of availabe memory + if ((StartPage + PageCount) > TotalPageCount) + { + return FALSE; + } + + for (Index=StartPage; Index<(StartPage + PageCount); Index++) + { + // If this page is allocated then there obviously isn't + // memory availabe so return FALSE + if (RealPageLookupTable[Index].PageAllocated != 0) + { + return FALSE; + } + } + + return TRUE; +} diff --git a/freeldr/freeldr/mm/mm.c b/freeldr/freeldr/mm/mm.c index 7c333a0bb3d..eab4341138e 100644 --- a/freeldr/freeldr/mm/mm.c +++ b/freeldr/freeldr/mm/mm.c @@ -86,6 +86,58 @@ PVOID MmAllocateMemory(ULONG MemorySize) return MemPointer; } +PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress) +{ + ULONG PagesNeeded; + ULONG StartPageNumber; + PVOID MemPointer; + + if (MemorySize == 0) + { + DbgPrint((DPRINT_MEMORY, "MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n")); + UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes."); + return NULL; + } + + // Find out how many blocks it will take to + // satisfy this allocation + PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE; + + // Get the starting page number + StartPageNumber = MmGetPageNumberFromAddress(DesiredAddress); + + // If we don't have enough available mem + // then return NULL + if (FreePagesInLookupTable < PagesNeeded) + { + DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + UiMessageBoxCritical("Memory allocation failed: out of memory."); + return NULL; + } + + if (MmAreMemoryPagesAvailable(PageLookupTableAddress, TotalPagesInLookupTable, DesiredAddress, PagesNeeded) == FALSE) + { + DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + UiMessageBoxCritical("Memory allocation failed: out of memory."); + return NULL; + } + + MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded); + + FreePagesInLookupTable -= PagesNeeded; + MemPointer = (PVOID)(StartPageNumber * MM_PAGE_SIZE); + +#ifdef DEBUG + IncrementAllocationCount(); + DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, StartPageNumber, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation pointer: 0x%x\n", MemPointer)); + //VerifyHeap(); +#endif // DEBUG + + // Now return the pointer + return MemPointer; +} + VOID MmFreeMemory(PVOID MemoryPointer) { ULONG PageNumber;