Page 1 of 1

test physical mm

Posted: Wed Sep 27, 2006 9:52 pm
by xyjamepa
Hi,i've been trying to write a physical memory manager,
and i'm using a stack to handle free physical memory pages
for allocation, but how can i make sure that my work's fine ?
in another way,how can i test my code and determine if it does its jop correctly or it doesn't ?

thanx...

Re:test physical mm

Posted: Wed Sep 27, 2006 10:34 pm
by viral
Hi..
If you have stack filled with addresses of physical pages, then you can pop them one by one and print those addresses on screen. If addresses are valid then you physical mm is working. Try to push, pop, push etc the pages and check again the above test.

Re:test physical mm

Posted: Thu Sep 28, 2006 10:38 am
by ces_mohab
I tried to think of how to write a stack physical allocator but i have the following question
How to allocate multiple contiguous pages?

I can't have a proper answer so I used a bitmap.

Re:test physical mm

Posted: Thu Sep 28, 2006 12:21 pm
by xyjamepa
would you give me your opinion how about this test?

Code: Select all

#define page_size   4096
#define page_shift   12
dword *pagetest;
static dword nballocated;
static dword nbfree;

static dword nballocated;
static dword nbfree;

void allocateall()  //allocate all the pages
{
 dword *addr;
 while(1)
  {
    addr=(dword *)allocframe(0);
    if(!addr) break;
    if(*addr==(dword)addr && addr[(page_size-1)/4]==0x55)
      {
        printf("Error,page at %u already allocated\n",(dword)addr);
        break;
      }
    addr[0]=(dword)addr;
    addr[(page_size-1)/4]=0x55;  //sign that we allocated this page
    pagetest[nballocated]=(dword)addr;
    nballocated++;
    nbfree--;
    state();
  }
}

void freeall()//free all the pages
{
 dword *addr;
 while(1)
  {
   if(!nballocated) break;
   addr=(dword *)pagetest[nballocated-1];
   if(addr[0]!=(dword)addr || addr[(page_size-1)/4]!=0x55)
    {
     printf("Error,page at %u corrupted\n",(dword)addr);
    }
   addr[0]=0; 
   addr[(page_size-1)/4]=0;  //delete the previous sign
   freeframe(((dword)(addr)>>page_shift));
   nbfree++;
   nballocated--;
   state();
  }
}

void testPhysMem()
{
 nballocated=0;

 dword initialnbfree=nbfree=freepages();
 nbfree=freepages();
 printf("testing physical memory manager...\n");
 allocateall();
 if(nballocated!=initialnbfree)
  {
   printf("there were %u free pages but only %u were allocated",
   freepages(),nballocated);

  }
 freeall();
 if(initialnbfree!=freepages())
  {
   printf("there were %u allocated pages but only %u were freed",
   nballocated,nbfree);

  }
 printf("physical memory test ok\n");
}

void state()
{
   moveto(0, 10);
   // MSG: %u frames allocated
   printf("\n%u frames allocated               \n", nballocated);
   // MSG: %u free frames
   printf("\n%u free frames               \n",nbfree);

}

void main()
{
 pagetest = (dword *)bootalloc((memorysize/page_size)*sizeof(dword));
 printf("\n");
 printf("initializing Physical Allocator...");
 phmanager();
 printf("[Done]\n");
 testPhysMem();
}

phmanager():just put the free pages in the stack
How to allocate multiple contiguous pages?
i didn't understand your question clearly...!
but...
first of all
get your memory size
and then your page size
and get your pages number
and push them to the stack as a free pages.
thanx...

Re:test physical mm

Posted: Thu Sep 28, 2006 6:55 pm
by xyjamepa
another question:
can i change the memory size in bochs to become
for example 100mb?

thanx

Re:test physical mm

Posted: Thu Sep 28, 2006 7:38 pm
by Ryu
Yes you can, apply this in bochsrc.txt:

Code: Select all

#=======================================================================
# MEGS
# Set the number of Megabytes of physical memory you want to emulate. 
# The default is 32MB, most OS's won't need more than that.
# The maximum amount of memory supported is 2048Mb.
#=======================================================================

megs: 100


Re:test physical mm

Posted: Thu Sep 28, 2006 10:13 pm
by xyjamepa
thank you Ryu ...
and how about my physical mm
did i test it in the right way or i didn't?

Re:test physical mm

Posted: Thu Sep 28, 2006 10:53 pm
by Brendan
Hi,
ces_mohab wrote:How to allocate multiple contiguous pages?
With free page stacks, you can't allocate contiguous pages, but, for most things the OS doesn't need contiguous pages.

The only place where contiguous pages might be needed is DMA buffers for device drivers. For this there can be other restrictions - must be below 16 MB and can't cross a 64 KB boundary (for ISA DMA), or must be below 4 GB (for 32 bit PCI devices).

To solve this, I use a free page bitmap for all memory below 16 MB. I also have different free page stacks for physical memory above 4 GB and below 4 GB. This means that a 32-bit PCI device that supports "scatter-gather" I/O can use memory from 16 MB to 4 GB, and an ISA device or a 32-bit PCI device that needs a contiguous buffer can use contiguous pages below 16 MB.

There's also a problem with cache efficiency (cache misses are extremely expensive, so reducing the chance of cache misses isn't such a bad idea). Almost all of the CPU's caches are "N-way set associative", which means for any given cache line there's only N positions in the cache where it can go. The position in the cache is determined by some of the bits in the cache line's starting address.

For example, for a given cache the physical address might be broken up such that bits 12 to 15 determine which position it can go in the cache (or the page colour). In this case it can be impossible for a 128 KB array or data structure to fit in a 1 MB cache because bits 12 to 15 of the physical addresses used match. Worst case would be if bits 12 to 15 in all of the physical pages used are identical (or all physical pages have the same page colour), where you might only be able to fit 16 KB of it in the cache at any time (for a 4-way set associative cache). Of course all of this depends on the exact "shape" of the cache.

To make sure this doesn't happen (and improve cache efficiency) some systems use "page colouring" (Windows, Solaris, FreeBSD, etc). The basic idea here is to make sure that contiguous pages in linear memory use physical pages with contiguous "important bits".

The easiest way to do this is to make sure that the important bits in the physical address of a page are the same as the important bits in the linear address of the page. This works, but some linear addresses are used more often than others (for example, most executables might be loaded at linear address 0x00001000). This can lead to uneven usage, where you run out of physical pages for one page colour while there's plenty of free pages for other page colours. This is easily prevented by giving each address space it's own starting page colour.

To implement page colouring using free page stacks, you need a seperate free page stack for each page colour. Then you'd use something like "free_page_stack = (physical_address >> M) & N" to determine which page stack a physical page should be put onto (when freeing pages), and "free_page_stack = ((linear_address >> M) + starting_colour) & N" when allocating a page. The hard part is determining M and N, which depend on the "shape" of the CPUs caches. If you get these values wrong you end up with reduced cache efficiency or a higher chance of uneven page colour usage (worst case would be similar performance to a system that doesn't implement page colouring).


Cheers,

Brendan