Home > Server Admin > Convert an existing Windows installation to a Xen guest

Convert an existing Windows installation to a Xen guest

January 19th, 2010

I’ve been dual booting Linux and Windows for as long as I’ve run Linux on the desktop. Recently I installed Xen on Ubuntu and subsequently decided to port my old Windows bare-metal install to a Xen domU.

Running Windows as a Xen domU has several advantages, the most obvious being the ability to access Windows while running Linux. Additionally, you can take advantage of features such as domain migration, save/restore and LVM snapshots.

In this article, I’ll walk through how I converted my existing Windows XP Professional bare-metal (normal) install to a Xen guest (domU). In my setup, the Xen dom0 is running on an LVM volume on a separate physical disk from the original Windows installation. I will show you how to move the original Windows installation to a LVM logical volume. You will need a retail or volume Windows license. Xen emulates different hardware that will cause you to have to reactivate Windows. An OEM license is not allowed to move hardware. While I’d argue the physical hardware is still the same, I’m sure there is some definition that says otherwise ;) . Finally, I converted a Windows XP installation, but the same procedure should work with any NTFS-based Windows installation (Vista, 7, Server 2003, Server 2008).

One thing before we get started: If you plan on following these directions please back up first! You’ll be partitioning volumes, copying partitions, etc. One slip of the finger and you can wipe your entire system. So be careful and back up!

Windows Disk Layout

Before we begin, let’s discuss the layout of a typical Windows hard drive. The table below shows a hard drive with a single NTFS partition.

Start Sector End Sector Start Cylinder End Cylinder Description
0 0 0 0 Master Boot Record
63 x 1 Total cylinders – 1 NTFS Volume

In order to boot Windows, three conditions concerning the NTFS partition must be met:

  1. The starting sector must be encoded in the partition’s volume boot sector at address 0x1c
  2. The partition should not occupy the last disk cylinder. This is not always true, but in some cases occupying the last cylinder can cause a BSOD.
  3. The partition must be marked bootable

Keep this in mind for now. We will see how it affects us later.

Set up Xen Virtual Block Device (VBD)

In a paravirtualized Linux guest, Xen acts as a bootloader by assigning virtual block devices and starting the kernel. In an HVM domain such as Windows we need a bootloader to start the domain. I chose to use the use the default bootloader that comes Windows XP.

Bootloaders such as Grub and the Windows bootloader are stored in the Master Boot Record of a physical disk. In order to emulate this in our Xen guest we will create a VBD that represents a physical disk.

Xen has several options for VBDs. I’m using an LVM-backed VBD as it is slightly faster than a file-based VBD and allows me to take LVM snapshots. Creating a logical volume is easy, but first we must determine what size to make it.

To meet the criteria in the previous section for booting Windows, we need to have two disk cylinders more than are required for our NTFS partition. To simplify this, just create a logical volume 25MB larger than your Windows’ NTFS partition.

# Create logical volume for our 50GB NTFS partition:
#   50 * 1024 + 25 = 51225 MB
$ sudo lvcreate -nwin_hda -L51225M vg

Partition Logical Volume

Now we need to partition the logical volume we just created. Why do we need to partition a partition? Remember that the logical volume in dom0 represents a physical disk in domU. We need to partition this virtual disk, add a MBR and clone our NTFS volume. Luckily, everything in Linux behaves like a file so we will have no problems partitioning our logical volume.

$ sudo fdisk /dev/vg/win_hda

Command (m for help): n
Command action
  e extended
  p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-6530, default 1): 1
Last cylinder should be one less than total cylinders:
Last cylinder, +cylinders or +size{K,M,G} (1-6530, default 6530): 6529

Command (m for help): a
Partition number (1-4): 1

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 7
Changed system type of partition 1 to 7 (HPFS/NTFS)

Command (m for help): w

Clone NTFS Partition

Now it is time to copy our NTFS partition. The simplest way to do this is by using dd.

# We offset the destination so that our NTFS partition starts at the beginning of the first cylinder
$ sudo dd bs=512 if=/dev/sdc1 of=/dev/vg/win_hda seek=63

This could take a while. Don’t worry if you don’t see anything, dd doesn’t display progress as it works. If you are like me and would rather know how the clone is progressing, install dcfldd and use that instead.

Modify NTFS Boot Sector

If your original NTFS partition was the first partition on the disk, you may be able to skip this step, but it won’t hurt to check.

To satisfy the first condition in the Windows Disk Layout section above, we need to make sure the starting disk sector is encoded in the NTFS boot sector of our NTFS partition. If you have followed the previous steps, your starting sector is 63. To verify this:

$ sudo fdisk -l -u /dev/vg/win_vma
Disk /dev/vg/win_hda: 53.7 GB, 53716451328 bytes
255 heads, 63 sectors/track, 6530 cylinders, total 104914944 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0xe3f4562c

           Device Boot  Start         End      Blocks   Id  System
/dev/vg1/win_hda1   *      63   104888384    52444161    7  HPFS/NTFS

You will need to convert the starting address to hexadecimal and rearrange it:

  1. Convert 63 to hex: 0x3F
  2. Left pad with 0s so you have 8 hexadecimal digits: 0x0000003F
  3. Rearrange pairs so AB CD EF GH becomes GH EF CD AB: 0x3F000000

Now using hexedit, or the binary file editor of your choice, ensure the starting sector address is inserted into the NTFS partition’s boot sector at address 0x1C (remember the NTFS partition starts at sector 63, or byte address 0x7E00).

$ sudo hexedit /dev/vg/win_hda

Move to position 0x7E1C (0x7E00 + 0x001C). In hexedit this is done by pressing Enter, typing 7E1C, and pressing Enter again. Now make sure the 4 bytes at 0x7E1C equal the rearranged pairs above. If not, type the pairs. To save and exit: Ctrl+X. To exit without saving: Ctrl+C.

Fix Master Boot Record

At this point you have a virtual disk (/dev/vg/win_hda) with a single NTFS partition containing your Windows installation. Unfortunately it is not quite ready because there is no bootloader in in the MBR. We can use the fixmbr command on the Windows XP CD to install a bootloader into our virtual disk’s MBR.

First, we need to create a configuration file for our Windows Xen guest. Here is mine, YMMV:

kernel = "/usr/lib/xen/boot/hvmloader"
builder = 'hvm'

memory = 1024

name = "winxp"
vif = []

disk = [
    'phy:/dev/vg/win_hda,hda,w',
    'phy:/dev/cdrom,hdc:cdrom,r'
]

device_model = '/usr/lib/xen/bin/qemu-dm'
boot="dc"
vnc=1

Place your Windows XP CD in your CD drive. You will boot your Xen guest using this CD to access the fixmbr command.

$ sudo xm create /etc/xen/winxp.cfg

Boot from CD:

Press any key to boot from CD

Press any key to boot from CD

At the Welcome to Setup screen, press R to enter the recovery console:

Press R to enter the recovery console

Press R to enter the recovery console

Log on to your Windows partition:

Select your Windows partition

Log in to your Windows partition

Use the fixmbr command to add the Windows bootloader to the MBR. Confirm the ominous warning message as you know what you are doing.

Running fixmbr on the Xen virtual disk

Running fixmbr on the Xen virtual disk

Boot Windows

At this point your Windows Xen guest domainU is ready to boot. Simply reboot the domain:

$ sudo xm reboot winxp

Once your Windows guest boots it should recognize new hardware and want to reboot. You will probably have to reactivate Windows at some point as well. You should probably install the Xen GPLPV drivers as soon as possible. It is probably also a good idea to remove drivers from your old hardware as they are no longer needed.

I recommend accessing your Xen guest over the Remote Desktop Protocol using rdesktop instead of over VNC. You’ll find your Windows is much more responsive over RDP.

Congratulations, you’ve ported your previous Windows installation to a Xen guest. Though it wasn’t a point-and-click migration, it’s still faster then reinstalling Windows and all of your apps from scratch.

Let me know if you found any errors or found this useful. Enjoy your new Xen setup.

Brandon Server Admin ,

  1. April 4th, 2010 at 06:09 | #1

    I’m adding an SSD to an i7/Win7 machine, as a worst-case scenario to dual boot Ubuntu off the SSD and leave Windows on the hard drive. Then when I need to do stuff in Visual Studio with our game client, I’ll just reboot and run Ubuntu in a VMware box.

    But given that the machine is an i7 with 6Gb of RAM, it seems a real shame not to be able to exercise those cores by running both OSes at once.

    I finally realized that Ubuntu doesn’t particularly want to be a Xen host, and after discovering the Xen Live CD I started looking at Debian for the dom0. But I just can’t seem to get it to boot the Windows 7 guest off there on it’s own drive – I couldn’t get it Xen Live to boot the Ubuntu guest currently sitting on the SATA drive, but I suspect that’s because it doesn’t have the right kernel installed :)

  2. April 5th, 2010 at 09:17 | #2

    @Oliver Smith
    What kind of errors do you get when trying to boot Win7 as a domU? I’ve got a Win7 domU running fine on my end, however I installed it from scratch rather than converting an existing installation as I describe in this post.

  1. No trackbacks yet.