Paging: Difference between revisions

m
Add 5-level paging and improve code indent
[unchecked revision][unchecked revision]
mNo edit summary
m (Add 5-level paging and improve code indent)
Line 1:
[[image:Paging_Structure.gif|right|thumb|600x350px|x86 Paging Structure]]
 
Paging is a system which allows each process to see a full virtual address space, without actually requiring the full amount of physical memory to be available or present. 32-bit x86 processors support 32-bit virtual addresses and 4-GiB virtual address spaces, and current 64-bit processors support 48-bit virtual addressing and 256-TiB virtual address spaces. Intel has released [https://en.wikipedia.org/wiki/Intel_5-level_paging documentation] for a planned extension to 57-bit virtual addressing and 128-PiB virtual address spaces. Currently, implementations of x86-64 have a limit of between 4 GiB and 256 TiB of physical address space (and an architectural limit of 4 PiB of physical address space).
 
In addition to this, paging introduces the benefit of page-level protection. In this system, user processes can only see and modify data which is paged in on their own address space, providing hardware-based isolation. System pages are also protected from user processes. On the x86-64 architecture, page-level protection now completely supersedes [[Segmentation]] as the memory protection mechanism. On the IA-32 architecture, both paging and segmentation exist, but segmentation is now considered 'legacy'.
Line 49:
=== Example ===
 
Say the kernel is loaded to 0x100000. However, it needed to be remapped to 0xc0000000. After loading the kernel, it'll initiate paging, and set up the appropriate tables. (See [[Higher Half Kernel]]) After [[Identity Paging]] the first megabyte,it'll need to create a second table (ie. at entry #768 in the paging directory.) to map 0x100000 to 0xc00000000xC0000000. The code may be like:
 
<source lang="asm">
Line 110:
 
<source lang="C">
void * get_physaddr(void * virtualaddr) {
{
unsigned long pdindex = (unsigned long)virtualaddr >> 22;
unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
 
unsigned long * pd = (unsigned long *)0xFFFFF000;
// Here you need to check whether the PD entry is present.
 
unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
// Here you need to check whether the PT entry is present.
 
Line 128 ⟶ 127:
 
<source lang="C">
void map_page(void * physaddr, void * virtualaddr, unsigned int flags) {
{
// Make sure that both addresses are page-aligned.
 
unsigned long pdindex = (unsigned long)virtualaddr >> 22;
unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
 
unsigned long * pd = (unsigned long *)0xFFFFF000;
// Here you need to check whether the PD entry is present.
// When it is not present, you need to create a new empty PT and
// adjust the PDE accordingly.
 
unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
// Here you need to check whether the PT entry is present.
// When it is, then there is already a mapping present. What do you do now?
 
pt[ptindex] = ((unsigned long)physaddr) | (flags & 0xFFF) | 0x01; // Present
 
// Now you need to flush the entry in the TLB
// or you might not notice the change.
Line 187 ⟶ 185:
 
<source lang="C">
static inline void __native_flush_tlb_single(unsigned long addr) {
{
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
}
Line 210 ⟶ 207:
 
=== External Links ===
*[httphttps://forum.osdev.org/viewtopic.php?f=1&t=18222 INVLPG thread]
*[http://www.dumaisnet.ca/index.php?article=ff3b7adb128cb438ac1e306b3fbe37e7 Process Context ID]
*[https://en.wikipedia.org/wiki/Intel_5-level_paging 5-Level Paging]
 
[[Category:Memory management]]
73

edits