title: Virtual Windows 7
linktitle: virtual-win7
parent: Home
ctime: 2011-07-28

# Introduction

This page documents the process of converting a dual-boot Linux/Windows
installation into a Linux installation running the Windows partition under a
KVM virtual machine.  This work was first performed under Ubuntu 10.10 and
11.04 versions.

# Why virtualize Windows 7?

During my development activities, customer needs infrequently require use of
software only available under Windows.  But booting between OSes is an
incredible waste of time and drain on productivity.  My work notebook, a Lenovo
X201, came pre-installed with an OEM version Windows 7 Home Premium.  The
obvious solution?  Virtualize Windows under Linux.

# Microsoft licensing issues?

[[!pquote text="The OEM Windows EULA allows for virtualization"]]

I downloaded the EULA for Windows 7 from microsoft.com as applicable for
pre-installed OEM versions of Windows 7 Home Premium. For this OS configuration,
the license specifically allows execution of the pre-installed OEM OS when
virtualized on the same hardware. The actual text is found in Section 3.d:

> Use with Virtualization Technologies. Instead of using the software directly
on the licensed computer, you may install and use the software within only one
virtual (or otherwise emulated) hardware system on the licensed computer. When
used in a virtualized environment, content protected by digital rights
management technology, BitLocker or any full volume disk drive encryption
technology may not be as secure as protected content not in a virtualized
environment. You should comply with all domestic and international laws that
apply to such protected content.

# Virtualization requirements

For Windows virtualization to be effective in my development use cases, the
following requirements and constraints must be met.  Additionally, I want the
virtualization solution to support running additional virtual machines as well.

* Run 32-bit x86 Windows 7 from 32-bit x86 Ubuntu Linux 10.10 and newer.
* Run various flavors of Linux or other Intel x86 based operating environments.
* No unnecessary dependences to software or hardware that will limit the
ability of the virtualized OS from functioning properly in the future.
* Ability to run with native disk, not disk-as-file, for improved IO
performance.
* Supports use of VT-x and VT-d, again for performance.
* Will be sufficiently performant on the target hardware when virtualized. The
X201 has an i5-M560 CPU which offers 4 cores at 2.66 GHz each, and 8 GB of RAM.
* Simple management of VMs, including configuration, start and stop.
* VMs must behave sanely in the presence of host OS power saving functionality,
like suspend.
* There is no requirement to continue to run Win7 natively.
* High end graphics are not required: no need for 3D, Aero effects, video
playback, etc.
* And finally, a reliable mechanism return to the prior physical configuration
if the VM experiment fails to work as hoped.

# Selecting a virtualization framework

There are a few virtualization options suitable for use on a development system,
including VMware, Xen, VirtualBox, and KVM.  All can do the job, but KVM was
chosen for a variety of reasons:

* KVM has the features needed, and is available through the standard
Ubuntu repositories.
* KVM management via libvirt is more than adequate.
* KVM can use an SDL local window for rendering the virtualized OS, for quite
good display performance.
* The enterprise features of Xen are overkill for this application.
* VMWare is not open source, so there is some concern about support for this
particular hardware in the far future (I tend to keep hardware for a very long
time).
* VirtualBox can not access USB hardware unless the purchased version is used.

The virtual machine manager, using libvirt, is a pretty nice environment.  This
management tool already supports a few different VM strategies, called
*backends*, and they are likely to improve moving forward.  Therefore, gaining
knowledge about VMM, libvirt, and KVM could in the near future represent
an intellectual asset deployable against future customer needs.

# Disk organization, pre-virtualization

Prior to any changes, the 320 GB notebook disk drive was organized as follows:

    /dev/sda1, 1.17 GiB, Label=SYSTEM_DRV
    /dev/sda2, 78.17 GiB, Label=WindowsOS_7
    /dev/sda3, 19.68 GiB, Label=Lenovo_Recovery
    /dev/sda4, an extended partition container
    /dev/sda5, 15.26 GiB, swap partition
    /dev/sda6, 23.84 GiB, / partition
    /dev/sda7, 159.96 GiB, /home partition

* The SYSTEM_DRV apparently supports the Lenovo ThinkVantage functionality
which includes some backup and restore capability.
* The WindowsOS_7 partition is the one to virtualize, containing the licensed
OEM version of Windows 7 Home Premium that came with this notebook.
* The system boots using Grub2, which initially included an entry to boot the
Windows_7 partition.

# The solution

Unfortunately, the solution is not so simple as to point the VM to the /dev/sda2
partition.  First, the virtual hardware expects to see a hard drive, complete
with partition table.  Second, suitable drivers for the virtual hardware must be
installed into the windows installation.  I took several steps to convert
/dev/sda2 in place to look like a hard drive (kpartx, etc) but the best I could
accomplish was Windows 7 hanging during boot.  Since my expertise with Windows
internals is limited, and so is the information available online, I elected to
do a clean re-install Windows from the virtual environment.

## Create backups

### R&R image

Levnovo offers a recovery capability accessible by booting the Lenovo_Recovery
partition.  I used this to create a recovery image for the WindowsOS_7
partition.

* Create a windows repair disc from the Win7 OS
* Create an R&R recovery boot disc
* Back up the current Win7 image via R&R to the Lenovo_Recovery partition. This
required removing all other prior backups because of size constaints in that
partition.
* Back up the current Win7 image to a set of DVD optical discs. It took 3: a
boot disc and two data discs.

### Partition level backups

Since the space was available in the Linux partition, I opted to create parition
level backups as well, which would be 'easier' to restore, at least for me.

    # Backup the first MiB of /dev/sda to capture MBR and any bootloader stuff
    dd if=/dev/sda of=mbr.save bs=1M count=1
    # Use ntfsclone to make a space-efficient copy of the windows partition
    ntfsclone --save-image -o - /dev/sda2 | gzip -c > sda2.img.gz

## Prepare /dev/sda2 for virtualization

First, /dev/sda2 must look like a DOS style disk, complete with disk level
partition information.  This can be accomplished using this fdisk command:

    fdisk -c -u /dev/sda2

Drive fdisk to create a single windows partition spanning the entirety of the
'disk' (actually the physical partition /dev/sda2).  Now /dev/sda2 will look
like a valid disk image usable by a VM to re-install Windows 7.

## Install the virtualization tools in Linux

    sudo apt-get install virt-manager virt-viewer python-vm-builder \
        kvm-pxe ubuntu-vm-builder

I tested the VM tools by creating an Ubuntu 11.04 install.  I ran the Virtual
Machine Manager using an Ubuntu 11.04 install .iso image as its CD-ROM.  The
installation was successful and the resulting virtual machine worked without
fail.

## Re-install Windows 7

Next windows was re-installed.  A Windows 7 Home Premium 32-bit OEM .iso was
used to do a clean install of Win7. See the virtioinstall.sh script for more
information. I used the Win7 iso, and virtual floppy and CD-ROM images from
RedHat containing signed virtio drivers for disk and network devices. The VM was
started using the virtio disk driver, booting into the Win7 iso. Then the
virtual floppy was accessed during the Win7 install process to load in the
virtio drivers so the Win7 install program could see the disc, which was of
course the disk image on the host /dev/sda partition. I formatted the 'drive'
(which is really the /dev/sda2 partition on the physical drive), then proceeded
to install Win7 onto it. The installation process, from first boot of the Win7
iso, to first user login to Win7, took just under 45 minutes.

At this point, the VM was stopped so its configuration could be altered it use
the virtio network driver.  The VM was then restarted with the virtio iso from
RedHat connected as the virtual CD-ROM disc.  Once Win7 was running, in device
manager the drivers for the broken network device were updated from the .iso to
get the network running.  The virtio network interface seems very efficient. The
VM configuration was finally modified to provide for 2 CPU cores and 2 GB of
RAM.

## Re-activate Windows 7

At this time, Win7 had to be re-activated. The online technique failed, so the
phone call technique was required.  It was a bit painful, but the end result was
a properly activated installation.

## Install other Windows 7 tools

Since I installed from scratch, I had to reinstall the few tools I use under
Windows.  Since these tools were few in number, this process was pretty
painless.  This strategy would be much more painful if there were lots of tools
and/or custom configuration or data required to be recovered.

## Improving diplay performance

The default display mechanism when interacting with the Windows VM display is
VNC.  This is not very performant.  Since the Windows VM is only to be accessed
from the local hardware, I instead configured the VM to use SDL for rendering
the VM display in a window.  Interestingly, this change also allowed sound from
the Win7 VM to propagate to the sound hardware.  The SDL configuration is fast
enough to watch Netflix from the VM.

    Stop the win7 VM
    Reconfigure the VM:
        Remove VNC graphics entry for the VM and add the local SDL one.
        Change the sound driver to ac97
    Edit /etc/libvirt/qemu.conf. Add:
        user = "smckown" 
        group = "smckown" 
    sudo service libvirtd-bin restart
    Restart the virtual machine

### Why not SPICE?

The SDL method creates a new local window that hosts the VM display. It cannot
be embedded into the virtual manager VM window. It looks like the better
solution is going to be to use the SPICE facility. Special drivers in the VM
work with special client features to implement a much improved connection. SPICE
provides better display performance than VNC, can do stereo sound, and also
provides for USB redirection. As of 7/13/12, Ubuntu 12.04 does not have the
right stuff to do spice through virt-manager. There is a PPA that will allow it.
The nice thing about SPICE is it is network-able and can be embedded. Since
network access to the VM is not necessary, the SDL window method seems optimal.

## Anti Virus considerations

It should be noted that the VM, as the native install before it, is running
Microsoft Security Essentials for Anti-Virus.  There appears a noticeable
performance hit for using AV within the VM, in comparison to running it
natively.  Unfortunately, the protection offered is probably worth the
performance penalty.

# Conclusion

I am quite happy with the results of this process. Win7 boots noticeably faster
from the VM than it did on native hardware.  Disk CPU are perceptibly sluggish
within the VM with respect to native performance, but it is tolerable.  Network
performance seems on par with native.  For the tasks in which I will use
Windows, the virtual machine performance is more than adequate.

Of course the big win is that Win7 can be running simultaneously with Ubuntu.
This solves a host of workflow problems and removes the terrible inefficiencies
caused by having to boot between the two OSes natively. For one, I was able to
continue working with apps in the host Ubuntu OS while the Win7 VM chugged away
literally for hours downloading and rebooting ad nauseum as it updated itself
with the latest Win7 SP1 and subsequent patches.

My overall concern with this strategy is that a change in Microsoft policy could
complicate my life.  Although this use of my windows license is perfectly
legitimate according to my reading of the EULA, I depend upon Windows Product
Activation to honor this legitimacy.  Here is to hoping that Microsoft will take
care to ensure that their WPA policies retain convenient use of Windows for all
legitimate uses.

---

# Updates

### 2012-08-13
After using this configuration for over a year, I have found it to be quite
reliable.  The upgrade to 12.04 triggered Windows Product Activation, and
another phone call to the automated WPA phone number was required.  The
activation was successful.

---

# Links

The following links, in no particular order, were invaluable in completing this project. Thanks to all those who published their prior experience for others to use!

* <http://support.microsoft.com/kb/927392>
* <http://answers.microsoft.com/en-us/windows/forum/windows_7-system/hp-mini-210-windows-7-recovery-0xc000000f-bcd/6c79d900-79dc-4f54-bcf7-22edf6f44dd4>
* <http://windows.microsoft.com/en-US/windows7/Startup-Repair-frequently-asked-questions>
* <http://www.sevenforums.com/tutorials/20864-mbr-restore-windows-7-master-boot-record.html>
* <http://www.sevenforums.com/tutorials/104341-bootmgr-missing-fix.html>
* <http://www.sevenforums.com/tutorials/163216-bootrec-exe-tool-how-use-windows-recovery-environment.html>
* <http://brandonkonkle.com/blog/2009/apr/27/lvm-based-virtualization-kvm-and-jaunty/>
* <http://techpp.com/2009/11/11/download-windows-7-iso-official-direct-download-links/>
* <http://bderzhavets.wordpress.com/2011/01/08/set-up-rh-virtio-scsi-driver-on-windows-xp-kvm-at-kvm-qemu-instance-on-f14/>
* <http://techpp.com/2009/11/11/download-windows-7-iso-official-direct-download-links/>
* <http://cloud.ubuntu.com/2011/03/fast-win7-kvm-virtiodisk-net-install/>
* <http://www.sevenforums.com/tutorials/1649-clean-install-windows-7-a.html>
* <http://rghost.net/3412907>
* <http://www.sevenforums.com/installation-setup/156599-help-windows-7-clean-install.html>
* <http://www.sevenforums.com/installation-setup/151566-reinstalling-windows-7-a.html#post1300819>
