WARNING: In the end, I found Windows would only boot from CD. It was installed completely, and booted from the hard drive, but only if the CD was in and I waited out the ``Press any key to boot from CD...'' screen. I don't know why this is, and Google suggests the problem is localized to my system, so I'm posting this article here anyway as though it doesn't happen. You have been warned.

Running Linux and Windows Simultaneously

A Word of Warning

I am a command-line junkie. I live in runlevel 3, only bubbling up to 5 when I need to read PDF's or lay out PCB's, things that I try to do all at once. If you are not comfortable with the command-line, this article is likely not for you.

Having said that, by following my instructions, you can't really go wrong here, so I encourage you to brave on.

Why Not Dual-Boot?

I have been running Linux exclusively for the last ten or so years, and every so often I come across the need to run a different operating system, in order to test a website design, open a funny file, or run a single-system program. Almost always, this operating system is Windows.

The typical solution to this problem is dual-booting. There are many problems with this. Firstly, you need to dedicate one or more partitions to Windows. This is disk space that you can't get back at a moment's notice, can't easily backup to other machines, and is generally a pain to access.

Secondly, Windows has to use your raw hardware. Not only do I not trust Windows to do this, it usually can't: device support is a joke on Windows.

Thirdly, you have to reboot to switch operating systems. You have to close all your programs, unload one system, load the other, and after all that hassle, you're stuck using Windows until you do it again. The whole process makes you think, how much do I really want to use Windows?

The answer for me has always been "not nearly enough". And so I have never dual-booted.

What then?

Instead I propose a new solution: we will create a virtual machine on which to run Windows XP, and run a second X server to connect via VNC. The result will be that Ctrl+Alt+F8 will switch to Windows, and Ctrl+Alt+F7 will go back to Linux. Nobody needs to reboot.

Also backing up or migrating Windows, both of which are normally arcane and error-prone tasks, are now as simple as transferring a disk image between machines.

Prerequisites and KVM

Since kernel 2.6.20, Linux has included a virtualization technology called KVM. The first few iterations were not terribly useful (or secure), though that quickly changed. I hadn't looked at it until a month ago, and judging by how well put-together it is, I must be pretty late to the game.

I am running Fedora 13. The following commands should be pretty much the same for most Linux distributions, but if you're using a different one, you have been warned. Some things might be different. (If you are not running Linux, I strongly encourage you to do so. Until then, this article is not for you.)

In addition to the KVM support included in the kernel, you will also need the utility virt-install. This can be installed by:

yum install python-virtinst
apt-get install virtinst

You also need a VNC viewer. I am using TigerVNC, which is rebranded vncviewer in Fedora 13.

Finally, run all commands as root, or with sudo, or whatever floats your boat.

Rolling Back

If you make a mistake and want to delete your VM and start over, there is a three-step process to deletion:

virsh destroy 
rm /etc/libvirtd/qemu/<VM Name>.xml
service libvirtd restart

The latter steps aren't strictly necessary, but without them, you cannot reuse the same VM name.

Let's Go Already!

Alright, that's enough patter. Let's get to work creating a Windows XP virtual machine. I am assuming that you have an Windows install disk to use.

First, install and enable virtualization support:

yum install libvirtd python-virtinst qemu-img tigervnc
chkconfig --add libvirtd
service libvirtd start

Then, install bridge utilities and setup the network:

yum install bridge-utils
brctl addbr br0
brctl addif eth0  # or wlan0, etc; your primary network device(s)
service network restart

This should be all you need to setup a network bridge to share your network connection with the VM. But your mileage may vary: things are different if you have NetworkManager, for example.

Then, create the Windows disk image. Using the qcow2 format is necessary for some reason; with the virt-install default format, Windows does not install correctly and the next boot fails, saying "disk read error". This is why we do not simply use virt-install to create the image.

qemu-img create -f qcow2 -o cluster_size=2M /var/lib/libvirtd/images/WinXP.img 10G

I'm not sure how important the exact path of that image is. I know that when I tried using an image on /home (where all my free space is), I couldn't get through the drive partitioner in the Windows installer. There are known issues using KVM with images on other partitions. However, my server has

as a separate partition, and its virtual machines - such as the one running this site - are working fine. Go figure.

Next, insert the XP disk and start the installation:

virt-install --name WinXP --ram 512 --disk path=/var/lib/libvirtd/images/WinXP.img,format=qcow2 --cdrom /dev/sr0 --os-variant=winxp --vnc &

The installation is now running. To view and interact with it, we need to start an X server. When you do, it will immediately grab your screen. To get back to your Linux GUI, press Ctrl+Alt+F7. To access the VM again, use Ctrl+Alt+F8. Here is the required command:

startx /usr/bin/vncviewer -Fullscreen localhost -display :1 -- :1
Substitute your VNC viewer and options, if necessary.

Windows XP needs to reboot several times during the installation and subsequent updating. This will disconnect from VNC, and often the VM doesn't come back up on its own. So, restart it:

<Ctrl+C> (to kill the old startx)
virsh start WinXP
startx /usr/bin/vncviewer -Fullscreen localhost -display :1 -- :1