It’s been some time since I installed Linux to dual-boot with Windows, but I’ve done it a few times before, so I figured installing Ubuntu to boot side-by-side with Windows 10 should be a piece of cake, right? Normally, it would have been simple, until I realized I had to catch up with all the changes from BIOS to UEFI, Secure Boot, and more.

A few detours later, I have it working, but not until I jumpted through a few hoops. Read on for how this can be accomplished, and what pitfalls may await you!

Starting off with a computer with a pre-installed Windows 10, the easiest thing to do is to create a bootable USB with your Linux distribution of choice, reboot with the USB in the computer, install Linux (which will also create a dual-booting config with a boot loader), and you’re all set!

“How hard can this be?” — famous last words.

Hint: if you want to skip the trials and tribulations and skip straight to the optimal solution, head straight over to the solution.

Creating a bootable USB with Linux

Since I’ve decided to install Ubuntu, I needed to find a suitable USB media. The only spare USB drive I had lying around at the time turned out to be an ancient 128MB (not a typo!) drive, but I knew that Ubuntu has “mini ISO” images, suitable for bootstrapping the system and installing the rest of it over the Internet, so let’s give that a go!

We can easily find Ubuntu’s “minimal CD” page which shows us that there are 64-bit images for several version of Ubuntu, and the latest (at the time of this writing) happens to be Ubuntu 18.04 “Bionic Beaver”. Although the size of these minimal images has been growing from 37MB (Ubuntu 14.04) to 54MB (Ubuntu 16.04) and now 64MB (Ubuntu 18.04), even the latest and greatest will comfortably fit on a 128MB USB key that I have, so let’s get started.

Writing an ISO image to a USB key is pretty straight-forward, so we won’t cover that here. The Ubuntu page on this topic has a number of viable solution alternatives whether by using Rufus on Windows (with a step-by-step tutorial), or creating a bootable Ubuntu USB from an existing Ubuntu installation (whether native or in a virtual machine) using Ubuntu’s Startup Disk Creator tool, which can be easily installed via:

$ sudo apt install usb-creator

Booting into Linux via USB

However, rebooting the machine we realize that the computer simply ignores the USB key and boots straight into Windows! Why is that?

Researching this further, I’ve learned that recent PCs ship with UEFI, a newer, more capable version of BIOS, and with a new feature called Secure boot, it can prevent unknown or unauthorized OSes from booting on that computer, which is of course what my rogue USB stick was.

With Windows 10, to reboot into USB, you have to select an option from the Control Panel in Windows to reboot into USB. However, even then, the USB stick wasn’t being recognized.

Some searching led me to disable “Secure Boot” and then switch to the older-style “UEFI with CSM” mode, which is essentially BIOS. This allowed me to boot with USB, I was able to partition the disk to give Linux some space, and installed Ubuntu side-by-side with Windows.

My advice: do not do this! I ended up reverting these changes.

Rebooting into Windows & Linux

After rebooting, I realized that I could now boot into Linux from the Grub boot menu, but not Windows. It would simply fail to boot. I modified the settings to revert to UEFI + Secure Boot, which enabled me to now boot into Windows, but not Linux anymore!

This put me in a strange predicament: to change the OS that the computer would boot into, I had to modify the BIOS/UEFI settings every time! Clearly, there had to be a better way.

To UEFI or not to UEFI?

After additional research, I realized that disabling UEFI (both the “Secure Boot” and switching to UEFI with CSM" mode) were both bad ideas, and needed to be reverted. However, it wasn’t clear how to then upgrade my “BIOS”-only installation of Ubuntu to UEFI-compatible mode, and how to enable “Secure Boot” on that partition.

However, to do this, I would need a UEFI-compatible bootable USB stick! The caveat here is that the Ubuntu Mini-ISO image I was using clearly specify that they do not support UEFI boot! However, the full Ubuntu USB images (which require a few GB of space), do support UEFI. What to do?

I first tried “upgrading” the mini ISO image to include the bits that would enable it to become UEFI-bootable, but after a lot of trial and error, I was unable to make it recognizable with computer set in UEFI-only (non-CSM) mode.

My advice: don’t waste your time trying to make Ubuntu mini-ISO images compatible with UEFI; either wait for Canonical to make their Ubuntu mini-ISO images compatible with UEFI (there are long-standing bugs on this), or just use the full-size USB images.

Note that the Ubuntu mini ISO page page says:

While the minimal iso image is handy, it isn’t useful for installing on UEFI-based systems that you want to run in UEFI mode. The mini iso lacks the proper files for booting the computer in UEFI mode. Thus, the computer will boot in BIOS compatibility mode, and the installation will be in BIOS mode.

You can use an Ubuntu Server amd64 iso file (64-bit) for ‘mini installations’ in UEFI mode. There is a compressed image file dd_text_16.04-UEFI-n-BIOS-4-pendrive-7.8GB.img.xz of such an installed system, that can be used as a start of a custom installation.

which strongly suggests that we shouldn’t even be bothering to try going the BIOS route without UEFI support. There’s a ticket on this open since 2015 that hasn’t been resolved yet, although a workaround suggests:

This issue can be fixed by copying the whole ‘EFI’ folder of http://cdimage.ubuntu.com/daily-live/current/wily-desktop-amd64.iso into the USB storage made by http://archive.ubuntu.com/ubuntu/dists/wily/main/installer-amd64/current/images/netboot/mini.iso.

but I haven’t tried it out myself, so I can’t vouch for whether or not it would work.

Solution

Before proceeding, I re-enabled UEFI boot (without CSM), and re-enabled “Secure Boot”, because it turns out hard to upgrade an installation installed under the UEFI-with-CSM (aka BIOS) mode to full UEFI mode, and we need it to support “Secure Boot” so that it’s compatible with the originally-existing Windows installation with which it will run side-by-side.

Then, I bought a new USB stick (turns out, you can get a 16GB USB stick these days for just a few dollars!) and loaded the full Ubuntu 19.04 image on it using Rufus, rebooted using it, and reinstalled Ubuntu.

As a result, I now have Grub with an easy dual-boot into either Linux or Windows!