Setting Up Paging With PAE
This is a guide to setting up paging with PAE enabled. You should read Setting Up Paging first.
Differences between PAE-Paging and Legacy-Paging
- PAE allows you to access more physical memory, which is usually 64GiB (in fact, this is implementation specific).
- A new data structure is added, the so called 'Page-Directory-Pointer-Table'
- A entry is now 8-byte-wide (Legacy: 4-byte), so the number of entries is halved to 512 (Legacy: 1024)
Setting Up The Data Structures
As mentioned above the 'Page-Directory-Pointer-Table' is added, which contains 4 Page-Directory-Entries
uint64_t page_dir_ptr_tab[4] __attribute__((aligned(0x1000))); // must be aligned to page boundary
Now we need our Page-Directory/-Table
// 512 entries uint64_t page_dir[512] __attribute__((aligned(0x1000))); uint64_t page_tab[512] __attribute__((aligned(0x1000)));
Making it run
Ok, now we have our structures. Now we have to make it run.
page_dir_ptr_tab[0] = (uint64_t)&page_dir | 1; // set the page directory into the PDPT and mark it present page_dir[0] = (uint64_t)&p_tab | 3; //set the page table into the PD and mark it present/writable
Ok, let's map the first 2MiB.
unsigned int i, address = 0; for(i = 0; i < 512; i++) { page_tab[i] = address | 3; // map address and mark it present/writable address = address + 0x1000; }
Ok, pages are mapped. Now we have to set the PAE-bit and load the PDPT into CR3
asm volatile("movl %cr4, %eax; bts $5, %eax; movl %eax, %cr4"); // set bit5 in CR4 to enable PAE asm volatile ("movl %%eax, %%cr3" :: "a" (&page_dir_ptr_tab)); // load PDPT into CR3
The last thing we need to do is activating paging. Simply done:
asm volatile ("movl %cr0, %eax; orl $0x80000000, %eax; movl %eax, %cr0;");
PAE-Paging should be now enabled.