Virtual Memory : Mapping pages problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
CloudNine

Virtual Memory : Mapping pages problem

Post by CloudNine »

Hi,

I've been rewriting my operating system (in C++ )to provide full virtual memory support, but it seems I'm falling at the first hurdle. I try to map the pages, but the processor page-faults with a page not present error, even though I have mapped the page ???

Here's my virtual.cpp, containing paging init code and the MemMapPage method

Code: Select all

int VirtualMemManager::Init()
{
 m_pageDirectory=(DWORD*)defPageManager.AllocatePage();

 DWORD* firstPageTable=(DWORD*)defPageManager.AllocatePage();

 if (!m_pageDirectory || !firstPageTable)
 {
    defConsole.Write("Out of memory in VirtualMemManager::Init");
 }

 DWORD address=0;

 for (int i=0; i<1024; i++)
 {
    firstPageTable[i]=address | 7;
    address+=4096;
 }

 m_pageDirectory[0]=(DWORD)firstPageTable | 7;

 //Map it to itself so we can keep track of physical addresses of tables and the directory.
 //Pretty much required for MemMapRange and friends
 m_pageDirectory[1023]=(DWORD)m_pageDirectory | 7;

 for (int i=1; i<1023; i++)
 {
    m_pageDirectory[i]=0;
 }

 //Put page directory address in cr3
 setcr3((DWORD)m_pageDirectory);

 defConsole.Print("pageDirectory = %u\n",m_pageDirectory);

 //Enable paging in the control register
 setcr0(getcr0() | 0x80000000);

 return true;
}

//Maps a page of virtual memory to a page of physical memory
int VirtualMemManager::MemMapPage(DWORD virtualAddress,DWORD physicalAddress)
{
   DWORD* address=(DWORD*)m_pageDirectory[1023];

   int dirEntry=(virtualAddress >> 22);
   int tableEntry=(virtualAddress >> 12)-((virtualAddress >> 22)*1024);

   defConsole.Print("dirEntry = %d\ntableEntry = %d\n",dirEntry,tableEntry);

   DWORD* pt=NULL;

   //Get the directory entry of the virtual address, going through the mapped page directory
   if (address[dirEntry] == 0)
   {
      DWORD page=defPageManager.AllocatePage();
      defConsole.Write("New page table is being created\n");
      defConsole.Print("page = %u\n",page);
      address[dirEntry]= page | 7;

      pt=(DWORD*)(address[dirEntry] & 0xFFFFF000);
   }

   pt=(DWORD*)(address[dirEntry] & 0xFFFFF000);
   defConsole.Print("pt = %u\n",pt);
   pt[tableEntry]=physicalAddress | 7;

   asm volatile("invlpg %0" :: "m"(virtualAddress));

   return true;
}
The physical memory manager uses a bitmap method to allocate physical memory at the moment.

Here's my test for the MemMapPage function

Code: Select all

    for (int i=0; i<1024; i++)
    {
       MemMapPage(0xC0000000+(i*4096),physPageManager.AllocatePage());
       DWORD* a=(DWORD*)0xC0000000+(i*4096);
*a=0xDEADBEEF;
    }

    asm("sti");
Any ideas as to what could be the problem?

CloudNine
bkilgore

Re:Virtual Memory : Mapping pages problem

Post by bkilgore »

When you go to map a page, you are getting the physical address of the page directory and using that to write to memory. This is not going to work once paging is enabled. You saved the physical address in pagedirectory[1023], which means that you can access the array of page tables starting at 0xFFC00000, and the page directory itself at 0xFFFFF000.

use these virtual addresses, not the physical address you stored, to edit the directory and tables once paging is enabled. The purpose of saving the address of the directory in the directory itself is not to load it back out later, but to allow the use of these high virtual addresses to edit the directory and tables.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Virtual Memory : Mapping pages problem

Post by Pype.Clicker »

what does CR2 contains at the time of the fault ? If you can also get EIP and general register values, you almost found the faulty access.
Post Reply