Qemu is a PC emulator that can be used instead of a real PC to test your L4 applications. In order to boot something with Qemu we have to create a bootable device as we would for a real PC. You can, for instance, create a CD image to boot or you use a tftp server to load your binaries.
The instructions specified here are for Qemu version 0.9.0. Other versions are mentioned explicitly.
Follow the instructions to create a CD image of your software. Once you obtained the image you can use it as the emulators CD drive (-cdrom) and tell Qemu to boot from it (-boot d).
The full command line would be:
qemu -cdrom /path/to/your/cd-image.iso -boot d
One of the nice feature of Qemu is its built-in TFTP server. The advantage of using a TFTP server to boot your software is that you do not have to recreate the CD image if something changes. You simple replace the binary to use.
If you want to use the built-in TFTP server specify the -tftp Option. Of course this only enable the TFTP server in Qemu--a boot image is still required. The easiest way is to cat the stage1 and stage2 of Grub together into one image. You can use the two files from you local installation of Grub in /usr/lib/grub/i386-pc/.
cat /usr/lib/grub/i386-pc/stage1 /usr/lib/grub/i386-pc/stage2 > grub_disk
You may, of course, use your own version Grub instead of the installed.
Now, you use the created grub_disk as boot image of qemu and the -tftp Option to tell the Qemu TFTP Server where to look for files (in this case in the root directory):
qemu -fda grub_disk -tftp /
The Qemu will boot a Grub with a command line where you may load your configuration file (menu.lst) for Grub. If you want to directly boot this configuration file whenever you boot Grub, simply open the created grub_disk in an editor, search for the string (nd)/tftp/menu.lst and replace it with the location of your configuration file. (For Grub version 0.97-os.6 the string is at offset 0x41c.) Do not insert your string but overwrite the existing string. There are enough zeros after the string that can be overwritten.
With recent versions of Qemu (currently only snapshots after February 19th 2007), you may also boot over the network using PXE. You will need a PXE Grub stage2. After you obtained the recent Qemu and the PXE Grub you can boot Qemu with:
qemu -tftp / -bootp /usr/lib/grub/i386-pc/pxegrub -boot n
Again you can modify the pxegrub binary to directly boot your preferred menu.lst. (For Grub version 0.97-os.6 the string is at offset 0x61c.)
Note for ubuntu users:
If you are using ubuntu as your host OS, you may don't have the pxe binaries installed. If so, you may want to download them from the svn repository:
wget -O pxe-ne2k_pci.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-ne2k_pci.bin?root=qemu wget -O pxe-rtl8139.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-rtl8139.bin?root=qemu wget -O pxe-e1000.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-e1000.bin?root=qemu sudo mv pxe*.bin /ush/share/qemu/
L4 software print lots of useful information on the serial line which can be helpful when debugging. To interact with the serial console of Qemu use the option -serial:
qemu ... -serial stdio
You may also want to modify the amount of memory Qemu uses with the -m option (here 256 MB):
qemu ... -m 256
Here comes a (bit more complex) Qemu sample configuration (a bit Debian/Ubuntu specific) which demonstrates one of its network facilities. Let's assume the following configuration: you got a physical network interface (eth1) in your host pc which you want to connect to your guest OS. Furthermore, you still want to be able to use Qemu's built-in tftp server. This can be achieved by using a software bridge (bridged networking).
- create a configuration for the software bridge (e.g. in /etc/network/interfaces):
auto br0 iface br0 inet static address 192.168.1.1 network 192.168.1.0 netmask 255.255.255.0 bridge_ports eth1 bridge_fd 9 bridge_hello 2 bridge_maxage 12 bridge_stp off
This creates a bridge called br0 and automatically adds interface eth1 to that bridge (seconds interface comes later). The addresses should differ from your normal network configuration (e.g. eth0).
- adopt the sudo config file (e.g. /etc/sudoers)
# Cmnd alias specification Cmnd_Alias QEMU=/sbin/ifconfig, \ /sbin/modprobe, \ /usr/sbin/brctl # User privilege specification root ALL=(ALL) ALL # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL $username$ ALL=NOPASSWD: QEMU
- now adopt your qemu-ifup script (e.g. /etc/qemu-ifup)
#!/bin/sh echo "Executing /etc/qemu-ifup" echo "Bringing up $1 for bridged mode..." sudo /sbin/ifconfig $1 0.0.0.0 promisc up echo "Adding $1 to br0..." sudo /usr/sbin/brctl addif br0 $1
This scripts gets called by Qemu and dynamically adds the tun interface to the bridge.
- now, starting Qemu with the following command should give the guest OS access to eth1 as well as to the internal tftp-server
qemu -serial stdio -m 256 -tftp /l4/ -bootp /tftp/pxegrub -boot n -net user -net nic,model=rtl8139,macaddr=00:11:22:33:44:55 -net tap,ifname=qtap0