-@section How User Programs Work
-
-Pintos can run normal C programs. In fact, it can run any program you
-want, provided it's compiled into the proper file format, and uses
-only the system calls you implement. (For example, @code{malloc()}
-makes use of functionality that isn't provided by any of the syscalls
-we require you to support.) The only other limitation is that Pintos
-can't run programs using floating point operations, since it doesn't
-include the necessary kernel functionality to save and restore the
-processor's floating-point unit when switching threads. You can look
-in @file{test} directory for some examples.
-
-Pintos loads ELF executables, where ELF is an executable format used
-by Linux, Solaris, and many other Unix and Unix-like systems.
-Therefore, you can use any compiler and linker that produce
-80@var{x}86 ELF executables to produce programs for Pintos. We
-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.
-
-Additionally, while it may be useful to hard-code which process will
-run at startup while debugging, before you submit your code you must
-make sure that it takes the start-up process name and arguments from
-the @samp{-ex} argument. For example, running @code{pintos run -ex
-"testprogram 1 2 3 4"} will spawn @samp{testprogram 1 2 3 4} as the
-first process.
-
-@node Problem 2-1 Argument Passing
-@section Problem 2-1: Argument Passing
-
-Currently, @code{thread_execute()} does not support passing arguments
-to new processes. UNIX and other operating systems do allow passing
-command line arguments to a program, which accesses them via the argc,
-argv arguments to main. You must implement this functionality by
-extending @code{thread_execute()} so that instead of simply taking a
-program file name, it can take a program name with arguments as a
-single string. That is, @code{thread_execute("grep foo *.c")} should
-be a legal call. @xref{80x86 Calling Convention}, for information on
-exactly how this works.
-
-@strong{This functionality is extremely important.} Almost all our
-test cases rely on being able to pass arguments, so if you don't get
-this right, a lot of things will not appear to work correctly with our
-tests. If the tests fail, so do you. Fortunately, this part
-shouldn't be too hard.
-
-@node Problem 2-2 System Calls
-@section Problem 2-2: System Calls
-
-Implement the system call handler in @file{userprog/syscall.c} to
-properly deal with all the system calls described below. Currently,
-it ``handles'' system calls by terminating the process. You will need
-to decipher system call arguments and take the appropriate action for
-each.
-
-You are required to support the following system calls, whose syscall
-numbers are defined in @file{lib/syscall-nr.h} and whose C functions
-called by user programs are prototyped in @file{lib/user/syscall.h}:
-
-@table @code
-@item SYS_halt
-@itemx void halt (void)
-Stops Pintos and prints out performance statistics. Note that this
-should be seldom used, since then you lose some information about
-possible deadlock situations, etc.
-
-@item SYS_exit
-@itemx void exit (int @var{status})
+@subsection How User Programs Work
+
+Pintos can run normal C programs, as long as they fit into memory and use
+only the system calls you implement. Notably, @func{malloc} cannot be
+implemented because none of the system calls required for this project
+allow for memory allocation. Pintos also can't run programs that use
+floating point operations, since the kernel doesn't save and restore the
+processor's floating-point unit when switching threads.
+
+The @file{src/examples} directory contains a few sample user
+programs. The @file{Makefile} in this directory
+compiles the provided examples, and you can edit it
+compile your own programs as well. Some of the example programs will
+only work once projects 3 or 4 have been implemented.
+
+Pintos can load @dfn{ELF} executables with the loader provided for you
+in @file{userprog/process.c}. ELF is a file format used by Linux,
+Solaris, and many other operating systems for object files,
+shared libraries, and executables. You can actually use any compiler
+and linker that output 80@var{x}86 ELF executables to produce programs
+for Pintos. (We've provided compilers and linkers that should do just
+fine.)
+
+You should realize immediately that, until you copy a
+test program to the simulated file system, Pintos will be unable to do
+useful work. You won't be able to do
+interesting things until you copy a variety of programs to the file system.
+You might want to create a clean reference file system disk and copy that
+over whenever you trash your @file{filesys.dsk} beyond a useful state,
+which may happen occasionally while debugging.
+
+@node Virtual Memory Layout
+@subsection 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/vaddr.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.
+When the kernel switches from one process to another, it
+also switches user virtual address spaces by changing 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 table.
+
+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, starting at @code{PHYS_BASE}. That is, virtual address
+@code{PHYS_BASE} accesses physical
+address 0, virtual address @code{PHYS_BASE} + @t{0x1234} accesses
+physical address @t{0x1234}, and so on up to the size of the machine's
+physical memory.
+
+A user program can only access its own user virtual memory. An attempt to
+access kernel virtual memory causes 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 an unmapped user virtual address
+will cause a page fault.
+
+@menu
+* Typical Memory Layout::
+@end menu
+
+@node Typical Memory Layout
+@subsubsection Typical Memory Layout
+
+Conceptually, each process is
+free to lay out its own user virtual memory however it
+chooses. In practice, user virtual memory is laid out like this:
+
+@html
+<CENTER>
+@end html
+@example
+@group
+ PHYS_BASE +----------------------------------+
+ | user stack |
+ | | |
+ | | |
+ | V |
+ | grows downward |
+ | |
+ | |
+ | |
+ | |
+ | grows upward |
+ | ^ |
+ | | |
+ | | |
+ +----------------------------------+
+ | uninitialized data segment (BSS) |
+ +----------------------------------+
+ | initialized data segment |
+ +----------------------------------+
+ | code segment |
+ 0x08048000 +----------------------------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ 0 +----------------------------------+
+@end group
+@end example
+@html
+</CENTER>
+@end html
+
+In this project, the user stack is fixed in size, but in project 3 it
+will be allowed to grow. Traditionally, the size of the uninitialized
+data segment can be adjusted with a system call, but you will not have
+to implement this.
+
+The code segment in Pintos starts at user virtual address
+@t{0x08084000}, approximately 128 MB from the bottom of the address
+space. This value is specified in @bibref{SysV-i386} and has no deep
+significance.
+
+The linker sets the layout of a user program in memory, as directed by a
+``linker script'' that tells it the names and locations of the various
+program segments. You can learn more about linker scripts by reading
+the ``Scripts'' chapter in the linker manual, accessible via @samp{info
+ld}.
+
+To view the layout of a particular executable, run @command{objdump}
+(80@var{x}86) or @command{i386-elf-objdump} (SPARC) with the @option{-p}
+option.
+
+@node Accessing User Memory
+@subsection Accessing User Memory
+
+As part of a system
+call, the kernel must often access memory through pointers provided by a user
+program. The kernel must be very careful about doing so, because
+the user can pass a null pointer, a pointer to
+unmapped virtual memory, or a pointer to kernel virtual address space
+(above @code{PHYS_BASE}). All of these types of invalid pointers must
+be rejected without harm to the kernel or other running processes, by
+terminating the offending process and freeing its resources.
+
+There are at least two reasonable ways to do this correctly. The
+first method is to verify
+the validity of a user-provided pointer, then dereference it. If you
+choose this route, you'll want to look at the functions in
+@file{userprog/pagedir.c} and in @file{threads/vaddr.h}. This is the
+simplest way to handle user memory access.
+
+The second method is to check only that a user
+pointer points below @code{PHYS_BASE}, then dereference it.
+An invalid user pointer will cause a ``page fault'' that you can
+handle by modifying the code for @func{page_fault} in
+@file{userprog/exception.c}. This technique is normally faster
+because it takes advantage of the processor's MMU, so it tends to be
+used in real kernels (including Linux).
+
+In either case, you need to make sure not to ``leak'' resources. For
+example, suppose that your system call has acquired a lock or
+allocated memory with @func{malloc}. If you encounter an invalid user pointer
+afterward, you must still be sure to release the lock or free the page
+of memory. If you choose to verify user pointers before dereferencing
+them, this should be straightforward. It's more difficult to handle
+if an invalid pointer causes a page fault,
+because there's no way to return an error code from a memory access.
+Therefore, for those who want to try the latter technique, we'll
+provide a little bit of helpful code:
+
+@verbatim
+/* Reads a byte at user virtual address UADDR.
+ UADDR must be below PHYS_BASE.
+ Returns the byte value if successful, -1 if a segfault
+ occurred. */
+static int
+get_user (const uint8_t *uaddr)
+{
+ int result;
+ asm ("movl $1f, %0; movzbl %1, %0; 1:"
+ : "=&a" (result) : "m" (*uaddr));
+ return result;
+}
+
+/* Writes BYTE to user address UDST.
+ UDST must be below PHYS_BASE.
+ Returns true if successful, false if a segfault occurred. */
+static bool
+put_user (uint8_t *udst, uint8_t byte)
+{
+ int error_code;
+ asm ("movl $1f, %0; movb %b2, %1; 1:"
+ : "=&a" (error_code), "=m" (*udst) : "q" (byte));
+ return error_code != -1;
+}
+@end verbatim
+
+Each of these functions assumes that the user address has already been
+verified to be below @code{PHYS_BASE}. They also assume that you've
+modified @func{page_fault} so that a page fault in the kernel merely
+sets @code{eax} to @t{0xffffffff} and copies its former value
+into @code{eip}.
+
+@node Project 2 Suggested Order of Implementation
+@section Suggested Order of Implementation
+
+We suggest first implementing the following, which can happen in
+parallel:
+
+@itemize
+@item
+Argument passing (@pxref{Argument Passing}). Every user program will
+page fault immediately until argument passing is implemented.
+
+For now, you may simply wish to change
+@example
+*esp = PHYS_BASE;
+@end example
+@noindent to
+@example
+*esp = PHYS_BASE - 12;
+@end example
+in @func{setup_stack}. That will work for any test program that doesn't
+examine its arguments, although its name will be printed as
+@code{(null)}.
+
+Until you implement argument passing, you should only run programs
+without passing command-line arguments. Attempting to pass arguments to
+a program will include those arguments in the name of the program, which
+will probably fail.
+
+@item
+User memory access (@pxref{Accessing User Memory}). All system calls
+need to read user memory. Few system calls need to write to user
+memory.
+
+@item
+System call infrastructure (@pxref{System Calls}). Implement enough
+code to read the system call number from the user stack and dispatch to
+a handler based on it.
+
+@item
+The @code{exit} system call. Every user program that finishes in the
+normal way calls @code{exit}. Even a program that returns from
+@func{main} calls @code{exit} indirectly (see @func{_start} in
+@file{lib/user/entry.c}).
+
+@item
+The @code{write} system call for writing to fd 1, the system console.
+All of our test programs write to the console (the user process version
+of @func{printf} is implemented this way), so they will all malfunction
+until @code{write} is available.
+
+@item
+For now, change @func{process_wait} to an infinite loop (one that waits
+forever). The provided implementation returns immediately, so Pintos
+will power off before any processes actually get to run. You will
+eventually need to provide a correct implementation.
+@end itemize
+
+After the above are implemented, user processes should work minimally.
+At the very least, they can write to the console and exit correctly.
+You can then refine your implementation so that some of the tests start
+to pass.
+
+@node Project 2 Requirements
+@section Requirements
+
+@menu
+* Project 2 Design Document::
+* Process Termination Messages::
+* Argument Passing::
+* System Calls::
+* Denying Writes to Executables::
+@end menu
+
+@node Project 2 Design Document
+@subsection Design Document
+
+Before you turn in your project, you must copy @uref{userprog.tmpl, ,
+the project 2 design document template} into your source tree under the
+name @file{pintos/src/userprog/DESIGNDOC} and fill it in. We recommend
+that you read the design document template before you start working on
+the project. @xref{Project Documentation}, for a sample design document
+that goes along with a fictitious project.
+
+@node Process Termination Messages
+@subsection Process Termination Messages
+
+Whenever a user process terminates, because it called @code{exit}
+or for any other reason, print the process's name
+and exit code, formatted as if printed by @code{printf ("%s:
+exit(%d)\n", @dots{});}. The name printed should be the full name
+passed to @func{process_execute}, omitting command-line arguments.
+Do not print these messages when a kernel thread that is not a user
+process terminates, or
+when the @code{halt} system call is invoked. The message is optional
+when a process fails to load.
+
+Aside from this, don't print any other
+messages that Pintos as provided doesn't already print. You may find
+extra messages useful during debugging, but they will confuse the
+grading scripts and thus lower your score.
+
+@node Argument Passing
+@subsection Argument Passing
+
+Currently, @func{process_execute} does not support passing arguments to
+new processes. Implement this functionality, by extending
+@func{process_execute} so that instead of simply taking a program file
+name as its argument, it divides it into words at spaces. The first
+word is the program name, the second word is the first argument, and so
+on. That is, @code{process_execute("grep foo bar")} should run
+@command{grep} passing two arguments @code{foo} and @code{bar}.
+
+Within a command line, multiple spaces are equivalent to a single
+space, so that @code{process_execute("grep @w{ }foo @w{ }@w{ }bar")}
+is equivalent to our original example. You can impose a reasonable
+limit on the length of the command line arguments. For example, you
+could limit the arguments to those that will fit in a single page (4
+kB). (There is an unrelated limit of 128 bytes on command-line
+arguments that the @command{pintos} utility can pass to the kernel.)
+
+You can parse argument strings any way you like. If you're lost,
+look at @func{strtok_r}, prototyped in @file{lib/string.h} and
+implemented with thorough comments in @file{lib/string.c}. You can
+find more about it by looking at the man page (run @code{man strtok_r}
+at the prompt).
+
+@xref{Program Startup Details}, for information on exactly how you
+need to set up the stack.
+
+@node System Calls
+@subsection System Calls
+
+Implement the system call handler in @file{userprog/syscall.c}. The
+skeleton implementation we provide ``handles'' system calls by
+terminating the process. It will need to retrieve the system call
+number, then any system call arguments, and carry out appropriate actions.
+
+Implement the following system calls. The prototypes listed are those
+seen by a user program that includes @file{lib/user/syscall.h}. (This
+header, and all others in @file{lib/user}, are for use by user
+programs only.) System call numbers for each system call are defined in
+@file{lib/syscall-nr.h}:
+
+@deftypefn {System Call} void halt (void)
+Terminates Pintos by calling @func{shutdown_power_off} (declared in
+@file{devices/shutdown.h}). This should be seldom used, because you lose
+some information about possible deadlock situations, etc.
+@end deftypefn
+
+@deftypefn {System Call} void exit (int @var{status})