Switching CR3 to new page directory triple faults
Posted: Thu Dec 02, 2021 7:56 pm
I've made a function to create a new page directory, but switching to it causes a triple fault. I copy entry 0 (and 1022) from the original, and set entry 1023 to recursive page at the copy. Somehow this doesn't work.
The code in question
The other functions and macros
The code in question
Code: Select all
uint32_t mkpdir()
{
uint32_t pd = phys_zalloc_start();
if(!pd) return 0;
((uint32_t*)TEMP_ADDR)[0] = (*MAKE_PGD_ADDR(PGD_RECURSE,0) & 0xfffff000) | 3;
((uint32_t*)TEMP_ADDR)[PGD_TEMP] = (*MAKE_PGD_ADDR(PGD_RECURSE,PGD_TEMP) & 0xfffff000) | 3;
((uint32_t*)TEMP_ADDR)[PGD_RECURSE] = pd | 3;
asm("" ::: "memory");
phys_zalloc_end();
return pd;
}
Code: Select all
#define PGD_TEMP 1022
#define PGD_RECURSE 1023
#define MAKE_PGD_ADDR(pgi, pti) ((uint32_t*)(PGD_RECURSE << 22 | pgi << 12 | pti << 2))
#define TEMP_ADDR ((void*)(PGD_TEMP << 22))
#define PAGE_SIZE 4096
uint32_t phys_zalloc_start() {
uint32_t pg = phys_alloc();
if (!pg) return 0;
*MAKE_PGD_ADDR(PGD_TEMP, 0) = pg | 3;
memset(TEMP_ADDR, 0, PAGE_SIZE);
return pg;
}
void phys_zalloc_end() {
*MAKE_PGD_ADDR(PGD_TEMP, 0) = 0;
uint32_t ta=(uint32_t)TEMP_ADDR;
asm("invlpg %0" :: "m"(ta) : "memory");
}