I'm working on paging. At the moment I only finished the init function while mapping and unmapping is still undone.
This is the init:
Code:
void vmm_init() {
uint32_t eflags = interrupt_save_disable();
uint32_t *pd __attribute__((aligned(4096))) = kmalloc();
/**
* Using the 'recursive mapping' technique.
*/
uint32_t self_pde;
memset(&self_pde, 0, sizeof(self_pde));
self_pde |= (uint32_t)pd | BIT_PD_PT_PRESENT | BIT_PD_PT_RW;
pd[PAGE_DIRECTORY_INDEX(PD_VADDR)] = self_pde;
/**
* Mapping the kernel to a 4MB page.
*/
uint32_t kernel_pde;
memset(&kernel_pde, 0, sizeof(kernel_pde));
kernel_pde |= BIT_PD_PT_PRESENT | BIT_PD_PT_RW | BIT_PD_PAGE_SIZE;
pd[PAGE_DIRECTORY_INDEX(KERNEL_VIRTUAL_BASE)] = (uint32_t)kernel_pde;
set_cr3((uint32_t)pd);
interrupt_restore(eflags);
}
The problem is that I can access pd until I set it as the "official" page directory. In fact when later I try to map a page (or just print it), it Page Faults.
Could you please help me? Am I missing something? Thanks.
This is the mapping code if you need it:
Code:
#define PD_VADDR 0xFFFFF000
#define PAGE_DIRECTORY_ADDR_OFFSET 22
#define PAGE_TABLE_ADDR_OFFSET 12
#define PAGE_DIRECTORY_INDEX(x) (((x) >> PAGE_DIRECTORY_ADDR_OFFSET) & 0x3ff)
#define PAGE_TABLE_INDEX(x) (((x) >> PAGE_TABLE_ADDR_OFFSET) & 0x3ff)
...
uint32_t map_page(uint32_t *phys, uint32_t *virt, uint32_t flags) {
uint32_t *pd = PD_VADDR;
uint32_t *pde = pd[(PAGE_DIRECTORY_INDEX((uint32_t)virt))];
if (!(*pde & BIT_PD_PT_PRESENT)) {
// Need to create a new page table
uint32_t pde_phys = kmalloc();
memset(&pde, 0, sizeof(pde));
*pde |= pde_phys;
pd[PAGE_DIRECTORY_INDEX((uint32_t)pde)] = pde;
memset(PD_INDEX_TO_PT_VADDR(PAGE_DIRECTORY_INDEX((uint32_t)virt)), 0b10, PAGE_SIZE);
pd[PAGE_DIRECTORY_INDEX((uint32_t)pde)] |= flags;
}
uint32_t *pte = pde[PAGE_TABLE_INDEX((uint32_t)virt)];
memset(&pte, 0, sizeof(pte));
*pte |= (uint32_t)phys | flags;
pde[PAGE_TABLE_INDEX((uint32_t)virt)] = pte;
pd[PAGE_DIRECTORY_INDEX((uint32_t)virt)] = pde;
return 0;
}
It crashes as soon as pd[
something] is accessed.