well as @file{filesys/fsutil.c} to learn the implementation details,
but it's really not relevant for this project.
+Here's a summary of how you would create and format a disk, copy the
+@command{echo} program into the new disk, and then run @command{echo}.
+It assumes that you've already built the tests in
+@file{tests/userprog} and that the current directory is
+@file{userprog/build}:
+
+@example
+pintos make-disk fs.dsk 2
+pintos run -f
+pintos put ../../tests/userprog/echo echo
+pintos run -ex echo
+@end example
+
You can delete a file from the Pintos file system using the @option{-r
@var{file}} kernel option, e.g.@: @code{pintos run -r @var{file}}.
Also, @option{-ls} lists the files in the file system and @option{-p
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.
+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
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}}.
+@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
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 Global Requirements
@section Global Requirements
-For testing and grading purposes, we have some simple requirements for
-your output:
+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 exits, e.g.@: @code{shell: exit(-1)}. The name
-printed should be the full name passed to @func{process_execute},
-except that it is acceptable to truncate it to 15 characters to allow
-for the limited space in @struct{thread}.
+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.
+
+@item
+The name printed should be the full name passed to
+@func{process_execute}, except that it is acceptable to truncate it to
+15 characters to allow for the limited space in @struct{thread}. The
+name printed need not include arguments.
+
+@item
+Do not print a message when a kernel thread that is not a process
+terminates.
+
+@item
+Do not print messages about process termination for the @code{halt}
+system call.
+
+@item
+No message need be printed when a process fails to load.
+@end itemize
@item
Aside from this, the kernel should print out no other messages that
conditions (usually errors).
@item SYS_exec
-@itemx pid_t exec (const char *@var{file})
-Run the executable in @var{file} and return the new process's program
-id (pid). If there is an error loading this program, returns pid -1,
-which otherwise should not be a valid id number.
+@itemx pid_t exec (const char *@var{cmd_line})
+Runs the executable whose name is given in @var{cmd_line}, passing any
+given arguments, and returns the new process's program id (pid). If
+there is an error loading this program, may return pid -1, which
+otherwise should not be a valid id number.
@item SYS_join
@itemx int join (pid_t @var{pid})
@item SYS_create
@itemx bool create (const char *@var{file}, unsigned @var{initial_size})
Create a new file called @var{file} initially @var{initial_size} bytes
-in size. Returns -1 if failed, 0 if OK.
+in size. Returns true if successful, false otherwise.
@item SYS_remove
@itemx bool remove (const char *@var{file})
-Delete the file called @var{file}. Returns -1 if failed, 0 if OK.
+Delete the file called @var{file}. Returns true if successful, false
+otherwise.
@item SYS_open
@itemx int open (const char *@var{file})
@item SYS_read
@itemx int read (int @var{fd}, void *@var{buffer}, unsigned @var{size})
Read @var{size} bytes from the file open as @var{fd} into
-@var{buffer}. Returns the number of bytes actually read, or -1 if the
-file could not be read. Fd 0 reads from the keyboard using
+@var{buffer}. Returns the number of bytes actually read (0 at end of
+file), or -1 if the file could not be read (due to a condition other
+than end of file). Fd 0 reads from the keyboard using
@func{kbd_getc}.
@item SYS_write
@var{position}, expressed in bytes from the beginning of the file.
(Thus, a @var{position} of 0 is the file's start.)
+A seek past the current end of a file is not an error. A later read
+obtains 0 bytes, indicating end of file. A later write extends the
+file, filling any unwritten gap with zeros. (However, in Pintos files
+have a fixed length until project 4 is complete, so writes past end of
+file will return an error.) These semantics are implemented in the
+file system and do not require any special effort in system call
+implementation.
+
@item SYS_tell
@itemx unsigned tell (int @var{fd})
Returns the position of the next byte to be read or written in open
@b{I implemented 2-1 and now all my user programs die with
@samp{system call!}.}
+Every reasonable program tries to make at least one system call
+(@func{exit}) and most programs make more than that. Notably,
+@func{printf} invokes the @code{write} system call. The default
+system call handler just prints @samp{system call!} and terminates the
+program. You'll have to implement 2-2 before you see anything more
+interesting. Until then, you can use @func{hex_dump} to convince
+yourself that 2-1 is implemented correctly (@pxref{Argument Passing to
+main}).
+
@item
@b{Is there a way I can disassemble user programs?}
@end itemize
@item
-@b{Why doesn't keyboard input work with @option{-v}?}
+@b{Why doesn't keyboard input work with @samp{pintos -v}?}
-Serial input isn't implemented. Don't use @option{-v} if you want to
-use the shell or otherwise type at the keyboard.
+Serial input isn't implemented. Don't use @samp{pintos -v} if you
+want to use the shell or otherwise provide keyboard input.
@end enumerate
@menu
pointer so that it is word-aligned: that is, we move it down to the
next 4-byte boundary. This is required because we will next be
placing several words of data on the stack, and they must be aligned
-in order to be read correctly. In our example, as you'll see below,
+to be read correctly. In our example, as you'll see below,
the strings start at address @t{0xffed}. One word below that would be
at @t{0xffe9}, so we could in theory put the next word on the stack
there. However, since the stack pointer should always be