-recommend using the tools we provide in the @file{tests} directory. By
-default, the @file{Makefile} in this directory will compile the test
-programs we provide. You can edit the @file{Makefile} to compile your
-own test programs as well.
-
-One thing you should realize immediately is that, until you use the
-above operation to copy a test program to the emulated disk, Pintos
-will be unable to do very much useful work. You will also find that
-you won't be able to do interesting things until you copy a variety of
-programs to the disk. A useful technique is to create a clean
-reference disk and copy that over whenever you trash your
-@file{fs.dsk} beyond a useful state, which may happen occasionally
-while debugging.
-
-@node Global Requirements
-@section Global Requirements
-
-For testing and grading purposes, we have some simple requirements for
-your output. The kernel should print out the program's name and exit
-status whenever a process exits. Aside from this, it should print out
-no other messages. You may understand all those debug messages, but
-we won't, and it just clutters our ability to see the stuff we care
-about.
+recommend using the tools we provide in the @file{tests/userprog}
+directory. By default, the @file{Makefile} in this directory will
+compile the test programs we provide. You can edit the
+@file{Makefile} to compile your own test programs as well.
+
+One thing you should realize immediately is that, until you copy a
+test program to the emulated disk, Pintos will be unable to do very
+much useful work. You will also find that you won't be able to do
+interesting things until you copy a variety of programs to the disk.
+A useful technique is to create a clean reference disk and copy that
+over whenever you trash your @file{fs.dsk} beyond a useful state,
+which may happen occasionally while debugging.
+
+@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 @func{pagedir_activate in
+@file{userprog/pagedir.c}}. @struct{thread} contains a pointer to a
+process's page directory.
+
+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
+@func{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, even in the kernel, an attempt to
+access memory at a user virtual address that doesn't have a page
+mapped into it will cause a page fault.
+
+You must handle memory fragmentation gracefully, that is, a process
+that needs @var{N} pages of memory must not require that all @var{N}
+be contiguous. In fact, it must not require that any of the pages be
+contiguous.
+
+@node Grading Requirements
+@section Grading Requirements
+
+For testing and grading purposes, we have some simple overall
+requirements:
+
+@itemize @bullet
+@item
+The kernel should print out the program's name and exit status whenever
+a process terminates, whether termination is caused by the @code{exit}
+system call or for another reason.
+
+@itemize @minus
+@item
+The message must be formatted exactly as if it was printed with
+@code{printf ("%s: exit(%d)\n", @dots{});} given appropriate arguments.