Lab: page tables

In this lab, the most important reference is kernel/vm.c, which relates to the creation, mapping, and freeing of page tables. Three functions are the quite useful in this lab:

  1. mappages(): Setup the page table entries with physical address usually used with kalloc().
  2. walk(): Fetch or create the corresponding page table entry in the three-level tree.
  3. uvmunmap(): Unmap vm pages by writing the page table entries to 0, optionally free the pointed physical memory.

Speed up system calls (moderate)

We can map a new read-only (don't forget PTE_U) page at va=USYSCALL, and store the information in the pointed physical page.

If user calls ugetpid(), function will directly return the pid stored at USYSCALL in user mode, instead of asking kernel to return getpid().

Print a page table (moderate)

Essentially this is a pre-order traversal in N-ary tree. You can imagine:

  1. Every page table is a node, and each pte is a pointer to one child node.
  2. If the pte is valid and labeled as pte & (PTE_W|PTE_R|PTE_X) == 0, then this node is an internal node.
  3. Recursively call vmprint() for internal nodes after printing the lines.

The indentation level can be passed as the second argument in the recursive function. You can construct the prefix string before traversing.

Detecting which pages have been accessed (hard)

I think this task is easy level. It is quite straight-forward:

  1. Call multiple walk() functions in the given range.
  2. For each pte returned, check whether the PTE_A bit is set and clear it.