560 Assignment 4

                      DUE : week of Oct 10, 2011
1. OBJECTIVES:
   fork, exec and threads in MTX

2. REQUIREMENTS:

   Implement the following system calls for the MTX system:

===========================================================================
(8). pid = fork()   : fork a child process with an IDENTICAL Umode image;
                      parent returns child's pid, child returns 0.
(9). r = exec(file) : change Umode image to the specified (executable) file

As usual, return -1 if the syscall fails.      
===========================================================================

                    3. HELPS and SUGGESTIONS:

1. HOW TO fork():

(1). Do the same as in kfork() to create a child proc in such a way that when 
     the child begins to run (in Kmode), it RESUMES TO goUmode().
     
(2). Determine the child's segment as  u16 child_segment. 

     Set child's   PROC.uss = child_segment, and
                   PROC.usp = running->usp   (See below for WHY?)

     But DO NOT load any Umode image (file) to child's segment because it 
     will have the SAME Umode iamge of its parent. 
                       
(3). Use get_word()/put_word() to implement a 
               copy_image(child_segment)
     function, which copies running's Umode image to child_segment.

     copy_image() implies that the Umode images of parent and child are
     IDENTICAL. So, their saved usp must also be the same value (each is 
     an offset relative to its own segment).
      
(4). While copy_image() is easy, the important part is how to fix the 
     child's ustack contents so that it will

            . return to Umode in its OWN SEGMENT, and
            . as if it had executed
                    pid = fork();
              but with a return pid = 0 
              (Recall that the parent returns with the chid's pid) 
=============================================================================

2. HOW TO exec("filename");    

(1). In general:
     Locate the file "filename", verify it's eXecutable, read file header
     to determine the TOTAL memory needed, allocate a memory area for the 
     NEW Umode image, then load the EXECUTABLE part of the file into memory.

     ----------------------------------------------------------------------
      In our situation, all executable files are generated with a 32-byte 
      header (because the loader expects them to have headers), but you may 
      ignore the size requirement since each proc has a fixed Umode image size
      of 64 KB.
     ----------------------------------------------------------------------

(2). After loading the new Umode image, fix the ustack contents to make the
     process execute from virtual address 0 when it returns to Umode. Refer 
     to the diagram again:

     (LOW)  uSP                                | by INT 80  |   HIGH
     ---------------------------------------------------------------------
           |uDS|uES| di| si| bp| dx| cx| bx| ax|uPC|uCS|flag| XXXXXX
     ---------------------------------------------------------------------
            -12 -11 -10  -9  -8  -7  -6  -5  -4  -3  -2  -1 | 0 

        (a). re-establish ustack to the very high end of the segment.
        (b). "pretend" it had done  INT 80  from (virtual address) 0: 
             (c). fill in uCS, uDS, uES in ustack
             (d). execute from VA=0 ==> uPC=0, uFLAG=0x0200, 
                                        all other registers = 0;
             (e). fix proc.uSP to point at the current ustack TOP (-24)

     Finally, return from exec() ==> goUmode().

3. Command-line parameters:

   In UNIX, when sh gets a command line
            cmd  arg1  arg2  ....  argn
   it forks a child process to execute the command cmd. When the child process 
   exec to the cmd file, it has the command line tokens as parameters. 
   Specifically, every exec-ed program can be written as

            main(int argc, char *argv[])
            {
               where argc=n+1;
               argv[0]=cmd, argv[1]=arg1,..... argv[n]=argn;
            }
     


   Implement the command line parameters in MTX. Specifically, every (Umode) 
   program can be written as
                    main(argc, argv) int argc; char *argv[];
                    {
                         .................
                    }
   just like in UNIX. Implement a forkexec command in Umode as

       forkexec: while(1){
                    ask for a command line, e.g. cat f1
                    fork a child to exec cat, with argc=2, 
                                                   argv[0]="cat", argv[1]="f1"
                           child:    main(argc, argv) int argc; char *argv[];
                                     {  print argc and argv[] strings }
                    wait for child to die; 
                    get dead child's exitValue to know HOW did it die;
                 }

===========================================================================
Sample Solution:  samples/A4/A4.gz
Help files     :  samples/A4/USER/ contains files for making executables 
                  u1, u2, forkexec