[GUIDE] Multibooting Windows after macOS, and Linux have already been installed

Jul 18, 2019
Asus prime Z370-A MK-ii
RX 580
  1. MacBook Pro
  2. Mac mini
Multibooting: Installing Windows on your already setup hack

So, you just got your new hack up, and running eh? Of course, you have macOS working, and may've also installed your linux distribution of choice, but what about Windows? For many, having Windows around is a very important part of their setup, as there are just some things which can only be done in Windows. You may've tried installing Windows 10 already, but there's a good chance you ran into a problem. This shouldn't be happening; after all, you made sure to add multiple SSDs to your build for the explicit purpose of having a smooth multibooting experience.

What's going on?
There has been a long standing annoyance with the Windows installer that only allows it to proceed if it can write its bootloader to what it sees as drive 0. Of course, if it can't, the install will promptly fail. Conventional wisdom tells us to disconnect every drive from our PCs except for the one which Windows will be installed. This may've been relatively easy to do back in the days of all SATA drives, but faster NVME drives have become much more common. A lot of modern motherboards have two M.2 slots ready to go, and you can easily add another via a PCIE card, bringing the total up to 3. Let's suppose you have 3 NVME SSDs, and a SATA HDD. If the Windows 10 installer sees the NVME SSD you wish to use as drive 3, you'd have to not only disconnect the SATA drive, but also the 2 other NVME drives. Sometimes removing these drives is a little bit more involved than someone would like for it to be, as you may need to remove the GPU, other PCIE cards, and in some extreme cases, the CPU heatsink.

That's where this guide comes in; at no point, will you need to disconnect any drives, but be warned, this method can take a bit longer than a normal windows install, and you should feel comfortable using a command line (you'll see why in a moment). To quickly summarize, this method works by creating a basic virtual machine, installing windows onto a virtual drive, and finally using dd to create an image of that virtual drive that can be written back to a physical drive.

Section I: setting up the virtual machine
We'll start with a virtual machine, as we can easily restrict the number of virtual hard drives very easily. This guide will use Parallels Desktop, as it is one of the better virtualization applications on macOS. You can download parallels from the following link. Once downloaded, run through the installer package as you would any other similar application. Once you have parallels installed, you'll likely be presented with the "create new VM" dialog; here you'll need to do the following.
  • click "Install Windows or another OS from a DVD or image file"
    • Screen Shot 2020-05-19 at 2.59.01 AM.png
  • If you already have a Windows 10 installation image, the automatic detection tool should be able to find it, if not, you'll have to slect it manually.
    • Screen Shot 2020-05-19 at 2.59.32 AM.png
  • Next, we'll have to define a VM preset to be used for our new Windows machine. I recommend going with the software testing option, as this'll isolate Windows from macOS.
    • Screen Shot 2020-05-19 at 2.59.54 AM.png
  • Lastly, we need to give our VM a name, but more importantly, you want to customize the VM's settings before proceeding with installation.
    • Screen Shot 2020-05-19 at 3.00.24 AM.png
At this point, our VM has technically been created; however, it is essential that you make some adjustments to the VM, as it'll help create a better generic Windows installation. The unattended installation that parallels will attempt to go through will automatically install the parallels tools (which we don't want).
Screen Shot 2020-05-19 at 3.09.59 AM.png
The default hard drive capacity is way too over the top, and as such, you want to remove it. You can add a second hard drive by clicking the + icon at the bottom of the window. Select Hard disk, and go with a small capacity (40 GB will do). You'll also see two CD/DVD entries; one of them will be the unattended install iso. Remove it, as this'll only cause problems. The other specs are entirely up to you to specify. Once all of that is good, startup the VM, and go through the Windows 10 installation, until you get to the initial setup.
Screen Shot 2020-05-19 at 3.19.33 AM.png
Once you reach initial setup, head up to actions, and shutdown the Windows virtual machine. At this point, we're done setting up our reference drive. I recommend making a backup in case something goes wrong.
Section II: Imaging the virtual hard drive
Now we will need to create a functional linux installation. This can be done by either
  • Adding another virtual hard drive to your existing Windows VM
  • Creating a new VM for Linux
I strongly recommend the second option, as it is much cleaner, and in my experience, seems to work better. The linux distribution you choose is entirely up to you; however, I strongly recommend something that follows a long term support cycle, as the parallels tools for linux tend to lag behind kernel development, and as such, the tools may not work on the latest kernel. I went with Debian testing, as I already had this VM setup, and ready to go, but if you're just getting started, I'd go with something like Ubuntu 20.04, or Debian 10. Similar to the previous VM setup, we need to add a virtual hard drive, but this time, we will tell parallels to use an existing disk rather than creating a new one. Once you have your Windows VM hard drive attached, make sure that it is completely deselected in the "Boot Order" tab, as we do not want our Linux VM to try to boot from this drive.

At this point, it's simply a matter of running through the installation process for your distribution of choice (I'm going to assume you know how to do this). Once finished, install the parallels tools for Linux, as they'll be needed for accessing a location outside the VM that can be used to store our drive image. Once everything is setup, you need to determine the drive assignment for your Windows virtual hard drive. There are many ways to do this, but for the sake of simplicity, I went with gnome disks, as this'll also give us a graphical representation of the drive's partitions.
Screen Shot 2020-05-19 at 3.27.39 AM.png
From the above screenshot, we can see that my Windows virtual drive was given the assignment of sdb; remember that, as it'll be vital in the next step. We will be using the dd command to create an img file from our virtual hard disk. Using the above example, the command will look like the following.
$ sudo dd if=/dev/sdb of=/media/psf/Home/win10.img bs=4096 conv=sync,noerror
This command will make a full copy of the drive sdb, and write the image file to your Mac's home directory. Depending on how good your hardware is, this may take a little while; so, feel free to grab a snack at this point. This exact command is only there as a reference, and you should use a destination path that is appropriate for your setup. If permitted, parallels will even share external drives with your VM; so, if you don't want to write a 40GB drive image to your main SSD, you have other options.

We can now shutdown the virtual machine, and head back on over to the macOS side of things. From here we will be able to write the image we just made directly to the internal SSD in question. To ensure we target the correct disk, open terminal and use diskutil to get a list of all drives seen by macOS.
$ diskutil list
Here is the sample output from my system; of course, yours will likely look different.
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.1 GB   disk0
   1:                        EFI NO NAME                 536.9 MB   disk0s1
   2:           Linux Filesystem                         465.3 GB   disk0s2
   3:                 Linux Swap                         34.3 GB    disk0s3

/dev/disk1 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.1 GB   disk1
   1:                        EFI EFI                     209.7 MB   disk1s1
   2:                 Apple_APFS Container disk3         499.9 GB   disk1s2

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *512.1 GB   disk2
   1:           Windows Recovery                         554.7 MB   disk2s1
   2:                        EFI NO NAME                 104.9 MB   disk2s2
   3:         Microsoft Reserved                         16.8 MB    disk2s3
   4:       Microsoft Basic Data                         511.4 GB   disk2s4

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +499.9 GB   disk3
                                 Physical Store disk1s2
   1:                APFS Volume Macintosh HD - Data     182.2 GB   disk3s1
   2:                APFS Volume Preboot                 82.3 MB    disk3s2
   3:                APFS Volume Recovery                528.1 MB   disk3s3
   4:                APFS Volume VM                      1.1 GB     disk3s4
   5:                APFS Volume Macintosh HD            11.4 GB    disk3s5

/dev/disk4 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *4.0 TB     disk4
   1:                        EFI EFI                     209.7 MB   disk4s1
   2:                 Apple_APFS Container disk5         4.0 TB     disk4s2

/dev/disk5 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +4.0 TB     disk5
                                 Physical Store disk4s2
   1:                APFS Volume Files HD                626.9 GB   disk5s1
Read this list CAREFULLY! The dd command is very blunt; it will (for better or for worse) do exactly what you tell it to do. Entering the wrong drive can result in data loss; so, please do not rush through this. From the above output, the device I'm using is /dev/disk2 and therefor, the final dd command to image the disk would look like the following.
$ sudo dd if=/Users/username/win10.img of=/dev/disk2 bs=4096 conv=sync,noerror
Like when we previously made the image, this too can take awhile; so, get up, take a break, and it should be done by the time you get back. Of course, do not forget to replace "username" with your macOS account name. If you opted to save the previously made disk image to another directory, please be sure to use that location instead of the generic one found in the example command.

Section III: Finishing up
And that's it? Assuming all went well, you should now have a bootable windows environment. When you boot for the first time from the newly imaged drive, you may see an error that explains why your PC was shutdown; you can ignore this. Once you setup your user account, I highly recommend going into computer management > disk management, and extending the size of the c:\ drive. The default block size used by NTFS is 4096 bytes, which is why I used that value in the dd command.

Overcomplicated? Sure, but it is a way to deal with the drive 0 problem nonetheless. Hopefully this bug will be fixed in newer versions of Windows 10, as to avoid needing to do something like this. If you're using OpenCore, please do not forget to clear NVRAM before you boot into Windows. Unlike Clover, OC will apply all patches to every OS, and therefor, you do not want to boot windows with it. Clearing NVRAM can address some issues that may linger from your previous macOS session, and on some motherboards, failing to clear it will result in a black screen when trying to enter UEFI, or even the boot menu.

Anyway, I hope this post was helpful, and feedback is greatly appreciated, as I hope to improve this thread over time. If you have any questions, feel free to drop a reply, or send me a message directly, and I'll do my best to answer said questions.