+@node Virtual Memory Layout
+@section Virtual Memory Layout
+
+Virtual memory in Pintos is divided into two regions: user virtual
+memory and kernel virtual memory. User virtual memory ranges from
+virtual address 0 up to @code{PHYS_BASE}, which is defined in
+@file{threads/mmu.h} and defaults to @t{0xc0000000} (3 GB). Kernel
+virtual memory occupies the rest of the virtual address space, from
+@code{PHYS_BASE} up to 4 GB.
+
+User virtual memory is per-process. Conceptually, each process is
+free to use the entire space of user virtual memory however it
+chooses. When the kernel switches from one process to another, it
+also switches user virtual address spaces by switching the processor's
+page directory base register (see @code{pagedir_activate() in
+@file{userprog/pagedir.c}}.
+
+Kernel virtual memory is global. It is always mapped the same way,
+regardless of what user process or kernel thread is running. In
+Pintos, kernel virtual memory is mapped one-to-one to physical
+memory. That is, virtual address @code{PHYS_ADDR} accesses physical
+address 0, virtual address @code{PHYS_ADDR} + @t{0x1234} access
+physical address @t{0x1234}, and so on up to the size of the machine's
+physical memory.
+
+User programs can only access user virtual memory. An attempt to
+access kernel virtual memory will cause a page fault, handled by
+@code{page_fault()} in @file{userprog/exception.c}, and the process
+will be terminated. Kernel threads can access both kernel virtual
+memory and, if a user process is running, the user virtual memory of
+the running process. However, an attempt to access memory at a user
+virtual address that doesn't have a page mapped into it will also
+cause a page fault.
+