+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
-
-
-
-
-
-
-
//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
/* 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"
//
#define FREELOADER_MAJOR_VERSION 1
#define FREELOADER_MINOR_VERSION 3
-#define FREELOADER_PATCH_VERSION 0
+#define FREELOADER_PATCH_VERSION 1
PUCHAR GetFreeLoaderVersionString(VOID);
BOOL LinuxHasInitrd = FALSE;
UCHAR LinuxCommandLine[260] = "";
ULONG LinuxCommandLineSize = 0;
+PVOID LinuxKernelLoadAddress = NULL;
+PVOID LinuxInitrdLoadAddress = NULL;
VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
{
{
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;
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);
// 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; )
PFILE LinuxInitrdFile;
UCHAR TempString[260];
ULONG LinuxInitrdSize;
- ULONG LinuxInitrdLoadAddress;
ULONG BytesLoaded;
UCHAR StatusText[260];
// Get the file size
LinuxInitrdSize = GetFileSize(LinuxInitrdFile);
- // Calculate the load address
- if (GetExtendedMemorySize() < 0x4000)
- {
- LinuxInitrdLoadAddress = GetExtendedMemorySize() * 1024; // Load at end of memory
- }
- else
+ // Allocate memory for the ramdisk
+ LinuxInitrdLoadAddress = MmAllocateMemory(LinuxInitrdSize);
+ if (LinuxInitrdLoadAddress == NULL)
{
- LinuxInitrdLoadAddress = 0x4000 * 1024; // Load at end of 16mb
+ return FALSE;
}
- 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
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
}
}
}
+
+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;
+}
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;