This is the init:
Code: Select all
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);
}
Could you please help me? Am I missing something? Thanks.
This is the mapping code if you need it:
Code: Select all
#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;
}