Thursday, September 6, 2012

Understanding Virtual Memory


On multi-process system, every process has the illusion that it has the entire physical address space, from 0x00 to some certain upper bound. When the process wants to access a virtual address, the operation system is responsible for translating it to a physical address. Memory Management Unit(MMU), a hardware, is doing the actual address translation. Given a virtual address, it will extract the virtual page number from the first certain bits, looks it up in a page table, and finds the corresponding physical frame number. Combining the physical frame number with the offset in the inputed virtual address, the MMU gets the physical address that the process wants to access.

The basic page table structure is like this:

virtual page # physical frame # usage bits
0 2 xxx
2 4 yyy

Since there are multiple processes each of which “has” the entire address space, only one page table is not sufficient. The OS needs a page table for each process. There are generally two ways to implement this. First, add a “address space ID” or “process ID” to a virtual address. The resulting page table would be like this:

process ID virtual page # physical frame # usage bits
1 0 2 xxx
2 0 3 xxx

A second possible approach is, the OS maintains one page table for each process. When process 1 wants to access a virtual address, the OS lets MMU(how?) to use its own page table to do the translation. The resulting page tables would be like this:

page table for process 1:
virtual page # physical frame # usage bits
0 2 xxx
2 4 yyy

page table for process 2:
virtual page # physical frame # usage bits
0 2 xxx
2 4 yyy

Note that each page table also resides in a physical page somewhere in the memory. When a process is inactive, its page table is moved out from the memory.

For performance concern, a hardware for page table entry cashing is introduced, TLB. When a process wants to access a virtual address, the CPU first searches it in TLB, if hits, loads the corresponding physical address. If misses, looks it up in the page table, (MMU does a pagetable walk) and inserts the entry to TLB.

Similar to the page table tag, TLB could also add a tag to indicate which process’ address space the current virtual address is in. However, on previous x86 architectures, there is no such a tag on TLB. Therefore, every context switch, i.e., address space changing, the entire TLB has to be flushed. On some other architectures, TLB is managed by software. This kind of tag could be there. What is it like in ARM?