I have an higher half kernel, so the code is executing at 0xC0000000 and paging is enabled from the bootloader.
Now I want to create a new, let's say, real page directory.
So my steps are:
1) save registers and disable interrupts
2) allocate a page from the physical memory manager for the page directory
3) create the self referenced entry (asking a physical address)
4) create the kernel 4MB entry (asking a physical address)
5) set CR3
6) restore registers and renable interrupts
I think I got it right, but the code still throws a page fault when accessing the allocated page directory, however that is right because it is a physical address and not a virtual one.
I already checked other questions but I couldn't get it to work, so can you please explain what other steps should I take before accessing new pd?
Here's my code to understand better:
Code: Select all
void vmm_init() {
uint32_t eflags = interrupt_save_disable();
uint32_t *pd = pAllocPage();
uint32_t *self_pde __attribute__((aligned(4096))) = (uint32_t)pAllocPage();
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;
uint32_t *kernel_pde __attribute__((aligned(4096))) = (uint32_t)pAllocPage();
memset(kernel_pde, 0, sizeof(kernel_pde));
*kernel_pde = (_start_addr_phys & 0xFFFFF000) | BIT_PD_PAGE_SIZE | BIT_PD_PT_PRESENT | BIT_PD_PT_RW;
pdv[PAGE_DIRECTORY_INDEX(KERNEL_VIRTUAL_BASE)] = kernel_pde;
set_cr3(pd);
interrupt_restore(eflags);
}