Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmm.c
Go to the documentation of this file.
00001 /* 00002 * FreeLoader 00003 * Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 00020 #include <freeldr.h> 00021 #include <debug.h> 00022 00023 #if DBG 00024 VOID DumpMemoryAllocMap(VOID); 00025 VOID MemAllocTest(VOID); 00026 #endif // DBG 00027 00028 DBG_DEFAULT_CHANNEL(MEMORY); 00029 00030 PFN_NUMBER LoaderPagesSpanned = 0; 00031 00032 PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType) 00033 { 00034 PFN_NUMBER PagesNeeded; 00035 PFN_NUMBER FirstFreePageFromEnd; 00036 PVOID MemPointer; 00037 00038 if (MemorySize == 0) 00039 { 00040 WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n"); 00041 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes."); 00042 return NULL; 00043 } 00044 00045 MemorySize = ROUND_UP(MemorySize, 4); 00046 00047 // Find out how many blocks it will take to 00048 // satisfy this allocation 00049 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE; 00050 00051 // If we don't have enough available mem 00052 // then return NULL 00053 if (FreePagesInLookupTable < PagesNeeded) 00054 { 00055 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize); 00056 UiMessageBoxCritical("Memory allocation failed: out of memory."); 00057 return NULL; 00058 } 00059 00060 FirstFreePageFromEnd = MmFindAvailablePages(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, FALSE); 00061 00062 if (FirstFreePageFromEnd == 0) 00063 { 00064 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize); 00065 UiMessageBoxCritical("Memory allocation failed: out of memory."); 00066 return NULL; 00067 } 00068 00069 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType); 00070 00071 FreePagesInLookupTable -= PagesNeeded; 00072 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE); 00073 00074 TRACE("Allocated %d bytes (%d pages) of memory (type %ld) starting at page 0x%lx.\n", 00075 MemorySize, PagesNeeded, MemoryType, FirstFreePageFromEnd); 00076 TRACE("Memory allocation pointer: 0x%x\n", MemPointer); 00077 00078 // Update LoaderPagesSpanned count 00079 if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned) 00080 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT); 00081 00082 // Now return the pointer 00083 return MemPointer; 00084 } 00085 00086 PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType) 00087 { 00088 PFN_NUMBER PagesNeeded; 00089 PFN_NUMBER StartPageNumber; 00090 PVOID MemPointer; 00091 00092 if (MemorySize == 0) 00093 { 00094 WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n"); 00095 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes."); 00096 return NULL; 00097 } 00098 00099 // Find out how many blocks it will take to 00100 // satisfy this allocation 00101 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE; 00102 00103 // Get the starting page number 00104 StartPageNumber = MmGetPageNumberFromAddress(DesiredAddress); 00105 00106 // If we don't have enough available mem 00107 // then return NULL 00108 if (FreePagesInLookupTable < PagesNeeded) 00109 { 00110 ERR("Memory allocation failed in MmAllocateMemoryAtAddress(). " 00111 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). " 00112 "\n", MemorySize, PagesNeeded, FreePagesInLookupTable); 00113 UiMessageBoxCritical("Memory allocation failed: out of memory."); 00114 return NULL; 00115 } 00116 00117 if (MmAreMemoryPagesAvailable(PageLookupTableAddress, TotalPagesInLookupTable, DesiredAddress, PagesNeeded) == FALSE) 00118 { 00119 WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). " 00120 "Not enough free memory to allocate %d bytes at address %p.\n", 00121 MemorySize, DesiredAddress); 00122 00123 // Don't tell this to user since caller should try to alloc this memory 00124 // at a different address 00125 //UiMessageBoxCritical("Memory allocation failed: out of memory."); 00126 return NULL; 00127 } 00128 00129 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType); 00130 00131 FreePagesInLookupTable -= PagesNeeded; 00132 MemPointer = (PVOID)((ULONG_PTR)StartPageNumber * MM_PAGE_SIZE); 00133 00134 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, StartPageNumber); 00135 TRACE("Memory allocation pointer: 0x%x\n", MemPointer); 00136 00137 // Update LoaderPagesSpanned count 00138 if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned) 00139 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT); 00140 00141 // Now return the pointer 00142 return MemPointer; 00143 } 00144 00145 VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType) 00146 { 00147 PFN_NUMBER PagesNeeded; 00148 PFN_NUMBER StartPageNumber; 00149 00150 // Find out how many blocks it will take to 00151 // satisfy this allocation 00152 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE; 00153 00154 // Get the starting page number 00155 StartPageNumber = MmGetPageNumberFromAddress(MemoryAddress); 00156 00157 // Set new type for these pages 00158 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, NewType); 00159 } 00160 00161 PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType) 00162 { 00163 PFN_NUMBER PagesNeeded; 00164 PFN_NUMBER FirstFreePageFromEnd; 00165 PFN_NUMBER DesiredAddressPageNumber; 00166 PVOID MemPointer; 00167 00168 if (MemorySize == 0) 00169 { 00170 WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n"); 00171 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes."); 00172 return NULL; 00173 } 00174 00175 // Find out how many blocks it will take to 00176 // satisfy this allocation 00177 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE; 00178 00179 // Get the page number for their desired address 00180 DesiredAddressPageNumber = (ULONG_PTR)DesiredAddress / MM_PAGE_SIZE; 00181 00182 // If we don't have enough available mem 00183 // then return NULL 00184 if (FreePagesInLookupTable < PagesNeeded) 00185 { 00186 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize); 00187 UiMessageBoxCritical("Memory allocation failed: out of memory."); 00188 return NULL; 00189 } 00190 00191 FirstFreePageFromEnd = MmFindAvailablePagesBeforePage(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, DesiredAddressPageNumber); 00192 00193 if (FirstFreePageFromEnd == 0) 00194 { 00195 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize); 00196 UiMessageBoxCritical("Memory allocation failed: out of memory."); 00197 return NULL; 00198 } 00199 00200 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType); 00201 00202 FreePagesInLookupTable -= PagesNeeded; 00203 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE); 00204 00205 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, FirstFreePageFromEnd); 00206 TRACE("Memory allocation pointer: 0x%x\n", MemPointer); 00207 00208 // Update LoaderPagesSpanned count 00209 if ((((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT) > LoaderPagesSpanned) 00210 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT); 00211 00212 // Now return the pointer 00213 return MemPointer; 00214 } 00215 00216 VOID MmFreeMemory(PVOID MemoryPointer) 00217 { 00218 } 00219 00220 #if DBG 00221 00222 VOID DumpMemoryAllocMap(VOID) 00223 { 00224 PFN_NUMBER Idx; 00225 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress; 00226 00227 DbgPrint("----------- Memory Allocation Bitmap -----------\n"); 00228 00229 for (Idx=0; Idx<TotalPagesInLookupTable; Idx++) 00230 { 00231 if ((Idx % 32) == 0) 00232 { 00233 DbgPrint("\n"); 00234 DbgPrint("%08x:\t", (Idx * MM_PAGE_SIZE)); 00235 } 00236 else if ((Idx % 4) == 0) 00237 { 00238 DbgPrint(" "); 00239 } 00240 00241 switch (RealPageLookupTable[Idx].PageAllocated) 00242 { 00243 case LoaderFree: 00244 DbgPrint("*"); 00245 break; 00246 case LoaderBad: 00247 DbgPrint( "-"); 00248 break; 00249 case LoaderLoadedProgram: 00250 DbgPrint("O"); 00251 break; 00252 case LoaderFirmwareTemporary: 00253 DbgPrint("T"); 00254 break; 00255 case LoaderFirmwarePermanent: 00256 DbgPrint( "P"); 00257 break; 00258 case LoaderOsloaderHeap: 00259 DbgPrint("H"); 00260 break; 00261 case LoaderOsloaderStack: 00262 DbgPrint("S"); 00263 break; 00264 case LoaderSystemCode: 00265 DbgPrint("K"); 00266 break; 00267 case LoaderHalCode: 00268 DbgPrint("L"); 00269 break; 00270 case LoaderBootDriver: 00271 DbgPrint("B"); 00272 break; 00273 case LoaderStartupPcrPage: 00274 DbgPrint("G"); 00275 break; 00276 case LoaderRegistryData: 00277 DbgPrint("R"); 00278 break; 00279 case LoaderMemoryData: 00280 DbgPrint("M"); 00281 break; 00282 case LoaderNlsData: 00283 DbgPrint("N"); 00284 break; 00285 case LoaderSpecialMemory: 00286 DbgPrint("C"); 00287 break; 00288 default: 00289 DbgPrint("?"); 00290 break; 00291 } 00292 } 00293 00294 DbgPrint("\n"); 00295 } 00296 #endif // DBG 00297 00298 PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries) 00299 { 00300 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress; 00301 00302 *NoEntries = TotalPagesInLookupTable; 00303 00304 return RealPageLookupTable; 00305 } 00306 Generated on Sat May 26 2012 04:18:03 for ReactOS by
1.7.6.1
|