mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
- Finally switch to the new memory manager, which is compatible both with ReactOS and NT-style boot types.
- Added: memory types for each allocation request, ability to alloc and free memory from the heap, ability to use 1 megabyte of low memory too (which was just wasted previously). - Removed: a bunch of hacky stuff. svn path=/trunk/; revision=32031
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <[email protected]>
|
||||
* Copyright (C) 2006-2008 Aleksey Bragin <[email protected]>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -43,6 +43,9 @@ ULONG TotalPagesInLookupTable = 0;
|
||||
ULONG FreePagesInLookupTable = 0;
|
||||
ULONG LastFreePageHint = 0;
|
||||
|
||||
extern ULONG_PTR MmHeapPointer;
|
||||
extern ULONG_PTR MmHeapStart;
|
||||
|
||||
BOOLEAN MmInitializeMemoryManager(VOID)
|
||||
{
|
||||
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
||||
@@ -93,12 +96,58 @@ BOOLEAN MmInitializeMemoryManager(VOID)
|
||||
MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable, BiosMemoryMap, BiosMemoryMapEntryCount);
|
||||
MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
|
||||
|
||||
// Add machine-dependent stuff
|
||||
// FIXME: this is only for i386
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // realmode int vectors
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // freeldr stack + cmdline
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages)
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x78, 8, LoaderOsloaderStack); // prot mode stack. BIOSCALLBUFFER
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x80, 0x10, LoaderOsloaderHeap); // File system read buffer. FILESYSBUFFER
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x90, 0x10, LoaderOsloaderHeap); // Disk read buffer for int 13h. DISKREADBUFFER
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0xA0, 0x60, LoaderFirmwarePermanent); // ROM / Video
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0xFFF, 1, LoaderSpecialMemory); // unusable memory
|
||||
|
||||
// This one is strange, without it WinNT crashes with PHASE0_EXCEPTION
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x59, 0x5, LoaderFirmwarePermanent);
|
||||
|
||||
FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
|
||||
|
||||
MmInitializeHeap(PageLookupTableAddress);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID MmInitializeHeap(PVOID PageLookupTable)
|
||||
{
|
||||
ULONG PagesNeeded;
|
||||
ULONG HeapStart;
|
||||
|
||||
// HACK: Make it so it doesn't overlap kernel space
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, LoaderSystemCode);
|
||||
|
||||
// Find contigious memory block for HEAP:STACK
|
||||
PagesNeeded = HEAP_PAGES + STACK_PAGES;
|
||||
HeapStart = MmFindAvailablePages(PageLookupTable, TotalPagesInLookupTable, PagesNeeded, FALSE);
|
||||
|
||||
// Unapply the hack
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, LoaderFree);
|
||||
|
||||
if (HeapStart == 0)
|
||||
{
|
||||
UiMessageBox("Critical error: Can't allocate heap!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize BGET
|
||||
bpool(HeapStart << MM_PAGE_SHIFT, PagesNeeded << MM_PAGE_SHIFT);
|
||||
|
||||
// Mark those pages as used
|
||||
MmMarkPagesInLookupTable(PageLookupTableAddress, HeapStart, PagesNeeded, LoaderOsloaderHeap);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Heap initialized, base 0x%08x, pages %d\n", (HeapStart << MM_PAGE_SHIFT), PagesNeeded));
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type)
|
||||
{
|
||||
@@ -188,13 +237,21 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map
|
||||
RtlCopyMemory(TempBiosMemoryMap, BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
||||
MmSortBiosMemoryMap(TempBiosMemoryMap, MapCount);
|
||||
|
||||
// Find a place, starting from the highest memory
|
||||
// (thus leaving low memory for kernel/drivers)
|
||||
for (Index=(MapCount-1); Index>=0; Index--)
|
||||
{
|
||||
// If this is usable memory with a big enough length
|
||||
// then we'll put our page lookup table here
|
||||
if (TempBiosMemoryMap[Index].Type == BiosMemoryUsable && TempBiosMemoryMap[Index].Length >= PageLookupTableSize)
|
||||
|
||||
// skip if this is not usable region
|
||||
if (TempBiosMemoryMap[Index].Type != BiosMemoryUsable)
|
||||
continue;
|
||||
|
||||
if (TempBiosMemoryMap[Index].Length >= PageLookupTableSize)
|
||||
{
|
||||
PageLookupTableMemAddress = (PVOID)(ULONG)(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize));
|
||||
PageLookupTableMemAddress = (PVOID)(ULONG)
|
||||
(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +298,7 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_ME
|
||||
// Mark every page as allocated initially
|
||||
// We will go through and mark pages again according to the memory map
|
||||
// But this will mark any holes not described in the map as allocated
|
||||
MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, 1);
|
||||
MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent);
|
||||
|
||||
for (Index=0; Index<MapCount; Index++)
|
||||
{
|
||||
@@ -254,8 +311,9 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_ME
|
||||
}
|
||||
|
||||
// Mark the low memory region below 1MB as reserved (256 pages in region)
|
||||
DbgPrint((DPRINT_MEMORY, "Marking the low 1MB region as reserved.\n"));
|
||||
MmMarkPagesInLookupTable(PageLookupTable, 0, 256, LoaderFirmwarePermanent);
|
||||
//FIXME: Not needed now since we mark low 1Mb with really used and free areas
|
||||
//DbgPrint((DPRINT_MEMORY, "Marking the low 1MB region as reserved.\n"));
|
||||
//MmMarkPagesInLookupTable(PageLookupTable, 0, 256, LoaderFirmwarePermanent);
|
||||
|
||||
// Mark the pages that the lookup table occupies as reserved
|
||||
PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
|
||||
@@ -271,10 +329,12 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page
|
||||
|
||||
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
|
||||
{
|
||||
#if 0
|
||||
if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Index = %d StartPage = %d PageCount = %d\n", Index, StartPage, PageCount));
|
||||
}
|
||||
#endif
|
||||
RealPageLookupTable[Index].PageAllocated = PageAllocated;
|
||||
RealPageLookupTable[Index].PageAllocationLength = (PageAllocated != LoaderFree) ? 1 : 0;
|
||||
}
|
||||
@@ -288,7 +348,7 @@ VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG
|
||||
|
||||
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
|
||||
{
|
||||
RealPageLookupTable[Index].PageAllocated = LoaderSystemCode;
|
||||
RealPageLookupTable[Index].PageAllocated = MemoryType;
|
||||
RealPageLookupTable[Index].PageAllocationLength = (Index == StartPage) ? PageCount : 0;
|
||||
}
|
||||
}
|
||||
@@ -326,7 +386,8 @@ ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG Pa
|
||||
if (FromEnd)
|
||||
{
|
||||
/* Allocate "high" (from end) pages */
|
||||
for (Index=LastFreePageHint-1; Index>0; Index--)
|
||||
for (Index=/*LastFreePageHint-1*/LOADER_HIGH_ZONE-1; Index>0; Index--)
|
||||
//for (Index=LastFreePageHint-1; Index>0; Index--)
|
||||
{
|
||||
if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <[email protected]>
|
||||
* Copyright (C) 2006-2008 Aleksey Bragin <[email protected]>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,36 +20,11 @@
|
||||
#include <freeldr.h>
|
||||
#include <debug.h>
|
||||
|
||||
ULONG AllocationCount = 0;
|
||||
|
||||
#ifdef DBG
|
||||
VOID VerifyHeap(VOID);
|
||||
VOID DumpMemoryAllocMap(VOID);
|
||||
VOID IncrementAllocationCount(VOID);
|
||||
VOID DecrementAllocationCount(VOID);
|
||||
VOID MemAllocTest(VOID);
|
||||
#endif // DBG
|
||||
|
||||
/*
|
||||
* Hack alert
|
||||
* Normally, we allocate whole pages. This is ofcourse wastefull for small
|
||||
* allocations (a few bytes). So, for small allocations (smaller than a page)
|
||||
* we sub-allocate. When the first small allocation is done, a page is
|
||||
* requested. We keep a pointer to that page in SubAllocationPage. The alloc
|
||||
* is satisfied by returning a pointer to the beginning of the page. We also
|
||||
* keep track of how many bytes are still available in the page in SubAllocationRest.
|
||||
* When the next small request comes in, we try to allocate it just after the
|
||||
* memory previously allocated. If it won't fit, we allocate a new page and
|
||||
* the whole process starts again.
|
||||
* Note that suballocations are done back-to-back, there's no bookkeeping at all.
|
||||
* That also means that we cannot really free suballocations. So, when a free is
|
||||
* done and it is determined that this might be a free of a sub-allocation, we
|
||||
* just no-op the free.
|
||||
* Perhaps we should use the heap routines from ntdll here.
|
||||
*/
|
||||
static PVOID SubAllocationPage = NULL;
|
||||
static unsigned SubAllocationRest = 0;
|
||||
|
||||
BOOLEAN AllocateFromEnd = TRUE;
|
||||
|
||||
VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd)
|
||||
@@ -71,12 +46,6 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||
}
|
||||
|
||||
MemorySize = ROUND_UP(MemorySize, 4);
|
||||
if (MemorySize <= SubAllocationRest)
|
||||
{
|
||||
MemPointer = (PVOID)((ULONG_PTR)SubAllocationPage + MM_PAGE_SIZE - SubAllocationRest);
|
||||
SubAllocationRest -= MemorySize;
|
||||
return MemPointer;
|
||||
}
|
||||
|
||||
// Find out how many blocks it will take to
|
||||
// satisfy this allocation
|
||||
@@ -86,7 +55,7 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||
// then return NULL
|
||||
if (FreePagesInLookupTable < PagesNeeded)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize));
|
||||
UiMessageBoxCritical("Memory allocation failed: out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -95,7 +64,7 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||
|
||||
if (FirstFreePageFromEnd == (ULONG)-1)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize));
|
||||
UiMessageBoxCritical("Memory allocation failed: out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -105,16 +74,8 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||
FreePagesInLookupTable -= PagesNeeded;
|
||||
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
|
||||
|
||||
if (MemorySize < MM_PAGE_SIZE)
|
||||
{
|
||||
SubAllocationPage = MemPointer;
|
||||
SubAllocationRest = MM_PAGE_SIZE - MemorySize;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DBG
|
||||
IncrementAllocationCount();
|
||||
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, FirstFreePageFromEnd));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation pointer: 0x%x\n", MemPointer));
|
||||
//VerifyHeap();
|
||||
#endif // DBG
|
||||
@@ -123,6 +84,39 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||
return MemPointer;
|
||||
}
|
||||
|
||||
PVOID MmHeapAlloc(ULONG MemorySize)
|
||||
{
|
||||
PVOID Result;
|
||||
LONG CurAlloc, TotalFree, MaxFree, NumberOfGets, NumberOfRels;
|
||||
|
||||
if (MemorySize > MM_PAGE_SIZE)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Consider using other functions to allocate %d bytes of memory!\n", MemorySize));
|
||||
}
|
||||
|
||||
// Get the buffer from BGET pool
|
||||
Result = bget(MemorySize);
|
||||
|
||||
if (Result == NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Heap allocation for %d bytes failed\n", MemorySize));
|
||||
}
|
||||
|
||||
// Gather some stats
|
||||
bstats(&CurAlloc, &TotalFree, &MaxFree, &NumberOfGets, &NumberOfRels);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
|
||||
CurAlloc, TotalFree, NumberOfGets, NumberOfRels));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
VOID MmHeapFree(PVOID MemoryPointer)
|
||||
{
|
||||
// Release the buffer to the pool
|
||||
brel(MemoryPointer);
|
||||
}
|
||||
|
||||
PVOID MmAllocateMemory(ULONG MemorySize)
|
||||
{
|
||||
// Temporary forwarder...
|
||||
@@ -155,7 +149,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
|
||||
"Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
|
||||
"AllocationCount: %d\n", MemorySize, PagesNeeded, FreePagesInLookupTable, AllocationCount));
|
||||
"\n", MemorySize, PagesNeeded, FreePagesInLookupTable));
|
||||
UiMessageBoxCritical("Memory allocation failed: out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -163,8 +157,8 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_
|
||||
if (MmAreMemoryPagesAvailable(PageLookupTableAddress, TotalPagesInLookupTable, DesiredAddress, PagesNeeded) == FALSE)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
|
||||
"Not enough free memory to allocate %d bytes at address %p. AllocationCount: %d\n",
|
||||
MemorySize, DesiredAddress, AllocationCount));
|
||||
"Not enough free memory to allocate %d bytes at address %p.\n",
|
||||
MemorySize, DesiredAddress));
|
||||
|
||||
// Don't tell this to user since caller should try to alloc this memory
|
||||
// at a different address
|
||||
@@ -178,8 +172,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_
|
||||
MemPointer = (PVOID)(StartPageNumber * MM_PAGE_SIZE);
|
||||
|
||||
#ifdef DBG
|
||||
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, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, StartPageNumber));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation pointer: 0x%x\n", MemPointer));
|
||||
//VerifyHeap();
|
||||
#endif // DBG
|
||||
@@ -213,7 +206,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress
|
||||
// then return NULL
|
||||
if (FreePagesInLookupTable < PagesNeeded)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize));
|
||||
UiMessageBoxCritical("Memory allocation failed: out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -222,7 +215,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress
|
||||
|
||||
if (FirstFreePageFromEnd == 0)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize));
|
||||
UiMessageBoxCritical("Memory allocation failed: out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -233,8 +226,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress
|
||||
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
|
||||
|
||||
#ifdef DBG
|
||||
IncrementAllocationCount();
|
||||
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, FirstFreePageFromEnd));
|
||||
DbgPrint((DPRINT_MEMORY, "Memory allocation pointer: 0x%x\n", MemPointer));
|
||||
//VerifyHeap();
|
||||
#endif // DBG
|
||||
@@ -245,141 +237,9 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress
|
||||
|
||||
VOID MmFreeMemory(PVOID MemoryPointer)
|
||||
{
|
||||
ULONG PageNumber;
|
||||
ULONG PageCount;
|
||||
ULONG Idx;
|
||||
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
// Make sure we didn't get a bogus pointer
|
||||
if (MemoryPointer >= (PVOID)(TotalPagesInLookupTable * MM_PAGE_SIZE))
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Bogus memory pointer (0x%x) passed to MmFreeMemory()\n", MemoryPointer));
|
||||
}
|
||||
#endif // DBG
|
||||
|
||||
// Find out the page number of the first
|
||||
// page of memory they allocated
|
||||
PageNumber = MmGetPageNumberFromAddress(MemoryPointer);
|
||||
PageCount = RealPageLookupTable[PageNumber].PageAllocationLength;
|
||||
|
||||
#ifdef DBG
|
||||
// Make sure we didn't get a bogus pointer
|
||||
if ((PageCount < 1) || (PageCount > (TotalPagesInLookupTable - PageNumber)))
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Invalid page count in lookup table. PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
|
||||
}
|
||||
|
||||
// Loop through our array check all the pages
|
||||
// to make sure they are allocated with a length of 0
|
||||
for (Idx=PageNumber+1; Idx<(PageNumber + PageCount); Idx++)
|
||||
{
|
||||
if ((RealPageLookupTable[Idx].PageAllocated == LoaderFree) ||
|
||||
(RealPageLookupTable[Idx].PageAllocationLength != 0))
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Invalid page entry in lookup table, PageAllocated should = 1 and PageAllocationLength should = 0 because this is not the first block in the run. PageLookupTable[%d].PageAllocated = %d PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocated, PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* If this allocation is only a single page, it could be a sub-allocated page.
|
||||
* Just don't free it */
|
||||
if (1 == PageCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through our array and mark all the
|
||||
// blocks as free
|
||||
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
|
||||
{
|
||||
RealPageLookupTable[Idx].PageAllocated = LoaderFree;
|
||||
RealPageLookupTable[Idx].PageAllocationLength = 0;
|
||||
}
|
||||
|
||||
FreePagesInLookupTable += PageCount;
|
||||
|
||||
#ifdef DBG
|
||||
DecrementAllocationCount();
|
||||
DbgPrint((DPRINT_MEMORY, "Freed %d pages of memory starting at page %d. AllocationCount: %d\n", PageCount, PageNumber, AllocationCount));
|
||||
//VerifyHeap();
|
||||
#endif // DBG
|
||||
}
|
||||
|
||||
PVOID MmHeapAlloc(ULONG MemorySize)
|
||||
{
|
||||
// Temporary forwarder...
|
||||
return MmAllocateMemoryWithType(MemorySize, LoaderOsloaderHeap);
|
||||
}
|
||||
|
||||
VOID MmHeapFree(PVOID MemoryPointer)
|
||||
{
|
||||
// Stub for WinLdr
|
||||
}
|
||||
|
||||
|
||||
#ifdef DBG
|
||||
VOID VerifyHeap(VOID)
|
||||
{
|
||||
ULONG Idx;
|
||||
ULONG Idx2;
|
||||
ULONG Count;
|
||||
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
|
||||
|
||||
if (DUMP_MEM_MAP_ON_VERIFY)
|
||||
{
|
||||
DumpMemoryAllocMap();
|
||||
}
|
||||
|
||||
// Loop through the array and verify that
|
||||
// everything is kosher
|
||||
for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
|
||||
{
|
||||
// Check if this block is allocated
|
||||
if (RealPageLookupTable[Idx].PageAllocated != LoaderFree)
|
||||
{
|
||||
// This is the first block in the run so it
|
||||
// had better have a length that is within range
|
||||
if ((RealPageLookupTable[Idx].PageAllocationLength < 1) || (RealPageLookupTable[Idx].PageAllocationLength > (TotalPagesInLookupTable - Idx)))
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Allocation length out of range in heap table. PageLookupTable[Idx].PageAllocationLength = %d\n", RealPageLookupTable[Idx].PageAllocationLength));
|
||||
}
|
||||
|
||||
// Now go through and verify that the rest of
|
||||
// this run has the blocks marked allocated
|
||||
// with a length of zero but don't check the
|
||||
// first one because we already did
|
||||
Count = RealPageLookupTable[Idx].PageAllocationLength;
|
||||
for (Idx2=1; Idx2<Count; Idx2++)
|
||||
{
|
||||
// Make sure it's allocated
|
||||
if (RealPageLookupTable[Idx + Idx2].PageAllocated == LoaderFree)
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Lookup table indicates hole in memory allocation. RealPageLookupTable[Idx + Idx2].PageAllocated == 0\n"));
|
||||
}
|
||||
|
||||
// Make sure the length is zero
|
||||
if (RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0)
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Allocation chain has non-zero value in non-first block in lookup table. RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// Move on to the next run
|
||||
Idx += (Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nope, not allocated so make sure the length is zero
|
||||
if (RealPageLookupTable[Idx].PageAllocationLength != 0)
|
||||
{
|
||||
BugCheck((DPRINT_MEMORY, "Free block is start of memory allocation. RealPageLookupTable[Idx].PageAllocationLength != 0\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID DumpMemoryAllocMap(VOID)
|
||||
{
|
||||
@@ -393,7 +253,7 @@ VOID DumpMemoryAllocMap(VOID)
|
||||
if ((Idx % 32) == 0)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "%x:\t", (Idx * MM_PAGE_SIZE)));
|
||||
DbgPrint((DPRINT_MEMORY, "%08x:\t", (Idx * MM_PAGE_SIZE)));
|
||||
}
|
||||
else if ((Idx % 4) == 0)
|
||||
{
|
||||
@@ -455,47 +315,6 @@ VOID DumpMemoryAllocMap(VOID)
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "\n"));
|
||||
}
|
||||
|
||||
VOID IncrementAllocationCount(VOID)
|
||||
{
|
||||
AllocationCount++;
|
||||
}
|
||||
|
||||
VOID DecrementAllocationCount(VOID)
|
||||
{
|
||||
AllocationCount--;
|
||||
}
|
||||
|
||||
VOID MemAllocTest(VOID)
|
||||
{
|
||||
PVOID MemPtr1;
|
||||
PVOID MemPtr2;
|
||||
PVOID MemPtr3;
|
||||
PVOID MemPtr4;
|
||||
PVOID MemPtr5;
|
||||
|
||||
MemPtr1 = MmAllocateMemory(4096);
|
||||
printf("MemPtr1: 0x%x\n", (int)MemPtr1);
|
||||
MachConsGetCh();
|
||||
MemPtr2 = MmAllocateMemory(4096);
|
||||
printf("MemPtr2: 0x%x\n", (int)MemPtr2);
|
||||
MachConsGetCh();
|
||||
MemPtr3 = MmAllocateMemory(4096);
|
||||
printf("MemPtr3: 0x%x\n", (int)MemPtr3);
|
||||
DumpMemoryAllocMap();
|
||||
VerifyHeap();
|
||||
MachConsGetCh();
|
||||
|
||||
MmFreeMemory(MemPtr2);
|
||||
MachConsGetCh();
|
||||
|
||||
MemPtr4 = MmAllocateMemory(2048);
|
||||
printf("MemPtr4: 0x%x\n", (int)MemPtr4);
|
||||
MachConsGetCh();
|
||||
MemPtr5 = MmAllocateMemory(4096);
|
||||
printf("MemPtr5: 0x%x\n", (int)MemPtr5);
|
||||
MachConsGetCh();
|
||||
}
|
||||
#endif // DBG
|
||||
|
||||
ULONG GetSystemMemorySize(VOID)
|
||||
|
||||
Reference in New Issue
Block a user