X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=doc%2Fuserprog.texi;h=612bb81ba553166d0796c84a923155a7e404ce45;hp=75bc8e542ffd3772fd58b10808f8527b3aadbe36;hb=e587ab7ffa2d548029189e540d5716f880932cb1;hpb=854aa042a0e960f142cb15ecca8177ee01c3f927 diff --git a/doc/userprog.texi b/doc/userprog.texi index 75bc8e5..612bb81 100644 --- a/doc/userprog.texi +++ b/doc/userprog.texi @@ -406,7 +406,7 @@ 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.cc}. This technique is normally faster +@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). @@ -443,7 +443,7 @@ put_user (uint8_t *udst, uint8_t byte) { int error_code; asm ("movl $1f, %0; movb %b2, %1; 1:" - : "=&a" (error_code), "=m" (*udst) : "r" (byte)); + : "=&a" (error_code), "=m" (*udst) : "q" (byte)); return error_code != -1; } @end verbatim @@ -616,6 +616,9 @@ Runs the executable whose name is given in @var{cmd_line}, passing any given arguments, and returns the new process's program id (pid). Must return pid -1, which otherwise should not be a valid pid, if the program cannot load or run for any reason. +Thus, the parent process cannot return from the @code{exec} until it +knows whether the child process successfully loaded its executable. +You must use appropriate synchronization to ensure this. @end deftypefn @deftypefn {System Call} int wait (pid_t @var{pid}) @@ -655,15 +658,16 @@ of the rest. @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. -Opening the new file is a separate operation using the @code{open} -system call. +Creating a new file does not open it: opening the new file is a +separate operation which would require a @code{open} system call. @end deftypefn @deftypefn {System Call} bool remove (const char *@var{file}) Deletes the file called @var{file}. Returns true if successful, false otherwise. -A file may be removed regardless of whether it is open or closed -(@pxref{Removing an Open File}, for more information). +A file may be removed regardless of whether it is open or closed, and +removing an open file does not close it. @xref{Removing an Open +File}, for details. @end deftypefn @deftypefn {System Call} int open (const char *@var{file}) @@ -701,13 +705,13 @@ than end of file). Fd 0 reads from the keyboard using @deftypefn {System Call} int write (int @var{fd}, const void *@var{buffer}, unsigned @var{size}) Writes @var{size} bytes from @var{buffer} to the open file @var{fd}. -Returns the number of bytes actually written, or -1 if the file could -not be written. +Returns the number of bytes actually written, which may be less than +@var{size} if some bytes 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. +actual number written, or 0 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 @@ -868,7 +872,7 @@ call handler just prints @samp{system call!} and terminates the program. Until then, you can use @func{hex_dump} to convince yourself that argument passing is implemented correctly (@pxref{Program Startup Details}). -@item How can I can disassemble user programs? +@item How can I disassemble user programs? The @command{objdump} (80@var{x}86) or @command{i386-elf-objdump} (SPARC) utility can disassemble entire user @@ -975,6 +979,18 @@ or the machine shuts down. You may modify the stack setup code to allocate more than one page of stack space for each process. In the next project, you will implement a better solution. + +@item What should happen if an @code{exec} fails midway through loading? + +@code{exec} should return -1 if the child process fails to load for +any reason. This includes the case where the load fails part of the +way through the process (e.g.@: where it runs out of memory in the +@code{multi-oom} test). Therefore, the parent process cannot return +from the @code{exec} system call until it is established whether the +load was successful or not. The child must communicate this +information to its parent using appropriate synchronization, such as a +semaphore (@pxref{Semaphores}), to ensure that the information is +communicated without race conditions. @end table @node 80x86 Calling Convention @@ -1074,17 +1090,18 @@ pointers. Then, push the address of each string plus a null pointer sentinel, on the stack, in right-to-left order. These are the elements of -@code{argv}. The order ensure that @code{argv[0]} is at the lowest -virtual address. Word-aligned accesses are faster than unaligned -accesses, so for best performance round the stack pointer down to a -multiple of 4 before the first push. +@code{argv}. The null pointer sentinel ensures that @code{argv[argc]} +is a null pointer, as required by the C standard. The order ensures +that @code{argv[0]} is at the lowest virtual address. Word-aligned +accesses are faster than unaligned accesses, so for best performance +round the stack pointer down to a multiple of 4 before the first push. Then, push @code{argv} (the address of @code{argv[0]}) and @code{argc}, in that order. Finally, push a fake ``return address'': although the entry function will never return, its stack frame must have the same structure as any other. -The table below show the state of the stack and the relevant registers +The table below shows the state of the stack and the relevant registers right before the beginning of the user program, assuming @code{PHYS_BASE} is @t{0xc0000000}: