Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm a Linux user but I keep a compressed Windows XP ISO with me on a pen drive for the case I absolutely need Windows to do something. This works in VirtualBox most of the time.

But now I want to play some games, so I would like to run the Windows image natively. My computer don't have CD drive so cannot just burn the ISO and make an install normally.

What I trying to do is moving the installed Windows image to a physical NTFS partition on my HDD and set up GRUB to let me dual boot it.

I found many tutorials that deal with making VDI to physical drive. But they assume I want to overwrite my entire drive. Moving the raw disk image with dd to the partition resulted in a corrupt partition.

I also tried the VMDK trick to use that empty partition and install the Windows on it. Although the text mode phase of the installation finishes without problems, the VM won't work, either crashes and keeps rebooting or just immediately freezes (depending on how I created the VMDK, with -rawdisk /dev/sda3 or -rawdisk /dev/sda -partition 3).

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

I spent all yesterday with research, and finally was able to make Windows XP boot. It should be somewhat similar for other OS-es too. But the operation is everything but not trivial.

Because this a dangerous operation, I recommend backing up your precious data.

Here is the steps:

Preparation

In the case Windows XP you need to make it forget the current disk letter and partition settings, so you need to erase all values from the HKEY_LOCAL_MACHINE/MountedDevices key on the virtual machine before the migration. The kernel will rebuild it on the next reboot. On Linux virtual machines, this mean fixing the fstab after migration.

Mounting the VDI image

You cannot just copy the entire VDI to a partition, because it contains an MBR too. You need to copy only the virtual partition, so first you need to find a way to mount the VDI.

You need the nbd driver and the qemu-nbd command. On Ubuntu it's in the qemu-kvm package.

First load the nbd driver:

# modprobe nbd

This should make some nbd devices in /dev.

Then mount the VDI:

# qemu-nbd -c /dev/nbd0 path_to.vdi

This should make /dev/nbd0p1, /dev/nbd0p2, /dev/nbd0p3 etc for all virtual partitions. These can be mounted like any ordinary devices.

Migrating the partition

Use dd for that, unmount both partitions before the operation:

# dd -if=<nbd_device> -of=<real_partition>

eg.:

# dd -if=/dev/nbd0p3 -of=/dev/sda4

Operation of the dd is silent, this may take several minutes, even a half hour. During the operation you may open a terminal and use fdisk -l to see all is going well.

UPDATE:

Apparently nbd is not a foolproof solution. It may cause I/O error and make dd fail. Moreover next try fails immediately. You can also try making a raw disk VMDK with this command (under linux):

$ VBoxManage internalcommands createrawvmdk -filename physical.vmdk -rawdisk /dev/sda

You need to be in the disk group to make it work. Then add this vmdk to the virtual machine as a secondary hard drive, then use a Live Linux ISO to dd the partition.

Fixing the boot sector of the NTFS partition

This is the hackish part.

We are almost ready, but Windows XP won't boot, because we need to set the number of hidden sectors of the filesystem at the offset 0x1C. This basically a number of sectors before NTFS partition. We can get this number from the fdisk -ul command. The start field of the output states which sector the given partition starts at, which is basically the number of sectors before the partition. So get the number from there, convert it to hexadecimal using gcalctool for example.

Open the partition with hexedit, like this:

# hexedit /dev/sda4

Then write the number of hidden sectors in little endian order at the 1C offset. Little endiean means: 0xABCDEFGH will be GH EF CD AB. If the hexa number is shorter that 8 digits, precede it with zero.

When done, save it and exit (Ctrl+X).

Setting up GRUB

You must tell GRUB to boot directly that partition, for GRUB add the following menu entry:

title       Microsoft Windows XP Professional
root        (hd0,3)
savedefault
makeactive
chainloader +1

Where (hdX, Y) identifies the partition. X is 0 for the default harddisk, 1 for /dev/sda, 2 for /dev/sdb etc. Y is the partition number. 0 for /dev/sda1, 1 for /dev/sda2, etc.

This should be similar for GRUB2 too, but it uses a bit different syntax for menu entries.

Final touches

The new NTFS partition is ready to boot up. But you still need some hacking to reach the Windows XP desktop. Other systems might need different hacks. First the boot.ini needs to be fixed.

[boot loader]
timeout=1
default=multi(0)disk(0)rdisk(0)partition(3)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(3)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect

Set the parition number accordingly. I installed it on the /dev/sda4. So the partition number should be 3.

You may need to fix the MountedDevices entry in the registry if Windows freezes right before the logon screen.

The registry is at <path to windows>/system32/config/system you can view it by chntpw. This can be a problem if your system drive letter is not C. Since chntpw's registry writing capabilities are quite limited, you need to fallback and use a hexeditor, like ghex2 to fix it. You need to find \DosDevices\C: and replace the C with a different drive letter, F in my case.

After these, you should be able to reach the desktop, now you need to hunt for all drivers, but this is out of the scope of this tutorial.

Sources

Moving Windows XP to a different partition

Mount a VDI under linux

share|improve this answer
add comment

you can try using partimage and gdisk to do taht. Take gdisk or another partition program and resize your current disk/set up a partition on a disk some where. idealy it will be a primary partition. I usually keep partition 1 for windows and 2+ for linux data.

once a partition is set up you can use the gdisk or another ghost clone to make backup files or straight image to the other drive. it is possible to set up a network connection to the host if you need to drop the file that way or you can make img files then copy then from the vmdk file to your host system... then use the image software to restore the partition to the location you created on the host system

configure grub as needed to add booting to that ntfs partition.

share|improve this answer
    
you can probably also moutnt the vmdk in a mannter that would allow the image software to directly read it from the host jsut depends on how the image software is. –  Kendrick Oct 6 '12 at 23:38
    
I spent all yesterday with research, and finally able to make Windows XP boot. I going to write it down in detail. It's not trivial. –  Calmarius Oct 7 '12 at 7:32
    
its quite ironic but I will need to do this process soon to. I have a pc that doesnt like installing solaris for some reason so I have to pull the data from a vm I have to the new machine. –  Kendrick Oct 14 '12 at 5:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.