I am a long time Linux user (Mint being my preferred distro) and have dual booted Windows and Linux on every computer I have owned in the last decade. Recently, I have been using Linux Mint 19.3 as my primary operating system, booting into it more often than Windows 10. I do still use Windows regularly; it is my preferred operating system for playing games and for .NET development with Visual Studio. Switching between each operating system required a reboot of my machine, and I contemplated creating a new virtual machine instance for Windows 10 (using Oracle’s VirtualBox) so I could target Linux and Windows at the same time. However, this would require going through the Windows installation process from scratch, configuring everything to my liking, installing all the software and development tools I require, etc. This approach would be an acceptable solution, but I would then have two separate Windows machines, one virtual and one physical. I didn’t want to maintain two separate Windows environments for daily use. I also didn’t necessarily want to make the switch to use Windows in a VM 100% of the time, I still wanted to be able to boot into Windows. So I pondered the question “can I create a virtual machine from the existing Windows 10 installation on my hard drive?” After some quick Googling, I was surprised to learn that the answer is “yes!” I found this post from Jamie Scaife’s blog and this question on superuser.com to be particularly helpful. Such a solution is ideal for me – I can boot into Linux Mint for my regular daily use and run the Windows 10 VM from there to do .NET development and other Windows-specific tasks. I can also boot directly into Windows if I choose. The concept is pretty straight forward – A Virtual Machine Disk file (VMDK) points to the physical partition, and that file is used to create a virtual machine. Here’s how I set it up:
The first step is to identify the disk which contains my Windows installation. As I mentioned above I’m using Linux Mint 19.3, so this can be accomplished with the
lsblk command or the “Disks” GUI application included with Mint:
As you can see, I have multiple disks each with multiple partitions. I know that my Windows partition is formatted as NTFS and is about 300 GB in size, so I was able to determine that device /dev/sda2 is my Windows installation. Note that the device name may differ on your machine. In my Windows installation, I also have a secondary disk with a NTFS partition for storage (I call it my “XtraDisk”) mapped to the “X:\” drive (clever name & drive letter, I know). That partition is device /dev/sdb1.
The next step was to grant my username full read and write permission to the disk. This is done by first creating a new group account called “win10disk”:
sudo groupadd win10disk
Then I added my username to the group with command “usermod.” The “-a” option appends the user (matt) to the group, the “-G” option specifies the group (win10disk).
sudo usermod -a -G win10disk matt
Next, I determined the UUID of my Windows disk and my XtraDisk using command “udevadm” and searching for “UUID”:
sudo udevadm info /dev/sda2 | grep UUID
sudo udevadm info /dev/sdb1 | grep UUID
The output I’m interested in when running each command looks something like this, where “E:” indicates a device environment variable with the name “ID_PART_TABLE_UUID” and its value after the equals sign:
I then created two files called “win10disk.rules” and “win10xtradisk.rules” in the udev rules directory:
sudo touch /etc/udev/rules.d/win10disk.rules
sudo touch /etc/udev/rules.d/win10xtradisk.rules
I edited the contents of each file to contain the following:
In each file, the “ID_PART_TABLE_UUID” environment variable is checked (== operator), and “GROUP” is assigned the “win10disk” group I created. I then saved the rules files, and rebooted my machine back into Linux Mint. Before I created the virtual machine, I needed to create two Virtual Machine Disk (VMDK) files that represent the Windows installation disk and my storage “XtraDisk” disk. These files are essentially pointers to the physical disks themselves. To create a VirtualBox raw disk image, use the
VBoxManage command, specifying location in the
-filename argument and the device name for the
-rawdisk argument. Note again the different device names for each, “/dev/sda” and “/dev/sdb” – these may be different on your computer:
VBoxManage internalcommands createrawvmdk -filename /home/matt/VirtualBox VMs/disks/Win10/Win10VirtualDisk.vmdk -rawdisk /dev/sda
VBoxManage internalcommands createrawvmdk -filename /home/matt/VirtualBox VMs/disks/Win10/Win10VirtualXtraDisk.vmdk -rawdisk /dev/sdb -partitions 1
The first disk I created, Win10VirtualDisk.vmdk will use the entire disk on
/dev/sda. This second disk I created, Win10VirtualXtraDisk.vmdk, uses only one partition as specified by the
-partitions argument. I then opened VirtualBox and clicked “New” to create a new virtual machine. I will be using my Windows VM for .NET development with Visual Studio 2019 which can be quite a resource hog, so I allocated 16 GB of RAM to this VM. Remember that the host machine still needs sufficient hardware resources to run the VM, so set this option accordingly. Under the “Hard Disk” option, I set option “Use an existing virtual disk file” and selected the “Win10VirtualDisk.vmdk” I just created:
I then clicked “Create” and the virtual machine was ready to go. Before booting, I want to make sure my “XtraDisk” is available so it can be mapped to the “X:\” drive on boot. I opened the machine’s settings, selected the “Storage” menu option, and under “Storage Devices” I clicked the “Add hard disk” (green plus) button next to the SATA Controller. I clicked “Choose existing disk” and selected file “Win10VirtualXtraDisk.vmdk” I created earlier.
While in the settings, I allocated 4 CPU cores to this VM, set the video memory to the maximum 128 MB, and changed the network adapter to bridged. The virtual machine is now ready to boot! When I start the machine, I’m presented with the GRUB boot menu and must select the Windows 10 operating system.
There are a couple important things I want to highlight first before booting the virtual machine. The first is that you should not boot the VM into the same operating system and partition which is currently running the host (Linux Mint 19.3 Cinnamon in my example). I’m not 100% sure what are the implications of doing so are, but I imagine there is a high potential for disk corruption and/or loss of data. Best case scenario is that
fsck could be used to repair the file system, worst case scenario would be a complete loss of data, requiring a reformat of the entire disk and re-installation of both operating systems. To avoid accidentally booting into Linux on this VM, I set the default GRUB menu selection to Windows. This is especially helpful, as Windows sometimes like to restart on its own after an update, and if you are not paying attention you want the VM to boot back into Windows.
Secondly, I want to point out that you should unmount any disks that are also in use by the Windows VM to avoid data corruption. I set the “XtraDisk” partition to automatically mount on Linux Mint startup, so before booting the Windows VM, I unmount this.
Once the Windows VM was booted up, I verified that my “X:\” drive was mapped and I was able to access files on that disk. I also have a network share mapped to the “H:\” drive and verified that was working and files were accessible.
That’s pretty much it! I now have a seamless transition between Linux and Windows without the need to reboot my machine, but still also have the option to boot directly into the same Windows instance on system startup. One additional thing to note is that depending on the version of Windows you are running, the change in hardware may prompt you to re-activate Windows with your license key.
edit: June 18, 2020
Adding a quick addendum to this post regarding Windows activation: I discovered that I am able to edit the UUID of my VM and set it to the same value as the UUID originally used by my Windows installation. While booted into Windows normally, I ran this command to obtain the UUID:
wmic csproduct get UUID
I then edited the
uuid property under the
<Machine> element of the .vbox file which contains my Windows virtual machine, setting its value to the same UUID I obtained above:
This should eliminate any issues Windows may have with prompting for re-activation when switching between booting the VM and booting normally.