You can build project 2 on top of your project 1 submission or you can
start with a fresh copy. No code from project 1 is required for this
-assignment. The ``alarm clock'' functionality may be useful in later
-projects, but it is not strictly required.
+assignment. The ``alarm clock'' functionality may be useful in
+projects 3 and 4, but it is not strictly required.
@menu
* Project 2 Background::
+* Project 2 Suggested Order of Implementation::
* Project 2 Requirements::
* Project 2 FAQ::
* 80x86 Calling Convention::
user programs on top of the operating system, this is no longer true.
This project deals with consequences of the change.
-We allow more than one user program to run at a time. User
-programs are written and compiled to work under the illusion that they
-have the entire machine. This means that when you load and
-run multiple processes at a time, you must manage memory, scheduling,
-and other state correctly to maintain this illusion.
+We allow more than one process to run at a time. Each process has one
+thread (multithreaded processes are not supported). User programs are
+written under the illusion that they have the entire machine. This
+means that when you load and run multiple processes at a time, you must
+manage memory, scheduling, and other state correctly to maintain this
+illusion.
In the previous project, we compiled our test code directly into your
kernel, so we had to require certain specific function interfaces within
modified @func{page_fault} so that a page fault in the kernel causes
@code{eax} to be set to 0 and its former value copied 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 programs 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)}.
+
+@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.
+@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
so that @code{process_execute("grep foo 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).
+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
number, then any system call arguments, and carry appropriate actions.
Implement the following system calls. The prototypes listed are those
-seen by a user program that includes @file{lib/user/syscall.h}. System
-call numbers for each system call are defined in
+seen by a user program that includes @file{lib/user/syscall.h}. (This
+header and all other files 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{power_off} (declared in
-@file{threads/init.h}). Note that this should be seldom used, since
-then you lose some information about possible deadlock situations,
-etc.
+@file{threads/init.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})
Waits for process @var{pid} to die and returns the status it passed to
@code{exit}. Returns -1 if @var{pid}
was terminated by the kernel (i.e.@: killed due to an exception). If
-@var{pid} is invalid or if it was not a child of the
+@var{pid} is does not refer to a child of the
calling thread, or if @code{wait} has already been successfully
called for the given @var{pid}, returns -1 immediately, without
waiting.
@deftypefn {System Call} bool create (const char *@var{file}, unsigned @var{initial_size})
Creates a new file called @var{file} initially @var{initial_size} bytes
in size. Returns true if successful, false otherwise.
+
+Consider implementing this function in terms of @func{filesys_create}.
@end deftypefn
@deftypefn {System Call} bool remove (const char *@var{file})
Deletes the file called @var{file}. Returns true if successful, false
otherwise.
+
+Consider implementing this function in terms of @func{filesys_remove}.
@end deftypefn
@deftypefn {System Call} int open (const char *@var{file})
is standard input (@code{stdin}), fd 1 is standard output
(@code{stdout}). These special file descriptors are valid as system
call arguments only as explicitly described below.
+
+Consider implementing this function in terms of @func{filesys_open}.
@end deftypefn
@deftypefn {System Call} int filesize (int @var{fd})
Returns the size, in bytes, of the file open as @var{fd}.
+
+Consider implementing this function in terms of @func{file_length}.
@end deftypefn
@deftypefn {System Call} int read (int @var{fd}, void *@var{buffer}, unsigned @var{size})
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}.
+
+Consider implementing this function in terms of @func{file_read}.
@end deftypefn
@deftypefn {System Call} int write (int @var{fd}, const void *@var{buffer}, unsigned @var{size})
Returns the number of bytes actually written, or -1 if the file could
not be written.
+Writing past end-of-file would normally extend the file, but file growth
+is not implemented by the basic file system. The expected behavior is
+to write as many bytes as possible up to end-of-file and return the
+actual number written, or -1 if no bytes could be written at all.
+
Fd 1 writes to the console. Your code to write to the console should
write all of @var{buffer} in one call to @func{putbuf}, at least as
long as @var{size} is not bigger than a few hundred bytes. Otherwise,
lines of text output by different processes may end up interleaved on
the console, confusing both human readers and our grading scripts.
+
+Consider implementing this function in terms of @func{file_write}.
@end deftypefn
@deftypefn {System Call} void seek (int @var{fd}, unsigned @var{position})
file will return an error.) These semantics are implemented in the
file system and do not require any special effort in system call
implementation.
+
+Consider implementing this function in terms of @func{file_seek}.
@end deftypefn
@deftypefn {System Call} unsigned tell (int @var{fd})
Returns the position of the next byte to be read or written in open
file @var{fd}, expressed in bytes from the beginning of the file.
+
+Consider implementing this function in terms of @func{file_tell}.
@end deftypefn
@deftypefn {System Call} void close (int @var{fd})
Closes file descriptor @var{fd}.
+
+Consider implementing this function in terms of @func{file_close}.
@end deftypefn
The file defines other syscalls. Ignore them for now. You will