OSDev.org

The Place to Start for Operating System Developers
It is currently Sun Apr 28, 2024 11:37 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Cottontail Mem Management/Implementation
PostPosted: Fri Mar 25, 2005 11:17 am 
Hows this look? Just for note, I am in protected mode with GDT set up and A20 enabled. Memory map set to 0 already.

Cottontail Mem Management tutorial as found at http://osdever.net/tutorials/cottontailmm.php?the_id=47.

Heres code (Alloc only, I commented it tediously):

Code:
#define MAP_BASE  0x10000000 //Start at 256mb mark
#define PAGE_BASE 0x10020000 //Start page map
#define MEM_BASE  0x10020400 //There are 2^20 pages, starting here

#define MICRO_PAGES 0x00100000 //Micro Pages/Mem Base (4kb/each)
#define SUPER_PAGES 0x00000400 //Super Pages/Start of each page (4mb/each)

unsigned long *MicroMap = MAP_BASE;
unsigned long *PageMap = PAGE_BASE;

const int CheckAND[] = { //So we can & to see what page is used in the longs (set of 32)
2^0, 2^1, 2^2, 2^3, 2^4, 2^5, 2^6, 2^7, 2^8, 2^9, 2^10, 2^11,
2^12, 2^13, 2^14, 2^15, 2^16, 2^17, 2^18, 2^19, 2^20, 2^21,
2^22, 2^23, 2^24, 2^25, 2^26, 2^27, 2^28, 2^29, 2^30, 2^31};

void* AllocPage(){                 //Allocate 4kb block
int i = 0, x = 0, Page = 0;       //i and x are counting vars, Page is superpage to use
void* newpage;                    //so we can return the final pointer
while(PageMap[i] == 0xFFFFFFFF){  //While the Super Page is used in this list 1-32...
  i++;                             //Keep searching
  if(i >= SUPER_PAGES)return NULL; //No more room, abort!
}                                 //We leave 'i' with set of 32 that has free superpage
for(x=0; x<32; x++){              //Now search through set of 32 for that free one
  if( !(PageMap[i] & CheckAND[x]) ){ //if this is a free of the 32 super pages....
   Page = x + i*32;                //make this our page, (rem., 'x' is within 32,
   break;                          // so make it like a two-dim array like [super][mini])
  }
}
i = 0;                            //Reset counter caus' we saved it in Page
while(MicroMap[i+Page*1024] == 0xFFFFFFFF){ //Search for free Micropage set in Superpage
  i++;                                     //Haven't found one yet
  if(i >= MICRO_PAGES/SUPER_PAGES)return NULL; //Should never get her unless weird error
}                                             //Since it said there was 1(or more) free
                                               //up there in the for loop
for(x=0; x<32; x++){                          //Find Page within set of 32 micropages
  if(! (MicroMap[i+Page*1024] & CheckAND[x]) ){ //Found one?
   newpage = (void*)(MEM_BASE+((i+Page*1024)*32+x)*4096); //Make ptr. to the actual mem
   MicroMap[i+Page*1024] |= CheckAND[x];             //Mark it as used....
   return newpage;                                //Return a page of free memory!
  }                                               //(Finally)
}
}


Top
  
 
 Post subject: Re:Cottontail Mem Management/Implementation
PostPosted: Fri Mar 25, 2005 11:41 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
imvho looks rather unreadable (here at least. with proportionnal font, the 'two column' coding style is rather ugly :P)

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Cottontail Mem Management/Implementation
PostPosted: Fri Mar 25, 2005 11:49 am 
Iself use a stack where the free memory addresses are pushed on. When I alloc a page, I only have to pop off the latest address and there is a page alloced. Cleaner, shorter and faster ;)


Top
  
 
 Post subject: Re:Cottontail Mem Management/Implementation
PostPosted: Fri Mar 25, 2005 3:31 pm 
Poseidon_away wrote:
Cleaner, shorter and faster


For allocation and deallocation of single inspecific pages. Consider the isAllocated() and AllocateContiguous() functions, which with a stack are dirtier, longer, and slower.

Less used, maybe, but still useful.

isAllocated(), among other things, is useful for checking to make sure you didn't attempt to free a page twice. This should never happen, but no one writes perfect code. So the check finds bugs, and helps you avoid data corruption. Consider what happens to a stack if you accidently push the same address on twice.

AllocateContiguous() you might want for DMA and such things. Pulling contiguous pages off a stack? Ick.


Top
  
 
 Post subject: Re:Cottontail Mem Management/Implementation
PostPosted: Fri Mar 25, 2005 3:52 pm 
Maybe my code will show you a way how to do allocation and deallocation!

Code:
//---------------------------
//   global vars
uint32_t mem_total_4kb= 1024;
uint32_t mem_total_4mb= 0;
uint32_t *bitmap_4kb= (uint32_t *)0xc0001000;
uint32_t *bitmap_4mb_1= (uint32_t *)0xc0021000;
uint32_t *bitmap_4mb_2= (uint32_t *)0xc0021080;
uint32_t free_first_4kb=0x100;
uint32_t free_first_4mb=1;
uint32_t free_4kb=0;
uint32_t free_4mb=0;

#define set_bit_makro(x,bit_nr) x|= (1 << bit_nr)
#define del_bit_makro(x,bit_nr) x&= ~(1 << bit_nr)
#define get_bit_makro(x,bit_nr) x& (1 << bit_nr)

uint32_t alloc_4kb_phys()
{
   register uint32_t x,y;
   uint32_t phys_addr;

   if(free_4kb == 0)
      return 0;

   x= free_first_4kb >> 5;
   y= free_first_4kb & 0x1f;

   del_bit_makro(bitmap_4kb[x],y);

   phys_addr= free_first_4kb << 12;

   free_4kb--;
   if(free_4kb == 0)
      return phys_addr;
   /////////////////////////
   //we need a new free 4MiB page
   if((free_first_4kb >> 10) == free_first_4mb)
   {
      x= free_first_4mb >> 5;
      y= free_first_4mb & 0x1f;
      del_bit_makro(bitmap_4mb_1[x],y);
      while(1)
      {
         if(bitmap_4mb_1[x] != 0)
            break;
         x++;
      }
      asm("bsf %0,%1"
         :"=r"(y)
         :"r"(bitmap_4mb_1[x]));
      free_first_4mb= (x << 5) + y;
      free_4mb--;
   }
   //end search of new 4MiB page
   /////////////////////////
   //we need a new 4KiB page
   x= free_first_4kb >> 5;
   while(1)
   {
      if(bitmap_4kb[x] != 0)
         break;
      x++;
      /////////////////////////
      //the old 4MiB page is full => search a new one with >0 free 4KiB pages
      if((x & 0x1f) == 0)
      {
         x>>= 5;
         x--;
         y= x & 0x1f;
         x>>= 5;
         del_bit_makro(bitmap_4mb_2[x],y);
         while(1)
         {
            if(bitmap_4mb_2[x] != 0)
               break;
            x++;
         }
         asm("bsf %0,%1"
            :"=r"(y)
            :"r"(bitmap_4mb_2[x]));
         x= ((x << 5) + y) << 5;
      }
      //end search for 4MiB page with >0 4KiB pages
      /////////////////////////
   }
   asm("bsf %0,%1"
      :"=r"(y)
      :"r"(bitmap_4kb[x]));
   free_first_4kb= (x << 5) + y;
   //end search of new 4KiB page
   /////////////////////////

   return phys_addr;
}

uint32_t dealloc_4kb_phys(uint32_t addr)
{
   register uint32_t x,y;

   if((addr & 0xfff) != 0)
      return 0;

   x= addr >> 12;
   y= x & 0x1f;
   x>>= 5;

   if(get_bit_makro(bitmap_4kb[x],y))
      return 0;

   set_bit_makro(bitmap_4kb[x],y);

   x>>= 5;
   y= x & 0x1f;
   x>>= 5;
   set_bit_makro(bitmap_4mb_2[x],y);

   free_4kb++;

   if((addr >> 12) < free_first_4kb)
      free_first_4kb= addr >> 12;
   /////////////////////////
   //check if the whole 4MiB page is free now
   x= addr >> 17;
   for(y= 0; y <= 31; y++)
      if(bitmap_4kb[x+y] == 0)
         return 1;
   /////////////////////////
   //set 4MiB page free
   x>>= 5;
   y= x & 0x1f;
   x>>= 5;

   set_bit_makro(bitmap_4mb_1[x],y);

   if(((x << 5) + y) < free_first_4mb)
      free_first_4mb= (x << 5) + y;

   free_4mb++;

   return 1;
}

uint32_t alloc_4mb_phys()
{
   register uint32_t x,y,z;
   uint32_t phys_addr;

   if(free_4mb == 0)
      return 0;

   x= free_first_4mb >> 5;
   y= free_first_4mb & 0x1f;

   del_bit_makro(bitmap_4mb_1[x],y);
   del_bit_makro(bitmap_4mb_2[x],y);

   for(z= 0; z <= 31; z++)
   {
      bitmap_4kb[(((x << 5) + y) << 5) + z]= 0xffffffff;
   }

   phys_addr= ((x << 5) + y) << 22;

   free_4mb--;
   free_4kb-= 1024;
   if(free_4mb == 0)
      return phys_addr;

   if((free_first_4kb >> 10) == free_first_4mb)
   {
      /////////////////////////
      //we need a new free 4KiB page
      x= 0;
      while(1)
      {
         if(bitmap_4mb_2[x] != 0)
            break;
         x++;
      }

      asm("bsf %0,%1"
         :"=r"(y)
         :"r"(bitmap_4mb_2[x]));
      x= ((x << 5) + y) << 5;
      while(1)
      {
         if(bitmap_4kb[x] != 0)
            break;
         x++;
      }
      asm("bsf %0,%1"
         :"=r"(y)
         :"r"(bitmap_4kb[x]));
      free_first_4kb= (x << 5) + y;
      //end search
      /////////////////////////
   }
   /////////////////////////
   //find new free 4MiB page
   x= 0;
   while(1)
   {
      if(bitmap_4mb_1[x] != 0)
         break;
      x++;
   }
   //end search
   /////////////////////////
   asm("bsf %0,%1"
      :"=r"(y)
      :"r"(bitmap_4mb_1[x]));
   free_first_4mb= (x << 5) + y;

   return phys_addr;
}

uint32_t dealloc_4mb_phys(uint32_t addr)
{
   register uint32_t x,y;

   if((addr & 0x3fffff) != 0)
      return 0;

   x= addr >> 17;
   y= (x >> 5) & 0x1f;

   if(get_bit_makro(bitmap_4mb_1[x>>10],y))
      return 0;

   for(y= 0; y <= 31; y++)
      bitmap_4kb[x+y]= 0xffffffff;

   x>>= 5;
   y= x & 0x1f;
   x>>= 5;
   set_bit_makro(bitmap_4mb_1[x],y);
   set_bit_makro(bitmap_4mb_2[x],y);

   free_4mb++;
   free_4kb+= 1024;

   x= addr >> 12;
   if(x < free_first_4kb)
      free_first_4kb= x;

   return 1;
}


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 15 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group