Memory Manager
Posted: Sun Jun 17, 2007 4:39 am
Does this look like a start to a good physical memory manager?
Code: Select all
////////////////////////////////////////////////////
// PHYSICAL MEMORY MANAGER
char physPagesBitmap[65536]; // 1 Byte represents 8 Pages of 4KB
void _setPhysPageState( unsigned long page, char state ) {
unsigned long off = page / (8 * 4096);
unsigned long bit = (page % (8 * 4096)) / 4096;
physPageBitmap [off] = state << bit;
}
char _queryPhysPageState( unsigned long page) {
unsigned long off = page / (8 * 4096);
unsigned long bit = (page % (8 * 4096)) / 4096;
return physPageBitmap [off] & ( 1 << bit);
}
int initPhysMemMgr(unsigned long physSize) {
unsigned long addrSEnd = (unsigned long)&end; //End of kernel (somewhere above 1MB)
unsigned long startMem = addrEnd + (addrEnd%4096==0?0:4096-addrSEnd);
unsigned long endMem = physSize - (physSize%4096==0?0:physSize%4096);
if(startMem % 4096 != 0) { // Should never get here, unless something wrong above
////////////////////
//Error Handling
return 0;
}
unsigned long pageIndex = 0;
for(;(pageIndex < 2048 * 1024 * 1024) & pageIndex < ;pageIndex += 4096) {
if(pageIndex < startMem) {
_setPhysPageState(pageIndex,1); // 1 Means allocated
} else if(pageIndex >= startMem && pageIndex < endMem) {
_setPhysPageState(pageIndex,0); // 0 means unallocated
} else // pageIndex >= endMem
_setPhysPageState(pageIndex,1); // 1 means allocated + reserved
}
return 1; // always here
}
void* allocPhysPage( void ) {
unsigned long base = 0;
for(;base < 65536;base++)
if(physPagesBitmap[base] != 0xFF)
break;
if(base >= 65536)
return NULL;
unsigned long page = base * (8*4096) ;
unsigned long offset = 0;
for(;offset<8;offset++;page+=4096) {
if( _queryPhysPageState(page) == 0) {
_setPhysPageState(page, 1);
break;
}
}
if(offset >=8)
return NULL;
else
return (void*)page;
}
void freePhysPage( void* page ) {
unsigned long _page = (unsigned long)page;
if(_page < startMem)
return;
else if(_page >= endMem)
return;
else
_setPhysPageState(_page,0);
}