In this lab you will implement user processes and system calls.

As supplied, Pintos is incapable of running user processes and only implements two systems calls. Pintos does, however, have the ability to load ELF binary executable, and has a fully functioning page-based, non- virtual memory management system.

There are three parts to this lab; each depends on the previous one.

  • Allow simple user process to run.
  • Support argument passing to user processes.
  • Implement seven new systems calls.


  1. Follow instructions from Lab 1 to get Oracle Virtual Box installed if you have not already done so.
  2. Download and install the lab specific virtual appliance: https://classes.soe.ucsc.edu/cmps111/Fall17/SECURE/CMPS111-Lab3.ova
    Import this appliance into Virtual Box using the “File->Import Appliance” menu: Select the downloaded .ova and accept all defaults.

  3. Start the virtual appliance:
    Click the button to start the lab appliance, an Ubuntu 32bit Desktop instance.

  4. Check the Pintos installation works:
    Open a terminal window (the icon) and enter the following commands:

$ cd pintos/src/userprog ( always work in this directory )

$ make ( builds pintos )

Now run a test:

$ pintos -v -k -T 60 –qemu –filesys-size=2 \

-p build/tests/userprog/args-none \

-a args-none – -q -f run ‘args-none’

The same test can also be run using the following command, but more sophisticated tests will need to be run in the long form above, passing arguments as required inside the single quotes. E.g. ‘args-many 1 2 3‘

$ runtest args-none

Also try:

$ make check ( runs the required functional tests - see below )

$ make grade ( tells you what grade you will get - see below )

In certain circumstances, “make grade” will fail to complete. If this happens to you, simply run the following command instead:

$ grade ( runs make grade repeatedly until it completes )

Background Information

Pintos Calling Conventions

Pinto is a Unix-like operating system and should implement the standard Unix / C calling convention. To understand how arguments are passed to Unix / C programs, consider the command:

/bin/ls -l foo bar

Also recall that the prototype for a C program entry point is:

int main(int argc, char *argv[])

Where argc is the number of arguments passed to the program (including the program name) and argv is an array containing pointers to each of the arguments stored as null-terminated character arrays.

To execute this program with the supplied arguments, we need to do the following:

    • Break this command into words: ”/bin/ls”, ”-l”, ”foo”, and ”bar”.
    • Place these words at the top of the stack, in right to left order.
    • Push onto the stack the _address _of each string plus a null pointer sentinel, in right-to-left order.

      *   These are the elements of argv. The null pointer sentinel ensures that argv[argc] is a null pointer, as required by the C standard. The order ensures that 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.
      • Push argv (the address of argv[0]) and 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 figure below shows the contents in the stack before executing the user program. We assume here that

PHYS_BASE is 0xc0000000.

As shown above, your code should start with the stack at the very top of the user virtual address space, in the page just below virtual address PHYS_BASE ( defined in threads/vaddr.h ).

System Calls

Most user programs require services provided by Pintos; they access those capabilities by making system calls. To support this feature, you will need to extend the existing system call implementation in userprog/syscall.c.

The system calls of interest in this lab are:

    • create : Creates a new file. Return true if successful and false otherwise.
    • open : Open a file and return the corresponding file descriptor (i.e. an integer handle). Note that file descriptor 0 is reserved for standard input and file descriptor 1 is reserved for standard output.
    • read : Read a specified number of bytes from an existing, open file into a buffer in the user program, returning the number of bytes actually read, or -1 if read failed.
    • write: Write a specified number of bytes to an open file from a buffer in the user program. Return the number of bytes actually written or -1 if an error occurs.
    • close : Close an open file.
    • exec : Starts the execution of a user program and returns the ID of the newly created child process if successful. The parent process should not return from the exec system call until it knows whether the child process has successfully loaded its executable code.
    • wait : Waits for a child process to complete and retrieves the child’s exit value.
      Note that the above descriptions are a guide only, your system calls must do whatever the tests demand they do!
on Next Page ~~~~

# Using the GNU Debugger (GDB) with Pintos

In Lab 1 and Lab 2, many of you will have “debugged” you code using printf statements and assertions.

The code you will write in this Lab is significantly more complex and an appropriately more sophisticated mechanism for examining your code as it runs is required.

Run a test in debug node (note the new argument):

$ pintos -v -k -T 60 --qemu --filesys-size=2 \

-p build/tests/userprog/args-none -a args-none \

**--gdb **-- -q -f run args-none

In a separate terminal, run GDB for Pintos:

$ pintos-gdb build/kernel.o

At the prompt, connect to the running test:

(gdb) target remote localhost:1234

GDB will respond:

Remote debugging using localhost:1234 0x0000fff0 in ?? ()

From there on in, set breakpoints and step into or over functions as required. To get the test to run to completion, enter “C” at the (gdb) prompt.

If you don't know how to use GDB, remember, Google is your friend. A quick search for **“gdb tutorial C” **will find you an abundance of information.

# Using the GIT revision control system with Pintos

The Virtual Box Ubuntu appliances have GIT installed, and we _highly _recommend you use it to track the changes you make, though this is not required.

CMPS111 is not, however, a GIT training course. But once again, Google is your friend, so find some beginner tutorials and study them if you have never used GIT. But also remember you have friends in the shape of your classmates, the TAs, and your instructor. If you want to know how to setup and use GIT, just ask someone.

~~~~ Continued on Next Page


User Processes:

    • Give Pintos the ability to execute user processes mapped one-to-one with kernel threads.
    • Pass the following test:

      *   args-none Arguments to User Processes:
      • Allow Pintos user processes to accept command line arguments.
    • Pass the following tests:

      *   args-single
      • args-multiple
      • args-many
      • args-dbl-space System Calls:

      • Implement the create, open, read, write, close, exec, and wait function calls.

    • Pass the following tests:

      *   create-empty
      • create-long
      • create-normal
      • create-exists
      • open-missing
      • open-normal
      • open-twice
      • read-normal
      • read-zero
      • write-normal
      • write-zero
      • close-normal
      • exec-once
      • exec-multiple
      • wait-simple
      • wait-twice

What to submit

In a command prompt:

$ cd pintos/src/userprog

$ make submit

This creates a gzipped tar archive named CMPS111-Lab3.tar.gz in the home directory.


In addition to submitting modified and new source files, you are required to write a short report on your work. This report should contain at least:

    • A defense of the design rationale behind your code
    • Details of tests your submission fails and what investigations you undertook to try and find out why
      If you keep a simple journal as you work your way through this lab, writing the report will be easy - it’s essentially a tidied up version of your journal.


Grading Scheme

The following aspects will be assessed:

  1. (80%) Does it work?

    a. User Processes(30%)
    b. Argument Passing(10%)
    c. System Calls(40%)

(10%) Is the code well written?

    • Marks awarded for:

      *   Compilation free of errors and/or warnings.
      • Clarity.
      • Modularity.
      • Evidence of original work - i.e. not simply having copied other peoples code.

      • Marks deducted for:

        • Compilation warnings in code you wrote.
      • Not giving credit to on-line resources you “borrowed” code segments from.
      • Poor factorization - e.g. huge functions that do way too much.
      • “Spaghetti Code” - i.e. code related to one functional area scattered all over the place.
      • Magic numbers, nested conditionals, duplication, inconsistent naming, and other assorted code nastiness.

(10%) Did you understand what you were doing?

    • Your code partially shows this, but the report is where you convince me.
    • Marks awarded for:

      *   Clearly stating which requirements were met and which were not.
      • Concise description of development process.
      • Details of testing methodology.
      • An observation of what was easy, what was hard, where problems arose, how they were overcome.
      • Reflection on how you might improve or extend your solution.
kamisama wechat