Page 1 of 1

Physical Page Allocation: Wrapping?

Posted: Fri Aug 03, 2007 11:21 pm
by pcmattman
Kevin McGuire wrote a neat page allocation scheme for my OS, but now I've found a small problem in it. I was adding (yet) another module to my OS via the GRUB command line and then suddenly everything started failing. I looked a bit closer and found out that somehow the memory had wrapped around and come back to the space before the kernel.

Now, I don't even get any memory after I hit the 4 MB mark:

Code: Select all

Allocated memory at 0x3bf000
Allocated memory at 0x3c9000
Allocated memory at 0x3d3000
Allocated memory at 0x3dd000
Allocated memory at 0x3e7000
Allocated memory at 0x3f1000
Allocated memory at 0x0
<more 0x0s>
The code for the page allocator is at this location.

I've been working at this for several hours now (short in comparison to other problems) and I'm hoping someone else can find the answer where I can't.

Posted: Sun Aug 05, 2007 2:09 am
by Kevin McGuire
One function needs to be changed:

Code: Select all

/// build dynamic tree to track 4GB of memory.
void pm_init(unsigned long page, unsigned long count)
{
   uint_fast32_t x, y;
   unsigned long *tbl;
   if(count == 1)
   {
      kdbgwarn("mem region ignored because of size.\n");
      return;
   }
   if(page == 0)
   {
      page += 0x1000;
      --count;
   }
   for(x = 0; x < count; ++x)
   {
	for(y = 0; y < ____pm_tes_cnt; ++y)
	{
		if(((page + (x * 4096)) >= ____pm_tes[y].page) && ((page + (x * 4096)) < (____pm_tes[y].page + (____pm_tes[y].count * 4096))))
		{
			// page is protected by ____pm_tes at this moment..
			//kdbginfo("page-protect: %x\n", page + (x * 0x1000));
			goto nn;
		}
  	}
	if(!pm_dir)
	{
		pm_dir = (unsigned long*)(page + (x * 4096));
		kdbginfo("pm_dir at %x\n", pm_dir);
		for(x = 0; x < 1024; ++x)
		{
			pm_dir[x] = 0;
		}
		continue;
	}
      if(!____pm_slack)
      {
         ____pm_slack = page + (x * 4096);
	   kdbginfo("pm_slack: %x\n", ____pm_slack);
      }else{
         if(!pm_dir[(page + (x * 4096))>>22])
         {
            pm_dir[(page + (x * 4096))>>22] = ____pm_slack;
            tbl = (unsigned long*)____pm_slack;
		____pm_slack = 0;
            for(y = 0; y < 1024; ++y)
            {
               tbl[y] = 0;
            }
         }else{
            tbl = (unsigned long*)(pm_dir[(page + (x * 4096))>>22] & 0xFFFFF000);
         }
         tbl[(page + (x * 4096))<<10>>10>>12] = PM_VALID;
      }
	nn:;
   }
   return;
}
It was allocating the directory with out checking the ____pm_tes.

i dont know

Posted: Sun Aug 05, 2007 8:47 am
by com1
i dont know if this will help or not, but your page frames are the same size of your pages, right? if your using virtual memory, the MMU handles the virtual addresses. so you could use some assembly functions (MOV REG,24576)e.g. to send the virtual addresses to the MMU so they can be split.