Instructions for setting up Vagrant xv6 environment

Xv6 is a real operating system kernel, and hence, it needs real hardware to boot. Fortunatelly, 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.

To run xv6 we need to compile and install a version of the QEMU emulator. Due to some compatibility issues it is impossible to compile QEMU directly on the openlab/andromeda machines. Instead, we will work inside yet another virtual machine called Vagrant. Vagrant will start on the andromeda machines, and will boot into a version of the Ubuntu Linux system. Currently vagrant is installed on Andromeda machines 1 through 75: andromeda-1.ics.uci.edu to andromeda-75.ics.uci.edu.

Before you begin, you need to select an andromeda server for yourself. We are following the following method to select a server :

  • Find out your student ID
    (Let's say: 66541280)
  • Evaluate serverNumber = (studentIDNumber mod 74) +1
    Ex: 66541280 => 37
  • Your server name is : andromeda-{serverNumber}.ics.uci.edu
    Ex: andromeda-37.ics.uci.edu

To configure your xv6 environment, login to your server

 
$ ssh UCInetID@andromeda-XX.ics.uci.edu
I suggest you create a new folder for your ics143a homeworks, like:
UCInetID@andromeda-XX$mkdir ics143a
Change into that directory:
UCInetID@andromeda-XX$cd ics143a
Fetch a version of the vagrant environment that explains to vagrant what kind of virtual machine you're planning to run:
UCInetID@andromeda-XX$ wget http://www.ics.uci.edu/~aburtsev/143A/hw/xv6-vagrant-master.tgz
UCInetID@andromeda-XX$ tar -xzvf xv6-vagrant-master.tgz
Change into the new folder
UCInetID@andromeda-XX$ cd xv6-vagrant-master
Change the name of the vagrant VM to something unique (otherwise we all end up with the same VM and vagrant is confused). In the Vagrantfile file change the following line
      vb.name = "xv6_box_anton" # <--- You should change this to make VM names unique
Start vagrant VM (this will take several minutes as it is building QEMU inside)
UCInetID@andromeda-XX$ vagrant up
If vagrant fails with the following message:
==> default: Clearing any previously set forwarded ports...
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 20000 is already in use
on the host machine.

To fix this, modify your current project's Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

  config.vm.network :forwarded_port, guest: 26001, host: 1234
Go ahead with the suggested fix. Change the following line in the Vagrantfile setting the host port to something random below 64000:
  config.vm.network "forwarded_port", guest: 26001, host: 30000
If vagrant VM is up, you're ready to log in inside and start working on your xv6 Linux environment. Log in inside the vagrant VM. From the same folder where Vagrantfile is (i.e., from ics143a/xv6-vagrant-master) type
UCInetID@andromeda-XX$ vagrant ssh

Now you're inside the Linux Ubuntu 12.04.5 LTS. Your new vagrant machine should have everything you need to compile and run your xv6 code. Vagrant automatically shares the directory of your host machine (i.e., odin.ics.uci.edu) where the `Vagrantfile` is as the `/vagrant` directory of the vagrant VM.

Note

While we provide instructions for how to use Andromeda 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. 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.

Finally, there are additional instructions for a yet another alternative setup inside of a Docker container at the bottom of this page.

Boot xv6

From inside your Vagrant VM fetch the xv6 source:
vagrant@odin$ cd /vagrant
vagrant@odin$ mkdir ics143a
vagrant@odin$ cd ics143a
vagrant@odin$ git clone git://github.com/mit-pdos/xv6-public.git
Cloning into xv6...
...
Build xv6:
vagrant@odin$ cd xv6-public
vagrant@odin$ make 
...
gcc -O -nostdinc -I. -c bootmain.c
gcc -nostdinc -I. -c bootasm.S
ld -m    elf_i386 -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
objdump -S bootblock.o > bootblock.asm
objcopy -S -O binary -j .text bootblock.o bootblock
...
vagrant@odin$ 

You're now ready to run xv6.

vagrant@odin$ make qemu-nox
...

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

You're now ready to start working on the homework (go back to the howework page).

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 localmachine, I downloaded the XV6 source code as follows :

localhost$ mkdir XV6_Dev
localhost$ cd XV6_Dev
localhost$ 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

Updated: October, 2017