Friday, March 10, 2006

Using Qemu and Kqemu Under a Debian or Ubuntu Linux Host

In this article, I'll show you how to get the excellent FOSS emulator qemu and its accelerator module, kqemu, up and running on a Debian Sarge or Sid system (you won't find Debian packages for kqemu, and the packaged version of Qemu tends to out of date). I include networking setup, and present a script that automates much of the qemu startup.

Preparation

First, you need the 2.6 or 2.4 kernel sources in /usr/src/linux. To get up and running more quickly, install the kernel source version you are currently running - "uname -r" will tell you this. I'll use the 2.6.8 kernel as an example, since that's what my Debian system is currently running.

apt-get install kernel-source-2.6.8 cd /usr/src tar xjf kernel-source-2.6.8.tar.bz2 ln -s kernel-source-2.6.8 linux

Despite what is on the qemu website, I've found that the kqemu accelerator does not compile if you have not at least compiled a kernel in the kernel source directory. The easiest way to do this is to use the installed config file in the /boot directory - in this case, it is /boot/config-2.6.8-1-386 (assuming you downloaded the kernel source for the version of the kernel you are running).

cp /boot/config-2.6.8-1-386 /usr/src/linux/.config cd /usr/src/linux && make oldconfig && make bzImage

Qemu will use SDL if you have the SDL devel package:

apt-get install libsdl1.2-dev

Also, you'll need sudo to run the script below as a non-root user.

apt-get install sudo

Don't forget to add your user to /etc/sudoers using the "visudo" command - just copy the one line in the default file for the root user, changing "root" to your user name.

On a stock Ubuntu system, you'll need to install GCC and tools (sudo is installed already):

sudo apt-get install build-essential automake autoconf

Building & Installing Qemu and Kqemu

Download qemu-0.8.0.

Download kqemu-0.7.2 (the accelerator) from the same site. Note that this is not free software, as in FSF free, so don't use it if this bothers you.

Untar qemu somewhere, then untar kqemu inside the top-level qemu-0.8.0 directory.

Do

./configure make sudo make install from within the qemu directory. qemu and its associated binaries will be installed in /usr/local/bin.

Note: You need GCC version 3.x to build qemu, GCC version 4.x will not work. You can pass a different compiler to the configure script as './configure --cc=/usr/bin/gcc-3.4'. Run 'apt-cache search gcc' to view a list of installable gcc versions. Further complicating things, if you are running a kernel compiled with gcc 4.x, you need to re-compile kqemu with gcc 4.x after compiling qemu with gcc 3.x. You can do this by re-running the 'configure' script without the '--cc' option and with the '--disable-gcc-check' option from the main qemu source directory, then type 'cd kqemu && make clean && sudo make install'. This will build and install kqemu using gcc 4.x.

Post-Install Setup

Do "modprobe kqemu" to load the accelerator. You may need to create kqemu's device file first (NOTE: in the latest version of kqemu (0.7.2) the kqemu device and permissions are created and set properly for you during the 'make install'):

mknod /dev/kqemu c 250 0 chmod 666 /dev/kqemu

On Debian, you can load the kqemu module at boot by adding the line "kqemu" to /etc/modules to get it to load automatically at boot. You'll need to modprobe the "tun" module, as well, for networking support:

cat >> /etc/modules kqemu tun ^D

You may need to load the tun module with "modprobe tun"; check that it is not already loaded with "lsmod | grep tun".

Creating a Disk Image & Running Qemu

Now you're ready to get started. Create a 10GB qemu disk image in some spare directory: qemu-img create disk.img 10G

The nice thing is that this 10GB virtual disk is a sparse file, so it only uses as much disk space as actually written to it by qemu. The installer sees a flat, 10GB disk, though.

Download any OS ISO image. I used the Debian 3.1 net installer and renamed it "deb.iso". I have a script "run.sh" (below) that will either boot from the cdrom ISO image, or from the qemu disk image, depending on how it is called. Just run the script from the same directory as the deb.iso:

run.sh install - Boots from cdrom/iso file - Use to install run.sh run - Boots from disk image - Use after installation

The "-m" switch to the qemu command controls virtual memory, 128MB is the default, but I put it in anyway to remind me how to increase qemu's memory allocation if needed. Feel free to change it.

My script sets up a networked environment using /dev/net/tun, so you may need to create this device as follows:

mknod /dev/net/tun c 10 200

The host IP is 172.20.0.1, and the guest virtual IP should be something on the same network (by default, Qemu sets this up with a class B netmask - 255.255.0.0). I use a static address of 172.20.0.2, but you could just as easily run a DHCP server on the host OS and use that to assign an IP address, gateway, and DNS client settings. I enable forwarding and NAT in run.sh, so the guest OS session should have Internet access through the host, as long as the host OS is connected to the Internet.

Run a DHCP, web, FTP, NFS, or any other network server on the host and access it from the guest OS as needed. You can also SSH back and forth between OS's. If you install the package dnsmasq on the host OS, you can use that as both a DHCP server and a DNS caching forwarder, allowing fully automatic, install-time network configuration of your Qemu guest OS.

Taking Screenshots of the Qemu Session

Qemu is great for making screenshots of installers, I use ImageMagick's command "import" from the host OS:

import -frame file.png

Then click on the window to capture - it captures just the window you click on into the file "file.png". Use ImageMagick's "display" command to view them quickly.

Tips & Scripts

Once qemu is up and running, the qemu monitor will be shown in the console window you actually ran qemu from. You can change cdroms from this prompt, just type Ctrl-Alt to escape qemu itself, then type "change cdrom deb2.iso", or whatever the second ISO image filename is. You can also switch virtual consoles in the guest OS by typing "sendkey ctrl-alt-f2", for example, in the qemu monitor window.

In any qemu session, use "crtl-alt" to escape out to the host OS.

You should have this two-line shell script in /etc/qemu-ifup, it won't be present if you compiled from source, but may be present if you have ever installed the qemu Debian binary package:

#!/bin/sh sudo -p "Password for $0:" /sbin/ifconfig $1 172.20.0.1

Here is run.sh:

#!/bin/sh # Set the mode for the tun device, # turn on IP forwarding, # and setup NAT for guest OS connections sudo -p "Password for sudo access:" chmod 666 /dev/net/tun sudo sysctl -n -w net.ipv4.ip_forward=1 sudo iptables -t nat -A POSTROUTING -o eth0 -s 172.20.0.0/16 -j MASQUERADE if [ -z "$1" ] then echo "Usage: `basename $0` [install|run]" exit 64 fi case "$1" in "run" ) qemu -boot c -net nic -net tun -cdrom deb.iso -hda disk.img -monitor stdio -m 128;; "install" ) qemu -boot d -net nic -net tun -cdrom deb.iso -hda disk.img -monitor stdio -m 128;; * ) echo "Usage: `basename $0` [install|run]";; esac exit 0 Technorati Tags: , , ,

6 comments:

Matthew Kincaid said...

I used this help to compile and install Qemu under Debian Sarge. Thanks! I appreciate it.

Mathias Brodala said...

You should mention that you need gcc < 4.0 to build qemu.
I tried to build qemu with kqemu but the following error occured:
dyngen: ret or jmp expected at the end of op_bsfw_T0_cc.
This one is not unknown.


Regards, Mathias

Doug said...

Thanks for the comments. I updated the post with a note about gcc 4.x and how to work around it.

Mathias Brodala said...

OK, that's a solution.
But if you compile QEMU and KQEMU this way, you'll get problems with loading the KQEMU module into a kernel which was compiled with gcc 4.x.
For this I found a solution in the QEMU-forums: after compiling and installing QEMU you can compile KQEMU again but this time with gcc 4.x. Only QEMU has to be compiled with gcc 3.x.
Then you can move the kqemu.ko to your modules directory and load it without problems.


Regards, Mathias

Doug said...

Thanks again. I tested your suggestion on an Ubuntu 5.10 box, seems to work great. I also updated the howto again.

Mind Booster Noori said...

Debian etch already has a kquemu package.