Tutorial:

Setting up Xv6

Xv6 is a real operating system kernel, and hence, it needs real hardware to boot. Fortunately, today we can emulate hardware in software. Programs like QEMU can emulate functionality of the real physical CPU in software. I.e., QEMU implements the normal CPU loop similar to the one we discussed in class: fetches an instruction pointed by the instruction pointer register (EIP), decodes it, performs all permission and condition checks, computes the outcome, increments EIP and continues to the next instruction.

Like a real PC platform, QEMU emulates hardware boot protocol. QEMU starts by loading the disk sector number 0 into the memory location 0x7c00 and jumping to it. Xv6 takes it from there. At a high level, for Xv6 it does not matter if it runs on the real hardware or under QEMU. Of course, emulation is slower than real hardware, but besides that as long as QEMU implements the logic of the CPU correctly we do not see any deviations from a real baremetal execution. Surprisingly, QEMU is reasonably fast, so you as a human barely notice the difference.

Setting up QEMU and Xv6

SSH into Openlab (circinus-XX)

We will use circinus machines 1 to 48: circinus-1.ics.uci.edu to circinus-48.ics.uci.edu. Before you begin, you need to select a circinus server for yourself. We have the following method to select a server just to provide some uniform distribution of students across different servers:

  • Find out your student ID number (Let's say: 66541280).
  • Obtain the server number (SN) you will connect to: SN = ID % 47 + 1 (Ex: 66541280 → 44).
  • Your server name is : circinus-SN.ics.uci.edu (Ex: circinus-44.ics.uci.edu).

This is the server you will use for the rest of the quarter. Unless it has a problem, stick to it. To configure your Xv6 environment, first, login to your server:

$ ssh UCInetID@circinus-XX.ics.uci.edu

Troubleshooting your Circinus ssh connection

If a specific server is not available, try with SN + 1, and so on. If you get an error message like this:

Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)

And you're connecting from outside of campus, you need to need to either use AnyConnect VPN to tunnel in or setup an SSH keypair for passwordless login. Openlab machines do not accept outside password login attempts.

Clone and build QEMU

To run Xv6 we need to compile and install a version of the QEMU emulator. Default QEMU's debugging facilities, while powerful, are somewhat immature, so it is highly recommend you use a patched version of QEMU which is maintained by MIT instead of the stock version that may come with your distribution.

From inside your home folder create a new directory for this class. I suggest you start in your home folder (unless you know what you're doing this is a good way to go)

$ cd ~ $ mkdir cs238p

Change into this new directory

$ cd cs238p

Clone the MIT's QEMU distribution into the qemu folder

$ git clone https://github.com/mit-pdos/6.828-qemu.git qemu Cloning into 'qemu'...

Change into qemu folder and initialize an internal git submodule

$ cd qemu $ git submodule update --init pixman Submodule 'pixman' (git://anongit.freedesktop.org/pixman) registered for path 'pixman' Cloning into 'pixman'...

Configure QEMU with minimal settings and the prefix pointing to the install folder

$ ./configure --disable-kvm --disable-werror --prefix=/home/YourUCInetID/cs238p/qemu-install --target-list="i386-softmmu x86_64-softmmu" --python=/usr/bin/python2.7 Install prefix /home/YourUCInetID/cs238p/qemu-install ... NUMA host support no

For example, for me this becomes:

$ ./configure --disable-kvm --disable-werror --prefix=/home/aburtsev/cs238p/qemu-install --target-list="i386-softmmu x86_64-softmmu" --python=/usr/bin/python2.7

Make and install QEMU (this will take some time)

$ make -j 8 $ make install

To make QEMU accessible from other programs add it to your path. You can either add it every time you log in to the circinus machine by exporting the PATH variable:

$ export PATH=$HOME/cs238p/qemu-install/bin:$PATH

Or you can add the command to your ~/.bash_profile to include the QEMU path in PATH automatically evey time you login. You can open and edit such file with the program nano:

$ nano ~/.bash_profile

Use the arrows to go to the end of the file and add these two lines (the first one is a comment):

# Adding QEMU to the PATH variable export PATH=$HOME/cs238p/qemu-install/bin:$PATH

To save and exit, press Ctrl + X (to say that you want to exit), then Y (to say that you want to save the file), and Enter (to confirm your choice).

Clone, build, and boot Xv6

Change back into the cs238p folder and clone Xv6 repository.

$ cd ~/cs238p $ git clone git://github.com/mit-pdos/xv6-public.git Cloning into xv6... ...

If you want, put an eye on what is in

Build Xv6 (you only will see a bunch of output from the make command that invokes the gcc compiler on all kernel files, links the kernel with ld, creates the kernel file system with all user-level programs that will be available inside Xv6, and so on):

$ cd xv6-public $ make

You're now ready to run Xv6.

$ make qemu-nox ...

You are now running Xv6 on top a hardware platform that is emulated by the QEMU emulator. You are now done with the Xv6 setup and can continue moving to any homeworks that are currently assigned.

You can find more information about QEMU monitor and GDB debugger here, feel free to explore them.

Alternative ways to install Xv6 if you feel like it (not required for this class)

Xv6 on your own Linux system

While we provide instructions for how to use Circinus machines, you are more than welcome to configure and run Xv6 on your own laptop, desktop, or VM. If you decide to use your own environment, see the instructions on the Xv6 tools page for how to set up Xv6.

I've successfully built Xv6 on my Ubuntu 14.04 LTS and later on Ubuntu 16.04 and 18.04 LTS. I had to install the following packages in order to build QEMU: libz-dev, libtool-bin, libtool, libglib2.0-dev, libpixman-1-dev, libfdt-dev.

Xv6 in Docker

In case you want to use run Xv6 on your own machine using docker containers, you can try it out as well. I have successfully built Xv6 using the grantbot/xv6 image hosted in the docker hub

In my local machine, I downloaded the Xv6 source code as follows:

$ mkdir XV6_Dev $ cd XV6_Dev $ git clone git://github.com/mit-pdos/xv6-public.git Cloning into xv6...

Next, you will need to setup Docker, if you don't have it already on your machine. I followed the instructions from here.

You will find similar instructions for other OS as well in the docker website. Once you have the setup ready, download the grantbot/xv6 image using

$ docker pull grantbot/xv6

Then you can start the container using

$ docker run -v '/Path to local Xv6 folder/XV6_Dev':/home/a/XV6_Dev/ -i -t grantbot/xv6

Once you have the bash prompt you can type the following to start Xv6:

$ cd ~/XV6_Dev/ $ make qemu-nox ...