FDS-TEAM
Linux, Windows, Programming and more...
Use a real Windows 7 partition in Virtualbox / KVM / VMware Player under Linux
25 Dec 2013 22:13 CET  - 22 comment(s)

Info:

This tutorial is a translation of a german blog post which I wrote about a year ago and is available here

Every linux user knows that for some Windows programs or services do not exist equivalent linux programs. This is especially true if the internal functionality of such programs should be kept secret (for example DRM based software), so you need to use Windows or Wine. One way to keep your normal desktop enviroment while doing this, is to use a virtual machine like Virtualbox or KVM. This works well, as long as you don't want to play games or use any other software which makes heavy usage of 3D. In this case you need to use a real Windows installation and you most likely will end up with two Windows installations which needlessly consume more space than they should. In this article I will show how to boot an existing Windows 7 Installation in Virtualbox/KVM/VMware, so that you will only need one Installation, which can be booted inside a VM or on your real system.

From a technical point of view this "Dualboot" method works flawless though it is not compatible with Microsofts license restrictions. Microsoft wants you to buy a second license if you want to use the system inside a VM and on a real machine disregarding the fact that the installation can not be used twice at the same time. Even if you would buy a second license of Windows 7 the system would still not be able to make use of both of them since you can only enter a single serial number which is used during the activation. This may lead to the problem that Windows wants to be reactivated after every switch between the VM and a real boot as the activation system will detect the change of the hardware. Depending on the used VM software it is possible to tweak some settings like HDD serial numbers and similar stuff to prevent this, but this is still kind of a hack.

Warning:

This tutorial should be considered as proof-of-concept because of the license problems mentioned above

Before we are going to start, I would like to explain why it makes sense to follow this more complex tutorial and not one of the easier ones you can find in the internet.

Most other tutorials create a new Master Boot Record (MBR) including a new partition table which basically contains the same partition layout as your real hard drive. The problem is that not all information is copied, most noticeable the Disk Signature is left out. This signature is written by Windows during the installation and is used by the kernel to identify the device containing the Windows installation you want to boot. There is also a similar system on Linux which is based on UUIDs and allows you to define the partitions in /etc/fstab without the problem that your drive letters (sda/sdb/..) may change on each boot. If you don't pay attention to this signature Windows can not be booted and you need to repair the system using the installation CD and it is necessary to repeat this step every time you want to switch between the VM and a real boot. In this tutorial we are going to create a MBR which contains exactly the same signature so that it is not necessary to alter anything in your current Windows installation.

If you installed Windows on a separate hard disk instead of a separate partition it is not necessary to pay attention to this signature and you can skip some of the steps inside this tutorial (as long as the Windows 7 boot partition is also on this hard disk).

Another advantage of the described method is that it is almost independent from the used virtualization software and we do not rely on any special features so that you can switch between different VM software at any time. We just need some linux commands and a Windows DVD (which we could avoid, but this would require some more effort) and create a virtual hard disk pointing to the real Windows partitions. It contains everything we need to boot Windows and you just need to select it inside your VM software. Some other tutorials use a special function of Virtualbox which needs full read access to your hard drive (not only the windows partitions!) to create the necessary virtual hard drive. Since this step is necessary every time you want to start Windows in the VM, it is a significant security risk, as all programs running with this user account could modify all files on the hard drive. This tutorial will just require read and write access on the Windows partitions when using the VM.

# 1. Preparation

If you still want to follow this tutorial although it is not compatible with Microsofts license restrictions, I recommend you to create a backup of your windows partition. We are working with raw disk access and a small mistake may damage the containing NTFS filesystem and therefore make it unreadable. If you have any questions while following the described steps feel free to write a comment so that we may help you before you accidentally do something wrong. Your question may also help other people who try to follow this guide.

If you are using Windows on a separate hard disk you can skip the first steps and directly continue with Step 5. If this is not the case for you and you just installed it to a separate partition, it is necessary to do some extra work to convince Windows that there is no difference between our virtual disk and the real hard disk. Before we can create this virtual hard drive we need to collect some information which is used in the following steps. First of all, we need the partition layout of the hard drive containing Windows. In my case the Windows partition is located on /dev/sda and we can use fdisk to get then necessary information:

sudo fdisk -l /dev/sda

Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xdee1dee1

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
/dev/sda2          206848   204802047   102297600    7  HPFS/NTFS/exFAT
/dev/sda3       204804094  1953523711   874359809    5  Extended
/dev/sda5      1937899520  1953523711     7812096   82  Linux swap / Solaris
/dev/sda6       204804096  1937899519   866547712   83  Linux

Partition table entries are not in disk order


As you can see in the output of fdisk, there are two partitions used by Windows 7 /dev/sda1 and /dev/sda2. The first one is only about 102400 Blocks big and contains the bootloader and the Recovery System. We need both partitions to boot Windows inside a VM. In my case the partitions are located at the beginning of the drive which makes the next step a bit easier. Before we create the virtual hard drive which points to these two partitions, you should make sure that you have a Windows 7 DVD either as real disk or as iso file since it is required in the next step.

# 2. Creating a virtual hard drive pointing to real partitions

In theory we just need to forward these two partitions to a VM and we should be able to boot Windows, but it is a bit more complicated. First of all our virtual hard drive would not have a Master Boot Record (which is required to boot) since the MBR is located in the first Sector of the hard disk. Moreover Windows has saved the location (i.e. start address) where the windows partition can be found on the hard drive. To get around these problems we need to create a virtual hard drive which points to the two windows partitions and which additionally contains a valid MBR + partition table.

As we saw in Step 1 the first 2048 Sectors are not used by any system (0-2047) and the first partition (in my case the windows partition) starts at sector 2048. We need to fill this hole, but we can not take the real 2048 bytes as they contain the Grub bootloader. Instead we simply make a small image file:

dd if=/dev/zero of=boot.mbr count=2048


count is the number of sectors we need to fill up and depends on the output of fdisk during the first step. It may also necessary to adjust the size of a sector which can be done by specifying bs=… as paramter. In my case the size of a sectors is 512 (as written in the output of fdisk) and this is also the standard sector size for dd and I can therefore skip this parameter. If you need to fill up several GBs, it is recommended to use a sparse file instead of a normal files. A sparse file is not really filled up with zeros but only saves the amount of zeros it contains and therefore saves a lot of disk space. You could create one with the following command:

dd if=/dev/zero of=boot.mbr count=0 seek=2048


Sparse files are much slower, if a program tries to write to arbitrary positions in the file, than normal files but as we just use the first 512 Bytes of this file it won't be a problem.

Now we need to create a virtual hard disk which contains our image as well as the 2 windows partitions. The easiest way to accomplish this is to use a software RAID. We can use the linear raid mode (NRAID) offered by the linux kernel to simply to put them together. Before we can do this, we need to install the mdadm utility which allows us to configure such RAIDs and we also need to load the required kernel module:

sudo apt-get install mdadm
sudo modprobe linear


The RAID module can only use devices as source disks but not images, so we first need to create loop back device from our image file before we are finally able to put them together:

sudo losetup /dev/loop0 boot.mbr
sudo mdadm --build /dev/md0 --level=linear --raid-devices=3 /dev/loop0 /dev/sda1 /dev/sda2


The virtual disk is created and we now need to fill up the partition table with useful values as it contains only 0s at the moment.

We can use fdisk again to accomplish this:

sudo fdisk /dev/md0


If your sector size does not match 512 byte, you need to need to tell the correct size to fdisk by using the parameter -b. This time we are in the interactive mode of fdisk and we need to recreate the partition table from above but we can skip everything beside the Windows partitions.

You can create new partitions by pressing n, the key a can be used to mark them as bootable, the filesystem type can be changed with t (for Windows/NTFS the type is 7), p allows you to take a look at the current layout and w finally write everything to the disk and exits the program.

The easiest way to recreate the partition table is to create the partitions in the same order as shown in Step 1. Be careful that every number is correct and that there is no difference between the recreated and the original partition table. This is the most critical step in the tutorial and you can easily destroy your NTFS filesystem by doing a mistake here. In my case the recreated partition table is:

   Device Boot      Start         End      Blocks   Id  System
boot.mbr1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
boot.mbr2          206848   204802047   102297600    7  HPFS/NTFS/exFAT


One way to check whether the partition table is most probably correct is to mount the partitions /dev/md0p1 or /dev/md0p2 in Linux as read only. If you can mount them and browse through files without problems you most probably did everything right.

One thing which is very important is that Linux now recognizes your Windows partitions on 2 different drives (for example /dev/sda1 and /dev/md0p1) and won't prevent you from mounting the same partition twice. This will most likely destroy the file systems located on them, so you should always double check that you do not accidentally get into this situation. As we are going to use the virtual hard drive in the VM as next step, you should unmount it again.

# 3. Using the virtual hard drive inside a VM

As the next step depends on the used VM software they are split into sections and I will explain the necessary steps for Virtualbox, KVM and VMWare Player.

## 3.1. Virtualbox

We need to create pseudo VMDK file which simply points to our virtual hard drive so that we can select it as hard disk file in Virtualbox:

sudo VBoxManage internalcommands createrawvmdk -filename windows.vmdk -rawdisk /dev/md0


## 3.2. KVM

KVM does not need any extra file. You just need to select /dev/md0 as hard disk with the format raw.

## 3.3. VMWare Player

As first step wee need to create a new VM by using the wizard and we also need to create a dummy hard disk (which we do not need) during this step as the wizard does not allow us to directly select a physical disk. You can delete the dummy hard disk later on. After creating the VM, edit it again, remove the dummy hard disk and add a new hard disk. Select “Use a physical disk”, enter /dev/md0 als device path and finally select “Use entire disk” to use our virtual hard disk.

# 4. Installation of the Bootloader

The next required step is to install a bootloader into our MBR. We could use GRUB as in our real system, but GRUB has the disadvantage that it needs a partition where it can store it configuration files and this would require us to create an additional one. We can get around this problem by simply using the original Windows 7 bootloader since we already have a working Windows 7 boot partition in our virtual hard drive. The only thing we need to do is to use the Windows DVD inside our VM and tell it to write the bootloader into our MBR (which is located in the image file we created).

Before we can do this, we must gain access to our virtual hard drive as it is currently owned by root,otherwise Virtualbox/KVM/VMWare can not access them. The best method is to use chown and set our user account as owner of the virtual hdd (so we will be able to access the windows partitions but not the linux partitions on the real hard drive), which can be accomplished by executing: chown user:group /dev/md0. For a short test it is also possible to start the VM software as root.

If you did not already create a new VM instance in Virtualbox/KVM it's now time to do this. Simply create a new VM with the default settings for Windows 7 and attach your Windows DVD to it. For Virtualbox you just need to select the windows.vmdk file as hard disk and kvm users just select /dev/md0 on the command line or via the virt manager. It is not time to fire up our VM for the first time.

You need to press a key when the Windows DVD shows up the corresponding message to boot from the DVD. After some seconds you should see a language selection dialog and you need to press SHIFT + F10 now to get the command line interface (it would be much more complicated to click through the gui to get to the required commands).

Simply execute the following command to fix the bootloader inside our virtual MBR:

bootrec /FixMbr


You could now assume that we did everything necessary to boot up Windows but as I mentioned a bit earlier, windows has a bad surprise for us: The bootloader and the windows system identifies itself by using a disk signature which is a 4 Byte unsigned integer plus the start offset of the partition. The start offset should be the same as we copied the necessary parts of the original partition layout, but the disk signature is now different. We need to fix this problem by altering the disk signature inside our virtual MBR as described on TechNet. We can now either change it by using a hex editor or by using some commands inside the recovery environment. Since we are already inside the recovery environment I decided to use the second approach.

First of all we need to find out the value which is expected by Windows and the easiest way to do this, is to read this information from the registry. We therefore need to find out which drive letter was assigned to our windows partition and load the registry. Since we only have two partitions, we can simply take a quick look at their content:

dir C:
dir D:


One of them should be empty, as all files are hidden (the boot partition) and the other one should contain the usual directories of a windows installation (Windows, Users,…).

To load the registry hives (as described for examplehere) we just use reg load and start regedit (In my case D: was assigned to my windows partition):

reg load HKLM\Computer_System D:\Windows\system32\config\system
regedit


Now navigate to HKEY_LOCAL_MACHINE\Computer_System\MountedDevices and you should see a listing with all hard drives. We are just interested in the first 4 byte / 8 characters of the Windows drive (usually \DosDevices\C:). These are the values of the disk signature and are required for the next step.

Disk Signatures

Before we can set the value inside our MBR we need to pay attention to the fact that the byte order between the registry and the utility which we are going to use for setting the id is different. We need to swap the values between little endian and big endian: For example if you see the values ab cd ef gh in the registry you will need to convert it to gh ef cd ab for the next command. The id can be simply set by using the diskpart utility:

diskpart
DISKPART> select disk 0
DISKPART> uniqueid disk id=ghefcdab
DISKPART> exit


You may now come across the problem that a Windows does not load all drivers during the boot and therefore may not be able to access the hard drive as only the drivers are loaded which are normally required to access the device on a real boot (i.e. SATA or IDE drivers). If you want to use the IDE device controller in KVM or a PIIX3/PIIX4 IDE controller in VirtualBox or if you are using the VMWare Player, make sure that the following entries in the registry:

HKEY_LOCAL_MACHINE\Computer_System\ControlSet001\services\atapi\Start
HKEY_LOCAL_MACHINE\Computer_System\ControlSet001\services\intelide\Start
HKEY_LOCAL_MACHINE\Computer_System\ControlSet001\services\pciide\Start


are set to zero / 0. Windows will not load the IDE drivers if it is installed to a SATA disk since this will speed up the boot sequence but may get you into trouble if you want to backup the system or use it in a VM like in our case.

That's all we need to do before we can start our System for the first time. Simply close regedit and unload the registry hives again:

reg unload HKLM\Computer_System


All changes we have done so far affected only our virtual MBR and the real partitions were not altered yet (except enabling additional drivers if required). Now it is time to adjust some settings and fire up our Windows installation in a VM.

# 5. Using Windows 7 in a VM

If you installed Windows to a separate hard drive or followed all the steps till here, we just need to alter some settings in our VM before we can finally boot Windows 7 for the first time inside our VM. You should now have the disk attached to a virtual machine as described in Step 3 and we need to tweak some CPU settings since Windows uses different kernels for different CPUs and you may get problems if you CPU supports less features than during the installation.

## 5.1. Virtualbox

Go to System -> Acceleration and make sure that VT-X/AMD-V is enabled. As next step check that PAE/NX is enabled at System -> Processor, since this is one of the features which is used to distinguish between the different kernel versions. Moreover NX is also a security feature and it is therefore recommended to enable it anyway.

## 5.2. KVM

If you are using the virt-manager, you can simply go to the options of the Windows VM and click "Copy Host-CPU-Configuration" under Processor and then save the changes.

If you are directly using the command line interface, you can achieve the same by passing -cpu host as parameter. You can also find some performance tips on the website of KVM.

## 5.3. VMware Player

The default settings are already optimal, if you choosed Windows 7 (x64) as operating system. You just may need to enable the sound manually.

If you try to boot Windows 7 and did not enable a required driver in Step 4, you will most likely see the following Bluescreen:

Error: INACCESSIBLE_BOOT_DEVICE

The cryptic error code 0x0000007B simply means INACCESSIBLE_BOOT_DEVICE and wants to tell us that the bootloader was able to find the Windows partition and that the kernel was loaded, but it can not access any files on this partition. As described above this is caused by the fact that you are using a different device driver (i.e different IDE or SATA Controller) between your real device and inside of the VM. Windows does not load all of them to shorten the boot time.

# 6. Result

## 6.1. Virtualbox

If you have problems booting Windows inside of Virtualbox, the easiest way to fix this problem is to try out the different supported IDE and SATA controllers as one of them is most probably supported by the loaded Windows drivers.

During my first try I was able to boot my system with the IDE controller and the ICH6 chipset even without enabling additional drivers inside the registry but I had problems with constant freezes. I therefore tried to exchange the controller with a SATA controller and got a bluescreen again.

Interestingly, the problem was gone after exchanging the IDE controller, which was used by the virtual CD drive, with a SATA controller, so that only SATA controllers were used.

If you want to improve the integration of the VM into your current system, you can install the Guest Additions. They won't have any bad impact if you do a real boot since the devices offered by Virtualbox are not available during a normal boot and therefore the corresponding drivers will not be loaded. The only thing you need to pay attention to is 3D Acceleration. In (at least) older versions of VirtualBox, there was no direct support for DirectX and the Guest Additions replaced the DirectX 8/9 DLLs with the wrapper libraries of Wine which translate the Direct3D functions to OpenGL, so that the host system only needs to offer OpenGL support. This would also affect a real boot since some system DLLs get replaced in this step. Newer versions of Virtualbox support a WDM driver, which is simply an additional graphic driver that does all the 3D acceleration work, so that all your system files stay untouched. Be sure to select the WDM driver if the installer asks you (may require to boot into safe mode).

If you followed all the steps, your result should look like:

Windows 7 in Virtualbox

## 6.2. KVM

If you want to use the IDE controller in KVM, you most likely need to change some registry settings in Step 4 to be able to boot the system but I would recommend to use the VirtIO driver instead, since it is known to have a better performance. You will need to download and install the VirtIO driver from the KVM website in Windows before you can enable it in KVM. I didn't test this driver as I required 3D acceleration, which is not yet supported by KVM, and therefore didn't want to install additional drivers for virtual machines. Anyway, the system also worked with the IDE drivers but was very slow.

## 6.3. VMware Player

The virtual hard disk is added as IDE device in VMWare and I therefore had to enable the IDE drivers, as described in Step 4, to be able to boot the system. The performance of the system was good and I was able to play videos after installing the VMWare Tools. Compared to Virtualbox, I was also able to get a better 3D performance but I wouldn't expect it to be enough to play 3D games.

# 7. Conclusion

I rarely used Windows 7 since I wrote the original german version of this tutorial a year ago, but it was still handy sometimes when I had to work with Windows programs, for example Visual Studio which I had to use for some university project. I mostly boot the system in a VM, but it also happened that I had to use some hardware which did not work well on Linux and I was happy that I could simply boot the same system outside of a VM. Although my real hardware setup (two Nvidia GTX 260 with 2 screens attached) is quite different from the one inside of a normal VM, I never had any problems and the hardware was always correctly detected. Moreover Windows allows you to define hardware profiles which can be selected during the boot sequence so that you can manually define which drivers should be loaded. This approach might be useful if the automatic detection does not work as expected.

I hope you enjoyed the tutorial and feel free to write a comment with your experiences or if you encounter any problems. If you are using a different VM software and got it to work, write me a message so that I can add the necessary commands.

07 Feb 2014 21:22 CET

Hello James,

sorry for the late answer, but the last week was very busy for me.

You are right, there are two commands you need to execute on every boot:

sudo losetup /dev/loop0 boot.mbr
sudo mdadm --build /dev/md0 --level=linear --raid-devices=3 /dev/loop0 /dev/sda1 /dev/sda2


One way to do this is to create an init script which executes the command after the filesystem is mounted. You can find an example for CentOS in the comments to the german version of the article (linked at the top).

Michael

29 Jan 2014 18:28 CET

I have gotten this to work with Windows 8.1 Virtualbox VM in OpenSUSE 13.1. The windows 8 tiles are pretty laggy, but it works none the less.

I resolved my previous issue with partition size not lining up by messing around with the partitions in gparted. I sort of stumbled upon that solution since I found that I allocated far too little memory for Linux and needed to readjust things before continuing. Thanks Sebastian for supplying a possible solution. I'm nosing around the irc channel now. I just thought that I'd report my progress here for posterity.

My main issue at this point is that the md0 drive does not stay persistent after reboot of Linux. I have to go through the entire process again at each boot. I'm probably missing a setting somewhere to make it persist.

23 Jan 2014 22:36 CET

Hi Nickolay,

I didn't test this with Windows 8, but I assume that the most parts should work the same way as for Windows 7. Anyway, you will need to pay attention to the fact that you can not simply mount a Windows 8 partition in Linux after shutting down Windows. Windows 8 does no longer do a complete shutdown, but goes to hibernation mode by default and the filesystem is therefore not completely unmounted. You will need to do a complete shutdown with for example shutdown.exe /s /t 0 before you can mount the Windows system partition in Linux.

Anyway, it seems like you just need to create a boot.mbr file with 63 blocks + partition table and then merge it with sda1 into a NRAID device. I don't know if you can still recover the mbr the same way as on Windows 7, otherwise you can still try to install a very simple boot manager with the install-mbr command (You will need to lookup which package contains this command, on Ubuntu it's just "mbr"). This boot manager will simply try to load the bootloader from the first partition it can find (don't forget to mark it as bootable). I haven't tested it myself, but it should work.

Michael

23 Jan 2014 21:55 CET

Hello,

Would it be possible a similar method to be used for virtualizing Windows 8.1 under Linux?

When You are executing fdisk -l, You are getting a similar output for Windows 7:

/dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
/dev/sda2          206848   204802047   102297600    7  HPFS/NTFS/exFAT


In Windows 8.1, the first partition (System Reserved) isn't created anymore (at least in my installation). The output of fdisk -l on the machine I'm using is:

nickolay@nickolay-pc:~\$ sudo fdisk -l
Disk /dev/sda: 160.0 GB, 160041885696 bytes
255 heads, 63 sectors/track, 19457 cylinders, total 312581808 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1a7c55d9

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *          63   122880239    61440088+   7  HPFS/NTFS/exFAT
/dev/sda2       122882046   185796607    31457281    5  Extended
/dev/sda3       185796608   312580095    63391744    7  HPFS/NTFS/exFAT
/dev/sda5       122882048   183144447    30131200   83  Linux
/dev/sda6       183146496   185796607     1325056   82  Linux swap / Solaris


I guess in this case only /dev/sda1 would be needed for virtualization, as it contains the Windows installation.

Thank You!

Best regards,
Nickolay

23 Jan 2014 19:28 CET

Hi,

@Philipp:
You can use Grub or LILO but at least Grub will need an additional small partition where it can store it's files and configuration. So you will need to create an additional partiton (for example with ext2) and mount it. Now you can install grub with:

sudo grub-install --root-directory=/mnt /dev/md0


If you don't care about having a CD inserted in your VM, you can also try to use the tiny Super Grub2 Disk which will automatically detect the installed operating systems during the boot, so that you do not need to install a boot loader.
Anyway, the partition offset of the Windows partition must be still correct otherwise the Windows kernel won't find it.

@Burgess:
If the other partitions are only data partitions, you do not necessarily need to have matching offsets between the real and the fake partition table. It is just necessary that the system partition is correct as Windows won't be able to boot otherwise. So you can put them directly after the real windows partition in the md0 device. Just create new fake partition entries with the same size as the original partitions and it is not important whether these are logical or extended entries. The only disadvantage of "moving" data partitions is that Windows might assign different drive letters as on the real boot, but they are user configurable.

@Ian:
The partition table you create with fdisk is only written into the small boot.mbr file and the table on your hard disk is not touched.
I am not sure what you mean with by changing the order of the partitions as the order depends on how you installed Windows and Linux. The order or to be precise the offsets between your real partition table and the fake one must be the same, otherwise Windows will not recognize it's system partition.

Michael

Writing comments is currently disabled, as we're updating the content management system.