Project 1: ps -- process status -- on xv6

Project Overview

This project is composed of three parts, which you must complete in order. Part 0 is the easiest part and simply requires you to get your development environment setup correctly. 

Educational Objectives

This project aims to achieve several educational objectives:

Part 0: Set up development environment

15 points

To be completed individually

To get your development environment setup, carefully follow the instructions below.  There is nothing to submit for part 0, but you'll have to complete part 0 before parts 1 and 2.

Resources

About xv6

In this course you will have the chance to learn about and work with xv6, a simple Unix-like teaching operating system from MIT.

"xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6). xv6 loosely follows the structure and style of v6, but is implemented for a modern x86-based multiprocessor using ANSI C.
xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14, 2000))."

From the xv6 README file.

As with Lions' Commentary, there is a xv6 book. Keep in mind that the version of xv6 we use is slightly older than that of the book and so you may note some differences.

Getting Started

To work on xv6, you will use two set of tools:

  1. QEMU, an x86 emulator for running your kernel
  2. A compiler toolchain (assembler, linker, C compiler, and debugger) for compiling and testing your kernel.

Some useful information about these tools can be found here. Fortunately, these tools are already installed for you on the T-Lab and Wilkinson Lab machines (and also on the EECS servers). The instructor and prior students have completed the xv6 projects on the lab machines and confirmed that everything is working, but please let us know ASAP if any problems arise with these tools.

We will now walk you through how to get started with xv6.

These instructions assume you are working from a lab machine, or at least SSH-ed into one. It might be possible to complete these instructions from another environment, but it will be tricky.

A note on working from outside the lab

For your projects, we STRONGLY recommend that you work remotely by SSH-ing into a lab machine or a server listed here. That being said, it may be possible to complete the projects on your personal machine. The easiest approach is to install xv6 in a recent version of the Linux operating system. If you are not running Linux, you can run Ubuntu inside a VM (like the freely available VirtualBox). The next easiest approach (which a previous quarter's TA couldn't get to work after several hours) is to try to run xv6 and QEMU on Mac OS X. There are a few websites that provide instructions (e.g., here and here). If you run Windows on your personal machine, your best bet is to SSH into the lab machines, or use a Linux VM as mentioned above.

Without further ado, let's get going.

Step 0: Github classroom

Join our github classroom and either join or create a new team.  

https://classroom.github.com/g/lPAlchmO 

After you've done this, you should get an email with a link to a private repository like https://github.com/starzia-teaching/project-1-GROUPNAME 

From the github web interface you can click "clone of download" and then "use HTTPS" to get your group's repository URL (used below)

Step 1: Download the source code

$ git clone https://USERNAME@github.com/starzia-teaching/project-1-GROUPNAME.git 

Notice that I added my github username to the user above, before "@github.com".  If you get an error related to "gnome-ssh-askpass" then try running "unsetenv SSH_ASKPASS" first (or log in with X11 forwarding).

You should now have a folder named project-1-GROUPNAME.  You may find it convenient to browse the source code online at https://github.com/starzia/xv6.  If you have not yet found a partner, then you can actually complete parts 0 and 1 of project 1 by just cloning the public repository (git clone https://github.com/starzia/xv6.git)

In the project directory you will find all the source code and some documentation in the following files:

README BUGS TRICKS

Compile the xv6 kernel:

In the xv6 directory, compile the kernel by simply running "make".  When the compilation is complete, you should now find two additional files in the xv6 directory:

fs.img xv6.img

Those two files are disk images that store your newly compiled xv6 operating system.  This particular OS must be installed on two hard disks: "xv6.img" stores the OS kernel and "fs.img" stores the root filesystem.  To run your xv6 OS you could actually copy the contents of these two files to two physical hard disks, connect those two disks to a PC-compatible computer and turn it on.  However, it is much easier to test an experimental OS using a machine emulator such as QEMU.

Step 2: Run xv6 on QEMU

The command to run xv6 on QEMU is:

$ make qemu-nox

You may see a couple warnings, then you should see the following output lines as xv6 boots up:

xv6...
cpu1: starting
cpu0: starting
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$

Step 3: Take a tour of xv6

You are now in an xv6 shell. Type "ls" to see the list of programs that you can run. You should see a few familiar commands such as 'cat' and 'mkdir'. It is always good to start by reading the README:

$ cat README

Interesting stuff, eh? Now try running the rest of the provided programs to get a feel for what they do. If a program doesn't exit on its own, you can kill it by typing:

control+d

Step 4: Exit xv6 and QEMU

When you are done snooping around, you can exit xv6 by typing:

control+a
then release both keys and tap
x

So far you have been interacting with the "serial console" on the xv6 virtual machine (this is just a very simple way to sent text back and forth between the host OS and your virtual machine).  Your virtual machine also has a virtual VGA display that you can look at.  If you're working on a lab computer, then you can actually see the virtual display by running xv6 with the command "make qemu".  If you are working remotely through SSH, then you'll have to add the "-Y" or "-X" parameter to enable X forwarding (to display graphics).

Step 5: Run xv6 again, this time with GDB remote debugging enabled

The GNU Debugger (GDB) will be one of your best friends this quarter. Any operating systems programming project at any college in the universe is basically composed of three parts:

  1. Stare confusedly at the provided code trying to figure out what is going on and come up with a plan of attack.
  2. Write code.
  3. Spend hours in GDB trying to find all the reasons your code isn't working properly.

Fortunately, xv6 allows you to "look inside" while it is running using GDB. This requires two terminals: one to run xv6 and another to run GDB with remote debugging.

First, run xv6 with remote debugging enabled:

$ make qemu-nox-gdb

You will notice that this time xv6 hangs during the boot-up process. It is waiting for you to make a remote connection using GDB, so let's do that. In another terminal window, in the xv6 directory, type:

$ gdb kernel

The first time you will probably get a warning that says:

...auto-loading has been declined by your `auto-load safe-path'...

Fortunately, it also tells you how to fix the problem:

To enable execution of this file add
    add-auto-load-safe-path /<path-to-xv6>/xv6/.gdbinit
line to your configuration file "/home/<username>/.gdbinit".

To completely disable this security protection add
    set auto-load safe-path /
line to your configuration file "/home/<username>/.gdbinit".

Go ahead and quit out of GDB so that you can follow the message instructions. You'll probably have to create a .gdbinit file in your home directory (there is already a separate .gdbinit in your xv6 directory, which you should NOT touch--leave it be). You should create (or, if it already exists, modify) /home/<username>/.gdbinit as suggested in the message. We recommend using the add-auto-load-safe-path method, which we have highlighted in red above.

Once you have fixed your .gdbinit file, you can run GDB again:

$ gdb kernel

This time, when GDB starts up, you should see the following lines in the output:

Connecting to QEMU
(gdb) target remote localhost:25273
     (<--port number may differ)

Now let's insert a breakpoint in the exec function. This kernel-level function is invoked whenever a new process is executed. In GDB, you can set the breakpoint by typing:

(gdb) b exec

We are now ready to let xv6 finish booting. In GDB, let xv6 continue by typing:

(gdb) c

In your xv6 terminal, you should see the system begin to boot:

xv6...
cpu1: starting
cpu0: starting

Then it hits the exec function for the first time, triggering the breakpoint. In GDB, you should see:

Breakpoint 1, exec (path=0x1c "/init", 0x8dfffe94) at exec.c:12
12 {

Notice the part that says: 

path=0x1c "/init"

This means that exec is about to execute the init process. We have just discovered the first process that xv6 executes during boot-up!

Keep typing 'c' or "continue" in GBD until xv6 reaches the shell prompt, noting the process(es) executed along the way. Once at the shell prompt, you can type an xv6 command to run a program, which should trigger your breakpoint again. You can then type 'c' in GDB to allow the program to run to completion. NOTE: Some programs may behave differently when remote debugging is in use.

You can now repeat your previous tour of xv6, but this time you can set breakpoints and use other GDB features to do some more thorough snooping around.  We recommend that you try running gdb with the "-tui" option.  This provides a large scrollable code viewer and this will make your life easier.  For example, run "gdb -tui kernel".

Step 6: Exit xv6, QEMU, and GDB

When you've had enough, you can exit xv6 and QEMU as before by typing control+a then x. You can exit GDB by typing q then enter.

Step 7: Complete the assignment

To verify that you've completed the assignment, tell us the size of the file xv6.img in your build directory.