Changes in v1.3.1 (6/8/2002)
authorBrian Palmer <brianp@sginet.com>
Sat, 8 Jun 2002 19:20:01 +0000 (19:20 +0000)
committerBrian Palmer <brianp@sginet.com>
Sat, 8 Jun 2002 19:20:01 +0000 (19:20 +0000)
- Implemented MmAllocateMemoryAtAddress()
- Fixed Linux boot code to go through the memory manager to allocate memory at 1MB

svn path=/trunk/; revision=3027

freeldr/CHANGELOG
freeldr/freeldr/include/mm.h
freeldr/freeldr/include/version.h
freeldr/freeldr/linuxboot.c
freeldr/freeldr/mm/mem.h
freeldr/freeldr/mm/meminit.c
freeldr/freeldr/mm/mm.c

index 43ff3a1..57bf86f 100644 (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
index 8633c00..7249e6f 100644 (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
index 66da3bd..f12ced8 100644 (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);
index 06cf522..617362d 100644 (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)
-       {
-               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
index 94e5c0d..71a392d 100644 (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
index 8a26b24..b7b6bf1 100644 (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;
+}
index 7c333a0..eab4341 100644 (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;