CS 350
Operating Systems

Fall 2013
Assignment 0: An Introduction to OS/161

This assignment is to be done individually
SLIP DAYS MAY NOT BE APPLIED TO THIS ASSIGNMENT

Introduction

This assignment will familiarize you with OS/161, the operating system with which you will be working this semester, and System/161, the machine simulator on which OS/161 runs. We also introduce tools that will make your work for this course easier:

Revision Control Software
Revision control software is used to manage the source files of a software package. It is especially helpful when multiple programmers want to work simultaneously. Each programmer has a private copy of the source tree and makes modifications independently. Revision control software attempts to intelligently merge multiple people's modifications, highlighting potential conflicts when it fails. Popular revision control systems are CVS, Subversion (SVN) and GIT, but there are also many others. You must use one of CVS, SVN or GIT for this assignment. Note that you will also need to use revision control software in future assignments when you work in groups and at that point all members of the group must use the same system. You might keep this in mind when choosing the system you use for this assignment. The instructions for this assignment are provided for CVS, you will need to determine the appropriate equivalent actions for whichever system you choose to use. They are here to ensure that by the end of this assignment you know some of the basic functions that will be useful.

GDB (GNU Debugger)
GDB allows you to examine what is happening inside a program while it is running. It lets you execute programs in a controlled manner and view and set the values of variables. In the case of OS/161, it allows you to debug the operating system you are building instead of the machine simulator on which that operating system is running.

The first parts of this document briefly discusses the code on which you'll be working and the tools you'll be using. The remaining sections then describe what you must accomplish for this assignment. Each section marked (hand me in) describes a specific task that you will need to complete, document, and submit.

What are OS/161 and System/161?

The CS350 assignments are based on two software systems:

The OS/161 distribution contains a full operating system source tree, including some utility programs and libraries. After you build the operating system you boot, run, and test it on the simulator.

We use a simulator in CS350 because it allows everyone to have a private machine on which to test their operating system. In addition, debugging and testing the operating system on the simulator is easier than it would be on real hardware. The System/161 machine simulator has been found to be an excellent platform for rapid development of operating system code, while still retaining a high degree of realism. Apart from floating point support and certain issues relating to RAM cache management, it provides an accurate emulation of a MIPS R3000 processor.

There will be an OS/161 programming assignment for each of the following topics:

About CVS

Most programming you have probably done at UW has been in the form of 'one-off' assignments: you get an assignment, you complete it yourself, you turn it in, you get a grade, and then you never look at it again.

Most of the software world uses a very different paradigm: development continues on the same code base producing releases at regular intervals. This kind of development normally requires multiple people working simultaneously within the same code base, and necessitates a system for tracking and merging changes.

Revision control systems are very powerful, but for CS350 you only need to know a subset of the functionality of one of them. A document that introduces CVS, available at http://www.student.cs.uwaterloo.ca/~cs350/common/cvs.html, contains all of the information you need to know and should serve as a reference throughout the term. If you'd like to learn more, there is comprehensive documentation available at http://ximbiot.com/cvs/manual/

Some of you may have experience with SVN from CS 246. Some documentation can be found at http://subversion.apache.org/docs/

Here are some links to references for GIT in no particular order:

About GDB

In some ways debugging a kernel is no different from debugging an ordinary program. On real hardware, however, a kernel crash will crash the whole machine, necessitating a time-consuming reboot. The use of a machine simulator like System/161 provides several debugging benefits. First, a kernel crash will only crash the simulator, which only takes a few keystrokes to restart. Second, the simulator can sometimes provide useful information about what the kernel did to cause the crash, information that may or may not be easily available when running directly on top of real hardware.

You must use the CS350 version of GDB to debug OS/161. You can run it on the UNIX systems used for the course as cs350-gdb. This copy of GDB has been configured for MIPS and has been patched to be able to communicate with your kernel through System/161.

An important difference between debugging a regular program and debugging an OS/161 kernel is that you need to make sure that you are debugging the operating system, not the machine simulator. Type

	% cs350-gdb sys161
and you are debugging the simulator. Detailed instructions on how to debug your operating system and a brief introduction to GDB are contained in the handout Debugging OS/161 with GDB, which is available at http://www.student.cs.uwaterloo.ca/~cs350/common/gdb.html

Step 1: Get a copy of OS/161 and set up your CVS repository

Instructions for obtaining and installing OS/161, and for creating a CVS repository, can be obtained from the Assignments page in the course web space. You are free to use CVS, SVN, or GIT but you will need to follow the ideas for CVS and translate them to the revision control system you decide to use. The remaining steps make the following assumptions:

  1. They assume that you have already installed OS/161 and created a source revision repository.
  2. They assume that you have checked out a working copy of OS/161 from your repository, and the working copy lives in a directory named cs350-os161 under your home directory.
  3. They assume that you have successfully followed the instructions for configuring your working copy of OS/161 and for building the OS/161 kernel, and that there is a compiled kernel in ~/cs350-os161/root.
  4. They assume that you will create and use another directory, called cs350, under your home directory, as well as a subdirectory cs350/asst0 for collecting output the output that will be handed in.

Step 2: Running your kernel (hand me in)

  1. Script the following session using the script command.
      % script
    
    The script command will record the rest of your session (the commands you type, as well as the output from those commands) into a file called typescript in the current directory.
  2. Change into your root directory.
      % cd ~/cs350-os161/root
    
  3. Run the machine simulator on your operating system.
      % sys161 kernel
    
  4. At the prompt, type ? <return>. This tells the kernel to print the kernel menu.
  5. Now at the prompt, type ?t <return>. This tells the kernel to print the kernel's tests menu.
  6. At the next prompt, type tt1 <return>. This tells the kernel to run thread test 1.
  7. Finally, at the next prompt, type q <return>. This tells the kernel to quit and shutdown the system.
  8. End your script session by typing exit or by pressing Ctrl-D. Have a look at your typescript file to ensure that it contains a recording of the commands you just finished executing.
  9. Create the cs350/asst0 hand-in directory. Run scriptfix to clean up the typescript placing the clean output in a file called run.script in the hand-in directory:
      % mkdir ~/cs350
      % mkdir ~/cs350/asst0
      % scriptfix typescript > ~/cs350/asst0/run.script
    

Step 3: Practice modifying your kernel (hand me in)

You should read the document "Working with OS/161" before completing this step. (You will also find a link to this document from the CS350 Assignments web page.)

  1. Create a file called kern/startup/hello.c in your working copy of OS/161.
  2. In this file, write a function called hello that uses kprintf() to print "Hello World\n". Declare this function to be of type void to indicate that it does not have a return value. At the top of the file, you will need to include the header files lib.h (which defines the kprintf function's signature), test.h, to which you will add a prototype for your new hello function, and types.h, which should always be included before any other OS/161 header files. You need to include types.h before lib.h, like this:
    #include <types.h>
    #include <lib.h>
    #include <test.h>
    
  3. Add a prototype for your new function to the header file kern/include/test.h, which is where the prototypes for other functions related to kernel startup and testing are defined. Change this:
    /* Kernel menu system. */
    void menu(char *argstr);
    
    to look like this:
    /* Kernel menu system. */
    void menu(char *argstr);
    /* Boot time shout out */
    void hello(void);
    
  4. Edit kern/startup/main.c and add a call to hello() in a suitable place, so that your Hello World message will be printed by the kernel during its boot process. Ensure that the call to the hello function is only used for assignment 0 by including it conditionally, like this:
    #if OPT_A0
       hello();
    #endif /* OPT_A0 */
    
    Be sure to add the following line to the end of the list of included files at the top main.c, like this
    #include "opt-A0.h"
    
    Among other things, the opt-A0.h file defines the preprocessor symbol OPT_A0, which you wrapped your call to hello(). You'll notice that main.h already includes test.h, which includes the prototype for your hello function. This enables the compiler to ensure that you have invoked hello correctly when it compiles main.c.
  5. Whenever you add a new source file to the OS/161 kernel, you need to add the new file's name to the kernel configuration file. Since you've added hello.c, edit the configuration file (kern/conf/conf.kern) to include the new source file. If you don't do this, your new file will not be included when the kernel is built. Look for this in the configuration file:
    #
    # Startup and initialization
    #
    
    file      startup/main.c
    file      startup/menu.c
    
    and change it to this:
    #
    # Startup and initialization
    #
    
    file      startup/main.c
    file      startup/menu.c
    file      startup/hello.c
    
  6. Now, since you've changed the kernel's configuration file, you should reconfigure the kernel. As is described in the Working with OS/161 document, do this by running
    ./config ASST0
    
    in the kern/conf directory.
  7. Now, build and install your modified kernel. Do this by running bmake depend, then bmake, then bmake install in the directory kern/compile/ASST0. See Working with OS/161 for more details. Have a look at the output of the bmake command - you should see hello.c and main.c being compiled successfully. If there are any problems, you can edit those files and try building your kernel again.
  8. Make sure that your new kernel runs and displays the new message. See Working with OS/161 if you need a reminder about how to run your kernel.
  9. Once your kernel builds and runs, script a session demonstrating your kernel running and printing the Hello World message when it boots up.
      % cd ~/cs350-os161/root
      % script
      % sys161 kernel
    
  10. Call the output of this script session newbuild.script.
      % scriptfix typescript > ~/cs350/asst0/newbuild.script
    

Step 4: Using GDB (hand me in)
You should read the document "Working with OS/161" - in particular, the section on debugging - before completing this step.

  1. Script the following gdb session (that is, you needn't script the session in the run window, only the session in the debug window). Be sure both your run window and your debug window are on the same machine.
  2. Run the kernel in gdb by first running the kernel and then attaching to it from gdb.
      (In the run window:)
      % cd ~/cs350-os161/root
      % sys161 -w kernel
    
      (In the debug window:)
      % script
      % cd ~/cs350-os161/root
      % cs350-gdb kernel
      (gdb) dir ../os161-1.99/kern/compile/ASST0
      (gdb) target remote unix:.sockets/gdb
      (gdb) break menu
      (gdb) c
         [gdb will stop at menu() ...]
      (gdb) where
         [displays a nice back trace...]
      (gdb) detach
      (gdb) quit
    
  3. End your script session. Rename your script output to gdb.script.
      % scriptfix typescript > ~/cs350/asst0/gdb.script
    

Step 5: Practice with Revision Control Software (hand me in)

These instructions are provided for CVS. You are free to use CVS, SVN or GIT but be sure to use the file names specified in the assignment (even when they use cvs in the name).

This step asks you to script your use of some of the most common features of CVS/SVN/GIT.

  1. Create a script of the following session.
      % script
    
  2. You have already created new file (hello.c) in your working copy of the kernel, in Step 3. Now tell your revision control system about it.
      % cd ~/cs350-os161/os161-1.99/kern/startup
      % cvs add hello.c
    
  3. You already edited main.c to include a call to your new hello() function, but perhaps you've forgotten exactly what changes you made. Ask your revision control system to tell you how your working copy of main.c differs from the copy in the repository:
      % cvs diff -c main.c
    
  4. Commit your changes to the revision control repository. Do this from the kern directory so that the commit catches all of the changes you have made:
      % cd ..
      % cvs commit -m "added hello function to the boot sequence"
    
    You should see the changes you have made to conf.kern, test.h, and main.c, as well as the new file hello.c, being committed to the CVS repository.
  5. In a different window , wreck your main.c file by removing the first 100 lines of text from it. Be sure to do this in a separate window so that your editing session is not part of the script output.
  6. Now, in the window in which you are creating your script, try to build your kernel. This should fail, because main.c has been wrecked. Be sure that your failed kernel build is captured in your script.
  7. Realize the error of your ways. Fortunately, you still have a good copy of main.c in your revision control repository. Get it back. In your script window, in the kern/startup directory, do this:
      % rm main.c
      % cvs update -d main.c
    
  8. Now, in your script window, try to build your kernel again. This time, the build should succeed.
  9. End your script session by typing exit or by pressing Ctrl-D. Rename your typescript file to be cvs-use.script. NOTE: that even if you use SVN or GIT you MUST name your file cvs-use.script because the submission stage of the assignment looks explictly for that file name.
      % scriptfix typescript > ~/cs350/asst0/cvs-use.script
    

Step 6: Submit your Results

For this assignment, you are expected to submit the script files that you created in the previous steps. They are:

If you have followed the instructions above, these files should all be located in the cs350/asst0 directory below your home directory. To submit your work, run the cs350_submit program in the cs350/asst0 directory:

  % cd $HOME/cs350/asst0
  % /u/cs350/bin/cs350_submit 0
Note that you must use the cs350_submit command, not the regular submit command, to submit your work. cs350_submit checks the completeness of your submission, packages up your files, and then submits them to the course account using the regular submit command. For this assignment, the packaging is not very important since you are not submitting any code. However, for the remaining assignments it will be very important. Therefore, get used to using cs350_submit to submit your work.

When you run the cs350_submit command, you should see output that looks something like this:

@cpu20.student[116]% cs350_submit 0
This is /u/cs350/bin/cs350_submit for CS350 assignment 0.
/u/cs350/bin/cs350_submit: found required file run.script
/u/cs350/bin/cs350_submit: found required file newbuild.script
/u/cs350/bin/cs350_submit: found required file gdb.script
/u/cs350/bin/cs350_submit: found required file cvs-use.script
/u/cs350/bin/cs350_submit: submitting run.script newbuild.script gdb.script cvs-use.script to CS350 course account
############ OUTPUT FROM submit ###################
  |
  output from the regular submit command here
  |
############ END OF OUTPUT FROM submit ###################
/u/cs350/bin/cs350_submit: submission is complete!
    This submission *replaces* any previous submissions that
    you may have made for assignment 0.
Look carefully at the the output from cs350_submit. If it looks like this:
/u/cs350/bin/cs350_submit IS ABORTING!  No files are being submitted to the course account.
then there was some kind of problem with your submission. Hopefully, the output from cs350_submit will give you a pretty good idea of what went wrong. You will need to correct the problems and try cs350_submit again. It is a good idea to run the cs350_submit command like this:
 /u/cs350/bin/cs350_submit 0 | tee submitlog.txt
This will run the cs350_submit command and also save a copy of all of the output into a file called submitlog.txt, which you can inspect if there are problems. This is handy when there is more than a screen full of output.

Here are a couple of important things you should know about cs350_submit: