Advanced OS

Table of Contents

Page tables

Memory access

What happens on pointer dereference? It depends. Address in virtual memory may not be the same as in RAM.

Virtual memory:

Address spaces

Why address spaces?

Page tables

address translated at page granularity

Memory Management Unit (MMU) performs translation

Basic linear page-table

Let’s say we dereference virtual address 0010000000000100.

  1. The first 4 bits are index into page table. 0010 is 2 in decimal, so page at index 2 in page table is used.
  2. Index 2 contains the value 1101, where the last bit is the ‘present/absent’ bit (i.e. does the entry map to a physical address). The first 3 bits are used as the first 3 bits in the outgoing physical address.
  3. The resultant physical address is 110000000000100: the 3 bits from the page table entry, and the 12 bits copied from the virtual address.

Linear page table

Hierarchical page tables (x86_32)

Use a top-level page table that points to other page tables.

The first 10 bits are an index into top-level page table, the second 10 bits index into second-level page table, and the last 12 bits are the offset.

The downside is, you need more lookups.

Inverted page tables (IA64)

Make a page table tailored to the size of physical memory instead of virtual. Then, use a hash table, indexed by hash on virtual page, with list of pages.

Four-level page tables (x86_64)

Only implements lowest 48 bits of the address, the rest are sign extend.

Register cr3 is pointer to a highest-level page table (PML4E). First 9 bits are index into table, which points to page-directory-pointer table (PDPE). The next 9 bits to page-directory table, then the page table, then a physical page, with the last 12 bits being the offset.

Four level paging structures

Page table management

Static page tables for bootstrapping

OpenLSD maps two locations in virtual memory:

In AT&T syntax (src, dst):

movl $(PAGE_PRESENT | PAGE_WRITE | PAGE_HUGE), %eax ; mapping 2 MiB pages
movl $page_dir, %edi
movl $4, %ecx           ; we want 4 entries

.map_pages:             ; identity mapping
movl %eax, (%edi)
addl $0x200000, %eax    ; map next physical address
addl $8, %edi
dec %ecx                ; decrement counter
jnz .map_pages

;; at next higher level, load single entry with identity mapping
movl $page_dir, %eax
orl $(PAGE_PRESENT | PAGE_WRITE), %eax
movl %eax, pdpt

;; and higher level again
movl $pdpt, %eax
orl $(PAGE_PRESENT | PAGE_WRITE), %eax
movl %eax, pml4
movl %eax, pml4 + 256*8

;; Load the root into cr3
movl $pml4, %eax
movl %eax, %cr3

OpenLSD after boot

Dynamic page table management (post boot)

Two issues:

Policies:

Mechanisms:

page table walk on x86_64 with 4-level page table, 48 bit virtual address, page tables mapped in virt memory:

  1. locate top-level page table: read cr3 register (or process struct)
  2. locate 2nd-level page table
    • get virtual pointer to top-level page
    • use bits 39-47 of virtual address as index
    • if not page table entry present, abort.
  3. locate 3rd-level page table
    • get virtual pointer to 2nd-level page
    • use bits 30-38 of virtual address as index
    • if not page table entry present, abort.
  4. last page table entry has physical address of page

page table mapping:

page table unmapping

permission bits:

Optimizations

TLB (caching)

result of page table translation: virtual address x is at physical address y

approach for memory access:

Needs to be super fast, so small number of sets.

Flush TLB:

TLB scalability:

Security

kernel address space layout randomization (KASLR):