Virtual Memory : Mapping pages problem
Posted: Sat Aug 07, 2004 3:49 am
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
The physical memory manager uses a bitmap method to allocate physical memory at the moment.
Here's my test for the MemMapPage function
Any ideas as to what could be the problem?
CloudNine
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;
}
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");
CloudNine