Overview
As an updated answer to this question for 2022, such a process is much more common than previously and while Thomas' answer may have been true to an extent once upon a time, in general* it's actually not as difficult as the previous answer might've made it seem.
To clarify, prior to Windows 8 & 10, Windows would've actually been the more difficult scenario moving from VM to Physical or vice versa simply because of not just the activation protection for genuine copies of Windows, but also Windows' Hardware Abstraction Layer (HAL) and the dependence of drivers along with the kernel on the actual hardware, as explained here. With Windows 10, Microsoft has made it so that Windows does a better job of adapting to sudden hardware changes
However, in the OP's case, it's a host Windows machine running a virtual version of Ubuntu using VirtualBox. While the process is somewhat tedious for some, it's not something I'd describe as extremely difficult IF you were talking about just converting a virtual machine and dropping it into a bare physical machine (no other existing operating system or need to retain another OS).
* What is difficult is if you are looking to have it become a part of dual-boot setup and you only have one hard drive. Then you'll have a VM that was created with multiple virtual partitions and are trying to put those multiple partitions into a single physical partition and would need to specify partition offsets and causes by consequence the added work of having to setup Grub and your bootloader all separately to play friendly with Windows, using a rescue process of some sort. It's in this case, that I would agree with the previous answer of simply doing a fresh install on the desired other partition so that the installer can take can take care of configuring your boot options as part of the installation process.
However, if you or whomever comes across this, and ideally have another hard drive to install the VM to, the process is described below.
Converting Virtual System (Linux-based) created in a Windows environment (Host OS)
To go about this, the process involves converting the virtual machine first into a a disk image using VBoxManage and then booting into a live boot USB of a linux system to write that image to your hard drive. This is process is slightly different when it comes to sharing a hard drive with Windows and having it be applied to a different partition. For those using a new hard though, a direct write to the disk from the image file will be sufficient and is included in the steps below prior to the steps given for the request made by the OP.
More on VirtualBox cloning found here.
Creating the VM image file
Open an elevated command prompt (Run as Administrator) and navigate to the installed directory for VirtualBox (or alternatively, you can add the install directory to your PATH so that you can run VBoxManage from the location of the VM file)
For below, we'll assume VirtualBox is installed at the default path of
C:\Program Files\Oracle\VirtualBox
and our example VM is located in another folder which we will reference as C:\MyVMs\example.vdi
and we will be writing the image to an external USB drive (D:) at D:\VMFolder\
naming it VMimage.img
# Adding VirtualBox's installed directory to our working environment
# This only changes the PATH temporarily within our command prompt window
C:\WINDOWS\system32> set PATH=%PATH%;C:\Program Files\Oracle\VirtualBox
# no output will indicate success but if you want to check if it's working
# you can either use echo:
C:\WINDOWS\system32> echo %PATH%
# or simply try to run VBoxManage:
C:\WINDOWS\system32> vboxmanage list hdds
# which outputs a list of all your installed VMs
Using the same elevated command prompt:
# Navigate to the location of our VM
C:\WINDOWS\system32> cd C:\MyVms
# You should now see the command prompt as:
C:\MyVMs>
# Run the command to convert our VM to a raw image file
C:\MyVMs> VBoxManage internalcommands converttoraw example.vdi D:\VMFolder\VMimage.img
# After hitting enter, it should show an output similar to this:
Converting image example.vdi with size 512110190592 bytes (488387MB) to raw...
# Prepare yourself, this may take awhile
Depending on how large your VM is, how fast your hard drive's read/write speed is, and the speed of the USB Drive (D: in our case), this might take quite a bit of time. For me, running this took about 30-40 minutes and you'll know it's complete when you see the Command line prompt available again.
Applying the .img to a physical hard disk (General)
For those who are taking the path of less resistance and would like to apply the image to a new hard disk, or in a new system with no current OS needing to be run alongside, the image can be applied by booting up a live boot USB of their preferred Linux distro (selecting the option to try a live demo test system or equivalent), opening a terminal window, and run the following (making sure the destination for the image is not mounted in the live boot system):
For the below examples, the formerly referenced USB drive on Windows (D:) will now be referenced on the Linux system as /media/user/usb
whereas the USB live boot resides on /dev/sda
(and appears as the primary system drive) and makes the local hard drive (again, unmounted) appear on something like /dev/sdb
You can double check your layout by running blkid
or fdisk -l
then:
dd if=/media/user/usb/VMFolder/VMimage.img of=/dev/sdb conv=sync,noerror status=progress bs=64K
The options can be omitted if desired, but to explain:
conv=sync,noerror
tells dd
that if it can't read a block due to a read error, then it should at least write something to its output of the correct length
status=progress
outputs some information as dd
is doing it's thing to help you understand how far long in the process it is
bs=64K
is the block size of 64x1024 Bytes. Some may suggest using bigger block sized to increase the speed of the copying/write process but to each their own.
At this point, some additional steps can be taken while in the live boot session environment to ensure booting goes smoothly but is beyond the scope of this answer as it diverts from the OP's question. But, for the most part it should be able to boot without much, if any, trouble. If not, try this article or this one for troubleshooting boot issues.
In case one is uncertain of how to create a live boot USB system, one example tutorial for Ubuntu can be found here.
Applying the .img to a physical hard disk (Specific to OP)
As aforementioned, the difficulty of this process is more prevalent when trying to install the converted VM to a partition on the same hard drive as your current Windows system. Since the OP mentioned having never created a system image before then it would be advisable, once again, to follow the advice of the previously submitted answer as it requires a much more advanced application and use of various commands, not to mention troubleshooting steps that could easily be avoided.
Side note: After going through the steps and seeing just how much troubleshooting it would incur, I've revised the instructions a bit as it became blindingly obvious that if nothing else, you should at least use the installer to install a new version of Ubuntu alongside Windows following a guide like this one or one of your choice. And then, after the installation is successful and you can boot into both systems, assuming that you used the same installer for the VM as you would for the fresh install on the physical system, then proceed with the steps below.
Overview and Explaining the Difficulties
When the image of the VM is created, the image file itself is the entire system and includes a partition table as part of the image. Since, generally speaking, an install of Ubuntu would often result in creating 3 different partitions (4 if you opt to use a swap
partition) when installing for a system that utilizes UEFI, then it becomes apparent that we only need to extract the partition where the main bulk of the OS resides on if we want to run our pre-tested and used system.
In other words, you would only be interested in copying the root
("/") partition, sometimes referred to as the user
partition, to the available partition on your hard drive but then you'd be missing the boot
and EFI
partitions (if applicable for the latter) which would then need to be adapted to reside with wherever your windows bootloader is located, just to boot properly. This in turn creates a need for you to also set up Windows to ignore the partition Ubuntu is on in Disk Manager in case it might detect it as a hard drive corruption and attempt to run chdisk
upon the next boot.
Thus to avoid all those issues mentioned above, and as aforementioned, using the same installer as you used for your VM to install a fresh version of Ubuntu first will help avoid those issues as you can simply copy the VM system's primary (or root partition) to overwrite the same partition that the fresh install would have made to more simply take its place, rather than have to troubleshoot all the issues that would inevitably arise. Then, a quick update to some of the boot configurations and you'll be set to go.
Determine the partition sizes and sectors
You'll need to gather some information in order to only write the main partition of the VM image to your physical partition. After installing the fresh version of Ubuntu, determine which partition on the physical drive your root directory for Ubuntu lies. Then for the image file, we will need to get the offset of the root partition for the original VM system.
Using the same references as above, from a terminal window in a live boot USB session run:
fdisk -l /media/user/usb/VMFolder/VMimage.img
The output of fdisk
will provide information that consists of a summary about the disk image and then list each of its partitions with a column for Device, Start, End, Sectors, Size and Type. Since partitions are not guaranteed to be laid out on disk in their numeric order without padding, it may be better to mount the root
partition of the image disk file to a loopback device first before copying it to your physical disk partition.
To do this, after gathering the information from the command above, you'll need to determine the correct offset for the root partition (usually the largest one on the drive) of the VM's system image. The offset you need is the start of a partition multiplied by the sector size.
For example if the start is 128 and sector size is 512 then the offset is 65536. To be sure, the sector size is found near the top in the summary part of the output for fdisk
while the start is in one of the columns for the listed partitions. Also, to ensure you use the right offset, the start might be a much larger number as it will be farther along in the disk image, and for example may be something like 1001472 for the start, and so with a sector size of 512, the offset that's more likely going to be used might look more like 512753664 in that case.
# There are two ways to accomplish the mount of the partition
# to a loop device. Choose one of them, I suggest the 2nd one
### Option 1
# make a temporary mount point in the live boot system
sudo mkdir /mnt/tmpboot
# then mount with the offset calculated as explained above
sudo mount -o loop,offset=512753664 /media/user/usb/VMFolder/VMimage.img /mnt/tmpboot
### Option 2
# alternatively, you can use 'losetup to accomplish the same thing without
# the need to create a temporary mount point, which also helps avert
# the risk of the partition being read/active when copying.
# Replace '512753664' with the offset you calculated earlier
sudo losetup -o 512753664 /dev/loop0 /media/user/usb/VMFolder/VMimage.img
### After Option 1 or 2
# the root partition of the image file now resides on
# either /dev/loop0 or /mnt/tmpboot | Now to write
# the partition using either of the above
# you will need to replace 'sdb3' with the correct partition
# that the fresh installation had created
dd if=/dev/loop0 of=/dev/sdb3 conv=sync,noerror status=progress bs=64K
# In case it's not obvious for above, replace /dev/loop0 with /mnt/tmpboot
# if you chose the former, option 1
Since you'll be missing the boot
partition and EFI
partition when attempting to boot you might have to opt for making the partition an LVM in order to create multiple partitions within a partition which means the above commands won't work for you and would've required the VM to use LVM during setup as well.
Since it would be too late for that, you could try copying the contents of the boot
partition into the Window's System Reserved partition so that when you run
In case your VM is running with LVM, and you have trouble mounting the partition as directed, refer to the page for How to mount an LVM volume from a dd/raw/vmdk image?
Since a bootloader would've been installed by the fresh Ubuntu install, you will need to update some of the configurations of the newly copied partition's system files so that it can recognize the transplant that took place.
As a side note, there are alternative methods for going about all this, such as using qemu
which can be found here.
Finalizing for Boot
With the image's partition now written to the physical drive, you will need to mount the physical drive's partition containing the VM's root partition and make some modifications.
# if it doesn't already exist create a mount point
sudo mkdir /mnt
# then mount the newly written partition
sudo mount /dev/sdb3 /mnt
# to make modifications to that system as that system (and not
# as the live boot USB system, we will need to chroot our way in
# this simply translates into running the following commands
sudo mount -t proc proc /mnt/proc
sudo mount -t sysfs sys /mnt/sys
sudo mount -o bind /dev /mnt/dev
sudo mount -t devpts pts /mnt/dev/pts
sudo chroot /mnt
# now we are in the VM's system acting similarly to if it was
# booted up and running, changes we make here affect our
# physical system
For this part of fixing boot, we will need to:
- Update the Grub Bootloader
- Check & Update fstab with any changes to UUIDs
- Update the initramfs if applicable
The above can be simplified if you want to use a script like this one instead. Otherwise to quickly cover it manually:
# Update Grub by running below to override the booted UUID
sudo grub-install
# Run grub update to change the grub boot menu
sudo update-grub
# Alternatively, you could modify the configuration in /etc/default/grub
# by updating the following line
GRUB_DEVICE_UUID=***INSERT NEW UUID HERE***
# Then running the update-grub command from above
# -------
# To check fstab, we will need to note the UUIDs of all the partitions
# currently set for current boot partition and home partition
# just to be extra careful, get it by running
blkid
# Now check and update fstab if needed
# You can replace nano with a different text editor
# if preferred (such as vim or gedit)
sudo nano /etc/fstab
# Replace the UUID for home with the newly written partition's UUID
# and double check the UUID for boot matches the one reported by blkid
# Close and save by hitting Ctrl+X answering Yes to save changes
# hit Enter to confirm the filename and overwriting then run
sudo update-initramfs
A more in-depth look at updating Grub can be found here.
A more thorough explanation of fstab
can be found here.
That should be about it! Unless you run into trouble with some ACPI issues or Secure Boot Issues when trying to boot, but those would've been made apparent after the fresh install of Ubuntu on the physical system.
Some *Extra* Final Steps
Before restarting, though not required, you can exit chroot and unmount all the drives, starting with the sub paths. Otherwise, simply typing exit (twice, once to exit chroot and again to close the terminal window), and closing down the live boot session by shutting down and removing the USB will suffice. But to fair on the safe side, it's best to build a habit of unmounting those partitions we had mounted in case it might come bite us back in the future.
# To exit chroot
exit
# then unmount everything (sub paths first)
umount /mnt/proc
umount /mnt/sys
umount /mnt/dev/pts
umount /mnt/dev
umount /mnt
# and if desired, for laziness
sudo reboot
# otherwise exit the liveboot session through the shutdown menu
# so as to safely remove the USB live boot USB device
I can see now, why Thomas just answered more simply the former. I pray all this serves to help someone out there one day...