I just felt like writing something in English.

Final effect

This is what it’s like when xv6 runs on my ancient T440.

The modified code is here. Below are explanations for the code. If you want concrete instructions however, look at the code.

Changes to xv6

Thanks to those MIT people there isn’t much change to make for xv6 to run on real hardware.

Russ Cox gave some basic instructions in entry.S, like

# Multiboot header, for multiboot boot loaders like GNU Grub.
# http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
#
# Using GRUB 2, you can boot xv6 from a file stored in a
# Linux file system by copying kernel or kernelmemfs to /boot
# and then adding this menu entry:
#
# menuentry "xv6" {
#   insmod ext2
#   set root='(hd0,msdos1)'
#   set kernel='/boot/kernel'
#   echo "Loading ${kernel}..."
#   multiboot ${kernel} ${kernel}
#   boot
# }

That means you basically edit the grub table and then update grub and reboot and, wow, an xv6 entry appears on the grub menu. But there are some subtleties to note however

Let’s address them one by one. I assume you are using Ubuntu 16.04. For different platforms my techniques may not work, sorry for that ;P.

Files to edit

/boot/grub/grub.cfg contains a generated grub configuration file that grub directly uses. You may examine this file, but you are strongly advised against editing it. Search for set root=, and you should see something like set root='hd0,msdos1'. If not, check the partition subsection below.

/etc/default/grub is another file you may touch. If you never see the grub menu during booting, that means the menu is hidden. Enable showing the menu by commenting out the line GRUB_HIDDEN_TIMEOUT=0 here. Alternatively you may press Shift key during booting to bring up the menu.

/etc/grub.d/* are the files we need to edit to get xv6 appear on the grub menu. Specifically we should edit the file /etc/grub.d/40_custom. Simple paste the code into it like

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

### xv6
menuentry "xv6" {
	insmod ext2
	set root='hd0,msdos1'
	set kernel='/boot/kernel'
	echo "Loading ${kernel}..."
	multiboot ${kernel} ${kernel}
	boot
}

After you edit the grub files, run sudo update-grub to put them into effect.

Partition table format

The xv6 menuentry assumes MBR format of the partition table. In recently years the more advanced GPT format is gradually replacing MBR. I tried to get xv6 working with GPT but didn’t have enough grub expertise to get it working, so here we focus on MBR.

To check whether your partition table is GPT or MBR, the most convenient way is to use ubuntu’s builtin utility. Bring up the dash starter, type into disks, and start the disks utility. Select your main disk, and its partitioning format is shown in the partitioning row.

If you happened to use the GPT format, my solution is to repartition and reinstall ubuntu :(

Backup your data before doing these.

Disks

xv6 uses disks. But it support only IDE interface, while modern machines only support SATA.

Our approach is to use a memory simulated IDE. That’s simple, switch to kernelmemfs instead of kernel. Just a few lines in the Makefile.

GRUB subtleties

Switching from xv6’s little bootloader to grub, I met the below errors:

Final steps

Now all we have to do is to copy the kernel image and reboot.

First create the kernel image and copy it

$ make kernelmemfs
$ sudo cp kernelmemfs /boot/kernel

Then reboot, and select xv6 in the grub menu

Conclusion

With the above modification, xv6 should successfully boot on your laptop. Can’t thank the MIT people too much for their work in the little and beautiful xv6 ;)

I admit that some techniques are stupid, and hope to improve them if I had better grub expertise. If the reader have any opinion, I’ll be happy to hear from you!