The address of the page table is a virtual address, wheter the page dir needs to be loaded with a real address for the cpu to understand. Or am i wrong?
Also, the same problem happens when u create a new process, create a page dir for it ( in virtual memory). But now u need to load the real addres of the page dir in register CR3.
So some kind of mapping is needed. As i read, a possibility is recursive mapping of pages.
I have organized the physical memory in pages. For each page, using tis page nr, its physical address can be computed as page nr * PAGZE_SIZE.
i have a function/allocator (vm_request_mem), which allocates real pages. Now, i wrote a function which returns a page table/direcotry:
uint32 *alloc_pagetable()
{
vm_page_frame *page = vm_request_mem();
// lock page
page->flags = (VM_READ | VM_WRITE | VM_LOCKED);
uint32 *real_addr = (uint32 *) PAGE_SIZE*page->p-nr;
uint32 i;
for( i =0; i++; i<1023)
real_addr = 0 | 2; //initialize all entries as unused
/* sets its last item, item 1023, to its real address */
real_addr[1023] = real_addr | 3;
return real_addr;
}
// when u need the real address of some page table/directory
uint32 *getRealAddrPagetable(vm_page_frame *p)
{
return (uint32 *) p[1023];
}
So the last item (1023) of a page table stores its real address.
Is this what i meant by recursive mapping?
But there is a problem then, what if the process to which this page table belongs, tries to access item 1023?
e.g. for page dir entry 0, page table entry 1023, this is virtual address : 0*4MB + 1023 * 4096B = 0x003FF000
This will map to the physical address of this pagetable!
SDo i do this wrong?
Is there a simpler/better way to do this mapping?
I think memory management is the most complex part of a kernel
