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

svn path=/trunk/; revision=3027
This commit is contained in:
Brian Palmer 2002-06-08 19:20:01 +00:00
parent 6eab84796a
commit 20327bf11a
7 changed files with 117 additions and 22 deletions

View file

@ -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

View file

@ -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

View file

@ -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 <brianp@sginet.com>"
#define AUTHOR_EMAIL "<brianp@sginet.com>"
#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);

View file

@ -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; BytesLoaded<LinuxKernelSize; )
@ -391,7 +412,6 @@ BOOL LinuxReadInitrd(VOID)
PFILE LinuxInitrdFile;
UCHAR TempString[260];
ULONG LinuxInitrdSize;
ULONG LinuxInitrdLoadAddress;
ULONG BytesLoaded;
UCHAR StatusText[260];
@ -411,19 +431,15 @@ BOOL LinuxReadInitrd(VOID)
// Get the file size
LinuxInitrdSize = GetFileSize(LinuxInitrdFile);
// Calculate the load address
if (GetExtendedMemorySize() < 0x4000)
// Allocate memory for the ramdisk
LinuxInitrdLoadAddress = MmAllocateMemory(LinuxInitrdSize);
if (LinuxInitrdLoadAddress == NULL)
{
LinuxInitrdLoadAddress = GetExtendedMemorySize() * 1024; // Load at end of memory
return FALSE;
}
else
{
LinuxInitrdLoadAddress = 0x4000 * 1024; // Load at end of 16mb
}
LinuxInitrdLoadAddress -= ROUND_UP(LinuxInitrdSize, 4096);
// Set the information in the setup struct
LinuxSetupSector->RamdiskAddress = LinuxInitrdLoadAddress;
LinuxSetupSector->RamdiskAddress = (ULONG)LinuxInitrdLoadAddress;
LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
// Read in the ramdisk

View file

@ -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

View file

@ -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;
}

View file

@ -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;