I am trying to make my own Operating System. I got interrupts working, some keyboard and mouse drivers, basic video and printing functions. Now I want to get into memory management and tasks and the first thing I realized is that I need paging which I have yet to set up properly.
I followed some guides and tutorials on it, the most primary one being the setting up paging tutorial in osdev wiki (https://wiki.osdev.org/Setting_Up_Paging). I "wrote" (copied and pasted basically) the following code in order to initialize paging.
void initPaging()
{
unsigned int i;
for(i = 0; i < 1024; i++)
{
// This sets the following flags to the pages:
// Supervisor: Only kernel-mode can access them
// Write Enabled: It can be both read from and written to
// Not Present: The page table is not present
page_directory[i] = 0x00000002;
}
//we will fill all 1024 entries in the table, mapping 4 megabytes
for(i = 0; i < 1024; i++)
{
// As the address is page aligned, it will always leave 12 bits zeroed.
// Those bits are used by the attributes ;)
first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
}
page_directory[0] = ((unsigned int)first_page_table) | 3;
enablePaging(page_directory);
}
The enablePaging function loads the page directory to cr3 and then enables paging by setting the PG bit in cr0.
The problem is after calling this if I call anything else like a printk it causes a page fault. I think that is because I don't identity page the kernel or something. In my page fault handler, I move the error code to eax and check the registers in qemu monitor. The error code is 0x00000020 which is
0 1 0 - Supervisory process tried to write to a non-present page entry
TL;DR
I cannot call anything else after enabling paging, do I need to map my kernel? How do I do that? What else is wrong?
This is my code on github: https://github.com/Danyy427/PagingOsdev
Edit:
Registers after the exception

My exception handler:
void isr14_handler(interrupt_frame_t *frame)
{
//panic("Page Fault");
unsigned int err = frame->err_code;
//asm(".intel_syntax noprefix");
asm("mov %0, %%eax "::"r"(err));
while(1);
}
I commented out panic as it causes a double fault which causes triple fault. I put error code into eax and code hangs which is intended.