Paging
Posted: Tue Feb 28, 2006 5:16 pm
I have tried to create a function to map a virtual address to a physical address but I can't get it to work and my brain has overloaded and crashed... so it would be nice if someone could spot something I missed
Here is my code to map a virtual address (vaddr) to a physical address (paddr)
here is some code how I use it
The problem is that if I don't have this loop bochs just resets and the bochsout.txt says I got a page fault
so if I have my old loop first it works..
why does it work if I run the above loop before I run the loop wit h my code?
Here is my code to map a virtual address (vaddr) to a physical address (paddr)
Code: Select all
int setPageTableEntry( struct PageDirectory_t *pd, unsigned long vaddr, unsigned long paddr, unsigned int flags )
{
kprintf("vaddr 0x%X paddr 0x%X", (unsigned)vaddr, (unsigned int)ALIGN_4KB(paddr));
unsigned int pdentry = ((vaddr/1024)/1024)/4;
kprintf("pdentry %i", pdentry);
/* Page directory entry */
struct PageEntry_t *pde = &pd->Entry[pdentry];
struct PageDirectory_t *pt = NULL;
if( pde->flags & PEF_NOT_SET )
{
if( flags & PEF_NO_ALLOC )
return 0;
/* Needs to allocate a new PageTable */
/* Not implemented yet */
return 0;
}
else if( !(pde->flags & PEF_NOT_SET) )
{
pt = (struct PageDirectory_t *)(unsigned long)(pde->address << 11);
}
else
return 0;
/* Page table entry */
unsigned int ptentry = (vaddr / 4096) % 1024;
struct PageEntry_t *pte = &pt->Entry[ptentry];
kprintf("ptentry %i", ptentry);
if( flags & PEF_CLEAR )
memset( pte, 0, sizeof(struct PageEntry_t) );
if( pte->flags & PEF_NOT_SET )
pte->flags &= ~PEF_NOT_SET;
pte->flags |= 0x7FF & flags;
pte->address = paddr >> 11;
return 1;
}
Code: Select all
for( vaddr=0; vaddr<SIZE_4MB; vaddr+=4096 )
{
setPageTableEntry( &g_KernelPageDirectory, vaddr, vaddr, PEF_PRESENT | PEF_SUPERVISOR | PEF_READWRITE | PEF_CLEAR | PEF_NO_ALLOC);
setPageTableEntry( &g_KernelPageDirectory, (0xC0000000 + vaddr), vaddr, PEF_PRESENT | PEF_SUPERVISOR | PEF_READWRITE | PEF_CLEAR | PEF_NO_ALLOC);
}
so if I have my old loop first it works..
Code: Select all
for( vaddr=0; vaddr<SIZE_4MB; vaddr += 4096 )
{
g_LowPageTable.Entry[vaddr / 4096].flags = 0x3;
g_LowPageTable.Entry[vaddr / 4096].address = (vaddr >> 11);
g_KernelPageTable.Entry[vaddr / 4096].flags = 0x3;
g_KernelPageTable.Entry[vaddr / 4096].address = (vaddr >> 11);
}