Getting Started With OS/161

Outline of this document:

  1. What are OS/161 and System/161?
  2. About SVN
  3. About GDB
  4. Setting up your account
  5. Getting the distribution
  6. Overview of the source tree
  7. Building a kernel
  8. Running a kernel
  9. Using GDB
  10. Using kernel DEBUG prints

What are OS/161 and System/161?

The code for this semester is divided into two main parts:

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 this course because debugging and testing an operating system on real hardware is extremely difficult. 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.

The assignments are designed to be largely stand-alone, however, the final product will be more interesting if you can build on top of your previous solution. In cases where an assignment depends on functionality from a prior assignment, we will publish a partial solution set that provides the needed operations after the grace period.

Using the solution sets may seem like an attractive alternative, since they are guaranteed to work. Keep in mind, however, that using the solution set requires that you understand a code base that you did not write. We encourage groups to refrain from using the solution sets except in the most dire circumstances.

About Subversion (SVN)

If you have taken previous CS courses at the University of Toronto you should already be familiar with SVN. If you need a refresher, this guided tour is a good tutorial.

In previous courses, you may not have taken full advantage of SVN to really keep track of your progress. You will find it increasingly important to use SVN as a revision control system and not just as a submission system. In other words, commit early and often.

About 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.

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 os161 version of GDB to debug OS/161. You can run on the UNIX systems used for the course as os161-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

        % os161-gdb kernel
(with the appropriate directory in the PATH, as described below) 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 Introduction to GDB for os161 .

Getting Started

First, follow the instructions for installing os161 for the lab machines. (Even if you plan to do most of your work on your own machine you will need to test it on the lab machines before you submit it.)

Getting the Distribution

If you are working on a cdf machine, the only software you need is the os161 source code itself. This you will check out of your repository. All the support software has been installed in /u/csc369h/fall/pub/tools/bin.

If you want to work on your own machine, you can download the support software (compiler, debugger, simulator, etc) from /u/csc369h/fall/pub/tools/dist. The file buildall.sh is a shell script that was used to build the full set of tools on CDF. With some small adaptations for your own machine, you should be able to use it to build the tools. Please read the comments in the file that explain some of the flags that are used.

Using GDB

    You will require two windows for the following portion. Be sure both your run window and your debug window are on the same machine.  Run the kernel in gdb by first running the kernel and then attaching to it from gdb. 

    #In the run window
      % cd ~/csc369/root
      % sys161 -w kernel
    
    #In the debug window
      cd ~/csc369/root
      % os161-gdb kernel
      (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

You will likely find that typing "target remote unix:.sockets/gdb" every time you start os161-gdb is a pain. Instead, create a file called .gdbinit in your root directory, and place the following lines in it:

 define db
 target remote unix:.sockets/gdb
 end
Then, you can just type "db" to attach to the kernel process when you start os161-gdb.

Using kernel DEBUG prints

Debugging with print statements is also common and useful, however, it is often undesirable to have EVERY debugging print statement produce output all the time, and it can be time-consuming and error-prone to manually rip out the print statements you are not currently interested in.

A useful alternative is provided by the DEBUG macro in kern/include/lib.h. Take a look at the definition of this macro. A DEBUG statement is simply a kprintf statement that is controlled by the dbflagsvariable. By default, this variable is set to 0 (find out where) so none of the DEBUG statements will actually print. One way to use DEBUG is (as suggested in lib.h) to attach os161-gdb to your running kernel and use it to modify the value of dbflags, turning DEBUG statements on and off as you work. The other option is to modify dbflags in the source code so that they are always set to print a certain class of DEBUG statements when your kernel executes. Because turning DEBUG statements on or off requires only a boolean value, multiple flags can be masked together into a single integer word using the C bitwise operators.

Use DEBUG statements liberally in your code, and feel free to define additional flags if they are useful to you.