Screenshot of Windows XP running within QEMU on an OpenBSD desktop

A KDE desktop on an OpenBSD laptop, with Windows XP running within a QEMU virtual machine. Within that XP VM, Explorer is viewing an early version of this page (in which you did not see Explorer viewing the page, and so on down to infinity).

How to Install and Run Windows Within the QEMU Emulator On an OpenBSD or Linux Desktop

The following describes how to do this on any Linux distribution or on OpenBSD. It is probably easier on Linux due to the distributions pre-packaging more things for you. This how-to includes all the details, including some steps (like adding QEMU and a BSD kernel module) needed only on OpenBSD.

I use OpenBSD on my laptop because:

Unfortunately, once in a great while I need to do something with the expensive bugware known as Windows.

Yes, OpenOffice and Gnumeric let me handle Microsoft Office documents just fine. That would seem to leave games as the only thing that Windows is really good for. But once in a while I need to figure out where Windows hides a certain piece of data, or just how Windows (mis)behaves in a certain situation, or I have to deal with a poorly written "web page" that isn't really a web page after all, it's nothing more than an Explorer page.

The solution would seem to be VMware, but it isn't available for the OpenBSD operating system. And even on Linux, it's very sensitive to kernel version and distribution. You might have to keep your system running older kernels and therefore older user-space packages to support VMware. And forget about running VMware on other hardware platforms, like the Alpha or UltraSPARC.

No problem — there is a much easier way to run Windows!

The following is based on the web page:
http://qemu-forum.ipi.fi/viewtopic.php?t=78
and the file:
/usr/local/share/doc/qemu/README.OpenBSD
with some corrections and updates and improvements.

Install QEMU and the QEMU accelerator kernel module

If you are using Linux as the host OS, this should be as simple as adding the QEMU packages, probably with names like qemu and qemu-img. See my page on Unix package management for details on how to add those packages. Add QEMU if necessary, then skip to the next section and install Windows.

If you are using OpenBSD, download the qemu and kqemu packages from the OpenBSD FTP archive. They will be somewhere like:
/pub/OpenBSD/release/packages/arch/
where you replace release and arch with your current release and hardware architecture.

% ftp ftp.openbsd.org
Connected to openbsd.sunsite.ualberta.ca.
220 openbsd.srv.ualberta.ca FTP server ready.
Name (ftp.openbsd.org:yourlogin): ftp
331 Guest login ok, send your email address as password.
Password: ________
ftp> cd /pub/OpenBSD
ftp> dir
ftp> cd release
ftp> dir
ftp> cd packages
ftp> dir
ftp> cd arch
ftp> dir *qemu*
ftp> bin
ftp> mget *qemu*
ftp> quit

Now install those two packages:

% su root -c 'pkg_add -v qemu-*.tgz kqemu-*.tgz'

As recommended, add some lines to the boot script /etc/rc.securelevel as shown below. Also add yourself and any other users you want to the group _kqemu by modifying /etc/group appropriately. The lines added to /etc/rc.securelevel are highlighted below:

#	$OpenBSD: rc.securelevel,v 1.16 2004/07/06 04:05:03 deraadt Exp $
#
# site-specific startup actions, daemons, and other things which
# can be done BEFORE your system goes into securemode.  For actions
# which should be done AFTER your system has gone into securemode
# please see /etc/rc.local

# This is the desired security level
# XXX
# XXX it is not really acceptable to put this value in a configuration
# XXX file, because locking it down requires immutability on about
# XXX 5 files instead of 2 (the kernel and init)
# XXX
securelevel=1

echo -n 'starting pre-securelevel daemons:'

#
# Place local actions here.
#

if nm /dev/ksyms | grep mp_lock > /dev/null; then
        if [ -r /usr/local/lib/kqemu/kqemu_mp.o ]; then
		echo -n ' kqemu'
		/sbin/modload /usr/local/lib/kqemu/kqemu_mp.o
        fi
else
        if [ -r /usr/local/lib/kqemu/kqemu.o ]; then
		echo -n ' kqemu'
		/sbin/modload /usr/local/lib/kqemu/kqemu.o
        fi
fi

echo '.'

Reboot to load the kernel module and completely recreate your user credentials. Plus, let's make sure that we haven't broken anything before continuing!

Install Windows in a QEMU Emulator

This was easier for me than the web page referenced above suggested it would be. But just in case, I'll provide alternatives in case you need to work around problems.

First, let's put our Windows virtual machine somewhere we can easily find it without cluttering things up. The location ~/windows made sense to me:

% cd
% mkdir windows
% cd windows

Now create an empty disk image. 8 GB was going to be more than enough for what I wanted to do. It would be nice to have an image that would fit on one single-layer DVD, so 4500M would have been a better choice than 8G for the size specification if I had been certain that what I needed to do would have fit into that space.

% qemu-img create -f qcow2 virtual.hd 8G

    create     = What we're doing, creating a new disk image
    -f qcow2   = Most versatile format, supporting sparse file
                systems, AES encryption, zlib-based compression,
                and multiple VM snapshots
                  "cow" = "copy on write",
                  "q" = "qemu",
                  "2" = version 2, not the older and
                        less capable "qcow"
    virtual.hd = The name of the image file to create
    8G         = 8 gigabytes

Unlike some people, I had no trouble getting qemu to boot from a physical drive. I simply put a Windows XP install DVD in the drive and used that. However, if for some reason that didn't work, you could always use k3b or similar to create an ISO image of that DVD. That could even be done on another system and shared over NFS.

I suspect that their problem might have been caused by ownership and permissions on the CD/DVD device itself. Compare the owner, group, and permissions reported by:
% ls -l /dev/cd0a
to your credentials reported by:
% id
and adjust as needed.

OK, let's do the initial installation:

% qemu -m 128 -cdrom /dev/cd0a -boot d -monitor stdio -no-acpi virtual.hd

    -- or, if that doesn't work --

% mkdir /tmp/nfs
% su root -c 'mount server:/home/cromwell /tmp/nfs'
% qemu -m 128 -cdrom /tmp/nfs/xp.iso -boot d -monitor stdio -no-acpi virtual.hd

    -m 128               = Let the virtual machine have 128 MB of RAM.
                           This should be no more than half the
                           physical RAM in the system.
    -cdrom /path/to/dvd  = Specify the CD/DVD device or ISO image.
    -boot d              = Boot from device D, the CD/DVD.
    -no-acpi             = Disable the disfunctional ACPI.
    virtual.hd           = The file containing the virtual disk image.

Hey, look, it works! It's the Windows installation boot process running within a window on your OpenBSD desktop. Get it started and then go do something else for a while.

It will get to some point and want to reboot from the partially installed hard drive. Since we're running on a virtual disk image, we will have to use qemu to tell it how to do that.

In the terminal emulator where you started qemu you should be looking at a qemu prompt. Type q and <enter> to effectively power off the virtual machine.

Now leave the DVD in the drive (or the ISO image mounted) and start qemu a little differently. Notice that we are not passing the -boot d parameter specifying a boot from the DVD device. The hard disk is the default boot device:

% qemu -m 128 -cdrom /dev/cd0a -monitor stdio -no-acpi virtual.hd

    -- or, if that doesn't work and the ISO image is still mounted --

% qemu -m 128 -cdrom /tmp/nfs/xp.iso -monitor stdio -no-acpi virtual.hd

Now get the secondary installation running, and go away and do something that takes even longer....

Once it's done installing, shut down Windows and quit the emulator. Then just start it the same way as shown above. I created a one-line shell script to save typing.

Networking on Windows within a QEMU Virtual Machine

I simply set up networking to use DHCP, as QEMU includes a tiny DHCP server! Go into the Control Panel, select Networking, then LAN Connection, its Properties, and TCP/IP. Then specify to get the IP address and the DNS server address automatically.

That resulted in the following promising output:


c:\>ipconfig /all

Windows IP Configuration

        Host Name . . . . . . . . . . . . : qemuxp    (or whatever....)
        Primary Dns Suffix  . . . . . . . :           (need to fix this....)
        Node Type . . . . . . . . . . . . : Unknown
        IP Routing Enabled  . . . . . . . : No
        WINS Proxy Enabled  . . . . . . . : No

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :
        Description . . . . . . . . . . . : Realtek RTL8029(AS)-based ....
        Physical Address  . . . . . . . . : 52-54-00-12-34-56
        DHCP Enabled . .  . . . . . . . . : Yes
        Autoconfiguraiton Enabled . . . . : Yes
        IP Address  . . . . . . . . . . . : 10.0.2.15
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 10.0.2.2
        DHCP Server . . . . . . . . . . . : 10.0.2.2
        DNS Servers . . . . . . . . . . . : 10.0.2.2
        Lease Obtained  . . . . . . . . . : (just a few minutes ago...)
        Lease Expires . . . . . . . . . . : (tomorrow...)

The Realtek RTL8029(AS) emulation and the MAC address are defined by QEMU. 10.0.2.2 appears to the virtual machine to be its DNS server, DHCP server, and default gateway. Really that's the QEMU software.

However, things aren't quite working correctly yet. DNS works, nslookup works just fine. But the only thing you can contact via ping or tracert or anything else is 10.0.2.2.

Here is what the networking situation initially seemed to be:

+--------------------------------+
| OpenBSD                        |
|                                |
|  (-------------------------)   |                    Firefox users may find that "monospace"
| ( QEMU                      )  |                    isn't really a constant-width font.
| (                           )  |                    Courier works much better for
| ( +---------+               )  |                    ASCII art.
| ( |Virtual  |   (--------)  )  |
| ( |Machine  |  ( DHCP/DNS ) )  |
| ( |WinXP    |  ( /routing ) )  |
| ( |10.0.2.15+--( 10.0.2.2 ) )  |
| ( +---------+   (-----+--)  )  |
| (                     ^     )  |
| (                     |     )  |
|  (--------------------|---)    |
|                       |        |
|                   DNS |        |
|                       |        |
|                       v        |
|                   resolver     |    +--------------------------+
|                       ^        |    |Linux       DNS/DHCP/NAT  |
|                       |        |    |                          |                  (~~~~~~~~~~)
|                       v        |    |                          |    +-------+    (            )
|                      10.1.1.230+----+10.1.1.100  98.223.229.141+----+ Cable +---( The Internet )
|                                |    |                          |    | Modem |    (            )
+--------------------------------+    +--------------------------+    +-------+     (~~~~~~~~~~)

DNS works because QEMU is an application making calls to the resolver library. It's QEMU that is generating and receiving the DNS queries and replies out via 10.1.1.230 to 10.1.1.100.

Sniffing packets with Wireshark reveals the mystery!

Stupid but typical Microsoft warning

The ICMP packets used by ping and tracert are being replaced by UDP port 7 (echo) packets by Slirp, used by QEMU and replacing the original network and transport layer encapsulation. My firewall isn't masquerading and passing UDP/Echo packets, and I wouldn't expect other firewalls to do so, either. TCP protocols like HTTP, FTP, and SSH work just fine. I'll just have to remember that ping and tracert just don't work from the virtual machine, but that doesn't mean that networking is broken.

My diagram needs to be a little more complicated to reflect reality:

+----------------------------------+
| OpenBSD                          |
|                                  |
|  (----------------------------)  |
| ( QEMU                         ) |
| (                              ) |
| ( +---------+                  ) |
| ( |Virtual  |                  ) |
| ( |Machine  |   (-----------)  ) |
| ( |WinXP    |  ( DHCP        ) ) |
| ( |10.0.2.15+--( 10.0.2.2    ) ) |
| ( +---------+  ( DNS routing ) ) |
| (               (-+-----+---)  ) |
| (                 ^     |      ) |
| (                 |  (-----)   ) |
| (                 | ( Slirp )  ) |
| (                 |  (-----)   ) |
| (                 |     ^      ) |
|  (----------------|-----|-----)  |
|                   |     |        |
|               DNS |     |        |
|                   |     |        |
|                   v     |        |
|               resolver  |        |
|                   ^     |        |
|                   |     |        |
|                   v     v        |
|              +---------------+   |    +--------------------------+
|              |      IP       |   |    |Linux       DNS/DHCP/NAT  |
|              +---------------+   |    |                          |                  (~~~~~~~~~~)
|              |  802.2/802.3  |   |    |                          |    +-------+    (            )
|              |     10.1.1.230+---+----+10.1.1.100  98.223.229.141+----+ Cable +---( The Internet )
|              +---------------+   |    |                          |    | Modem |    (            )
+----------------------------------+    +--------------------------+    +-------+     (~~~~~~~~~~)

Everything works just fine if you have multiple interfaces on the host OS. QEMU is a user process running on that OS, and the operating system simply uses its routing table to decide which interface to use, and how. This seems to me like a huge improvement over VMware and its obsession about the first Ethernet interface.

See http://www.h7.dion.ne.jp/~qemu-win/HowToNetwork-en.html for far more details on QEMU networking.


Installing Office on that virtual Windows system

VMware Networking

How to install the QEMU emulator and Linux on a USB device, so you can run Linux within a window on a hosting maching running Linux or BSD or Windows

How to install and run Windows within the QEMU emulator on an OpenBSD or Linux desktop

Installing Office on that virtual Windows system

Back to the Unix page...

Click here to inquire about advertising on this or any page on this site.
Home Unix/Linux Networking Cybersecurity Travel Technical Radio Site Map Contact


Use /bin/vi! Manipulate images with ImageMagick! Hosted on OpenBSD
Hosted on Apache This site is viewable with any browser Valid XHTML 1.0! Valid CSS!
© Bob Cromwell Feb 2012. Created with /bin/vi and ImageMagick, hosted on OpenBSD with Apache.    Root password available here, privacy policy here.