Home Engidea Home Circle

Devo scusarmi con i lettori Italiani ma questa parte estremamente tecnica e mi trovo meglio a scriverla in Inglese che Italiano.
Ci sono molteplici informazioni su Qemu e Windows XP, molte sono vecchie e poco accurate, questo documento si riferisce a una Installazione Ubuntu Edgy Eft 6.10 e a Qemu 0.8.2

Windows XP inside Linux

This is a step by step guide on having Windows XP (or any Windows earlier than Vista) to run inside Linux.
I have spent some time finding out the correct info on the web, this is not for lack of information but because the instructions where too many, for different versions of Linux or Qemu.
What I try to do here is to be specific.

This information is for Ubuntu Edgy Eft 6.10 Intel 32 bit architecture and Qemu 0.8.2

IMPORTANT: What I have used

My setup is based on Ubuntu Edgy Eft, also called Ubuntu 6.10 I have installed the standard workstation and I was quite happy with it. Then I did try Xen, mostly to have Windows to run inside Linux and I have realized that Xen uses Qemu to do this, but a rather old version of Qemu.

NOTE: unless otherwise noted all commands are run as root

So I have installed Qemu 0.8.2 using the command:

apt-get install qemu

Qemu does not try to expose your hardware to Windows XP, what it does is to provide fake hardware and emulation to the installed Windows XP, you can then run your favorite strange program in XP using the emulated machine.
In other words it is like having a computer inside a computer and you have to attach disks and network to it.

To actually run windows XP you have to install it from scratch.

You cannot (I did try and the result was a bit of a mess) take a partition with the installed Windows XP and just run it. The reason for this is that the installed XP knows a certain hardware, video, audio, network chips and so on but instead the emulated machine provides different hardware and therefore Windows XP cannot handle it. Some suggest to try by configuring and alternative hardware profile in Windows, I did try but it wanted to validate the Copy every time... not something that Microsoft is happy about. (blame Microsoft, please)

So, the first step, just to play a bit is to create a disk where Qemu can write, create a working directory and type the following.

qemu-img create -f qcow disk-c.img 40G

Note that we use the qcow format since it is quite flexible and do not take excessive space on disk. You can create a 40Gb disk even if you physically have now a 30Gb disk and when you have a bigger disk you can copy the image there and enjoy the extra space. The next step is to actually start the virtual machine and tell it to boot from the cdrom. I have a script that i named winrun.sh like the following

MEM="-m 512"; 			export MEME
NACPI="-no-acpi";		export NACPI        # Needed for Kqemu
DISKC="-hda disk-c.img";	export DISKC
BOOT="-boot d";			export BOOT

if [ -n "$1" ]; then
	qemu -cdrom "$1" $BOOT $DISKC $MEM $KKO $NACPI $NET &
else
	qemu $BOOT $DISKC $MEM $KKO $NACPI $NET &
fi

Install Windows as usual, including service pack two and then start configuring it.
Do not install any extra application yet, I need to tell you about overlay images !

Simple networking

By default Qemu provides an unbridged network interface to the guest system. This means that the two machines (the Host and the Guest) appears "separate". This is quite annoying and complicated. The best thing is to have the machines as if they are in the same network, this is possible using bridging !

Setting up a bridge is not difficult if you understand the logic of it.
The first point to know is that the bridge is handled with special commands, not the normal interfaces commands this simply because it is like to have an extra piece of hardware inside your machine and that needs extra commands.
The second point to know is that all interfaces attached to a bridge share the same network, so, logically if you want to share your Linux eth0 and you newly Ethernet interface of the Guest you have to put them in the same bridge.
Knowing this, lets see the commands.

Enabling IP forwarding

Ip Forwarding needs to be turned on since packets will arrive to eth0 (or whatever interface) and need to be forwarded somewhere else. The simple way to have ip forwarding always set is to enable it into the configuration file /etc/sysctl.conf , search for default.forwarding and remove the comment from the ipv4 version of it.

Installing bridge utils

As said before bridge utils are needed to manage the bridge. On Edgy they are not installed by default, so you just need to add the bridge utils. (Luckily tun is enabled by default).

apt-get install bridge-utils

Create the bridge interface

This is a simple operation that should be done once. Actually, this may just be a test to see if everything done above is correct. If you enable the network config from /etc/network/interfaces then this may be redundant, but do it anyway to check if bridge utils are ok.

brctl addbr br0

Bring eth0 inside the bridge

To do this I am going to change the configuration script. Note that I still wish that dhcp configure my IP address, if your setup is different you have to play a bit with it. The content of my /etc/network/interfaces is:

auto lo
iface lo inet loopback

auto ath0
iface ath0 inet dhcp

auto wlan0
iface wlan0 inet dhcp

auto br0
	iface br0 inet dhcp
	bridge_ports eth0
	bridge_fd 9
	bridge_hello 2
	bridge_maxage 12

Qemu add the new interface to the Bridge

When Qemu starts it runs a script to properly setup the new network interface. The script name is /etc/qeumu-ifup and the new content should be.

#!/bin/sh
echo "Start $1"
/sbin/ifconfig $1 up
echo "Add $1 to br0.."
/usr/sbin/brctl addif br0 $1

Remember that you are running Qemu as root and therefore no sudo is needed.

Add the right parameters

To have Qemu run with a tap interface you need the following options

-net nic -net tap

Why I can ping from guest to host and not the opposite

This is a windows firewall setup. It is quite easy to either disable the firewall or to just allow the ping to pass trough. For all of you that wants to learn a bit more there is a good document that you can look at, thanks to Pavan Shah of Net-square Solutions.
The command to use to enable windows ICMP-ECHO is:

netsh
    firewall
        set icmpsetting 8 ENABLE

Installing and using Kqemu

Kqemu is great, the feeling is that you almost have native performance. There are two types of kqemu: one used to emulate user space programs and the other to emulate the windows kernel. You basically need both on since Windows spend quite some time in itself and therefore you have a huge boost in performance enabling kqemu for kernel.

NOTE: My experience is that to be able to successfully run kqemu you have to remove ACPI, and you should do this before you install Windows

Downloading, compiling, Installing

I am not ading anything here, just look and follow the instructions.
Well, for us from Ubuntu we need to install the essential stuff to compile first.
After that is just a configure, make, make install

apt-get install build-essential linux-headers-generic

Using Overlay images

Overlay Images are great, basically you can keep a "clean" version of Windows and then have many small subversions for each thing you want to try. When you install something new you can test it in a separate version of the system and if you not like it you just trow it away. Try this with real windows :-)

To use overlay images you have to use the qcow version of disk images. The process is as following:

  1. Install a clean windows on something you may call disk-c.qcow
  2. rename disk-c.qcow to disk-c-base.qcow
  3. use qemu-img create -b dick-c-base.qcow -f qcow disk-c.qcow
You will notice how the new disk-c.qcow is much smaller than the base image. Now you can run windows as usual and if after messing with it you want to trow all away just delete disk-c.qcow and recreate it with the command above. You original windows setup is still there !

Using seamless mouse support

It is possible to have the mouse move in seamless mode between the host and the guest. Just add the following opetion to the end of your command line.

-usb -usbdevice tablet

Apparently after this the CTRL-ALT-1 key does not work, no problem, to have the Qemu console just use

-monitor stdio

Putting all together

I have a simple script with all the options in it, you can find it below. Basically if you give a filename as parameter it will be taken as a cdrom ISO image, othervise it starts qemu without cd being set.
There are no error checking, it is just a simple script to get the job done.

modprobe -v kqemu

device="/dev/kqemu"

if [ -e $device ]; then
	echo "kqemu active"
else
	mknod $device c 250 0
fi

MEM="-m 512"; 				export MEM
KKO="-kernel-kqemu";			export KKO
NACPI="-no-acpi";			export NACPI
DISKC="-hda disk-c.qcow";		export DISKC
BOOT="-boot c";				export BOOT
NET="-net nic -net tap";		export NET
SOUND="-soundhw es1370";		export SOUND
SWAP="-hdb pagefile.disk";		export SWAP		# use this disk as pagefile
SMOUSE="-usb -usbdevice tablet";	export SMOUSE		# Seamless mouse
MON="-monitor stdio"; 			export MON		# to have a monitor even when using tablet

CMDLINE="${BOOT} ${DISKC} ${SWAP} ${MEM} ${KKO} ${NACPI} ${NET} ${SOUND} ${SMOUSE} ${MON} ";	export CMDLINE

echo Comando=$CMDLINE

# Since normally the monitor is on stdio then do not background it

if [ -n "$1" ]; then
	qemu -cdrom "$1" $CMDLINE
else
	qemu $CMDLINE
fi


You can find further info at the Qemu Wiky, just be aware that things may be old and irrelevant.