Dual Booting Ubuntu and Windows 10 on Mac Mini 2011

4 steps. Install Ubuntu. Make space for Windows. Install Windows. boot-repair. Easy, right? WRONG! The task of installing Windows next to a pre-existing Ubuntu installation on an old Mac Mini could be painfully long.

Introduction

I have a 2011 mac mini, with one internal HDD. Initially, I had the entire disk occupied by a Ubuntu 16.04 installation. I have MacOS ElCapitan installed on an external HDD. Later, I decided to add Windows 10 to the internal HDD. This is how I did it. It may not be the best way, but it’s how I did it. I’ve spend several days doing this, so I hate to forget how it was done. This post is meant to document the entire experience. I don’t want to go through the same thing again without knowing the details.

Requirements

  • Working internet connection.
  • Windows 10 disk image (installation iso file).
  • 8GB (or more) USB storage device (like a USB flash drive).
  • 2GB (or more) USB storage device (optional, since we can always use the one above, but we’ll need to create a live-cd more than once).
  • Ubuntu disk image (to make USB storage devices into live-cds).
  • MacOS pre-installed to an external HDD (optional iff you can figure out and download the correct boot camp support software package online. Trust me, it’s hard!).
  • Optional: a machine with Windows installed to create the Windows 10 USB installer (even a virtual machine with WinXP would work).

Legacy Boot vs EFI

I installed Ubuntu in legacy boot mode. I didn’t know much about EFI, so I didn’t pick this way, though things are different now. If I ever have to configure another machine, I think I’ll use EFI. You might want to do that too. Even though it might be a bit complicated, but EFI (or UEFI) is superior in every way. If so, stop reading immediately! In this tutorial, we are doing it the legacy way.

WIFI Drivers

We’ll need to boot off a Ubuntu live-cd several times. The Ubuntu live-cds normally don’t have the BCM4331 drivers installed by default. If you have access to internet through Ethernet, then you don’t have a problem. However, if you are using Wifi or the router is out of reach, it would be better to download these drivers onto your current Ubuntu partition beforehand:

  • Download the driver.
  • Unzip the archive, and create a small script file next to it install.sh with these commands:
    sudo mkdir /lib/firmware/b43
    sudo cp b43/*  /lib/firmware/b43
    sudo modprobe -rv b43 
    sudo modprobe -v b43
    
  • Run this file every time you need to use the driver off-line:
    sudo sh install.sh
    

Booting off an External USB Device

We’ll need to do it several times. Here’s the procedure:

  • Shut down the machine.
  • Attach the device to the machine using USB.
  • Turn on the machine while pressing and holding the option key (alt key in Windows keyboards) until the boot menu shows.
  • Select the device.

We won’t be using any EFI boots in this tutorial.

Preparing an Ubuntu USB Live-CD

Bootable devices made using Unetbootin don’t work out of the box on this particular Mac Mini (I don’t know about other Macs). To make it work, use GParted to format the USB storage device into FAT32 first. Then flag the partition as boot. Now you can use Unetbootin to create the live-cd. If while booting it, it shows the grub menu but stops booting with this fancy message:

(initramfs) mount: mounting /dev/loop0 on //filesystem.squashfs failed: Invalid argument
Can not mount /dev/loop0 (/cdrom/casper/filesystem.squashfs) on //filesystem.squashfs

then either your .iso file is corrupt, or this particular file was not created as a hybrid ISO file. To make it into a hybrid ISO file, use:

isohybrid ubuntu-14.04.5-desktop-amd64.iso

Just substitute the correct file name above (the file will be over-written). Now, use Unetbootin with this image file. The EFI boot seems gone, but the legacy boot should work fine.

You can also skip all the above and just dd the image onto your device directly without using Unetbootin at all:

dd if=<insert image file path> bs=4M | pv -W | dd of=/dev/<device name, usually sdb> bs=4M

DANGER: double check before just using /dev/sdb. Write the correct block device name.

This works just as fine as Unetbootin (and seems faster). Note: the hybrid iso thing still applies.

Partitions

The first thing to do is make space for the Windows installation:

  • Boot the machine from a USB device loaded with the Ubuntu live-cd.
  • Use GParted:
    • Shrink the Ubuntu partition to leave 1 GB of free disk space at the beginning of the HDD. This space should be before the partition. Also, leave enough space for your Windows partition (and in my case, an additional “Storage” partition) after the partition.
    • Create an EXT2 partition in the 1 GB free space.
    • Create the Windows and Storage partitions as NTFS.
    • Apply all the changes.
    • Flag the 1 GB partition as boot.

About the 1 GB partition:

  • It’s going to be the boot partition.
  • Why 1 GB? I don’t know! I think 256 MB would have been sufficient, but the official guide said 1 GB.
  • Why at the beginning? For some reason, it seems that the boot partition has to exist within the first 100 GBs of the device. However, note that resizing a partition to leave free disk space at its beginning will copy the entire partition, so it’s a lengthy process.
  • While installing Ubuntu in the first place, we could have created this partition from the installer, and set its mount point as /boot.
  • Why EXT2? Because there are reliable tools that allow you to mount and use EXT2 partitions in Windows. I have failed, no matter what I did, to make my USB keyboard work in the GRUB boot menu. Well, I could make it work, but then the machine wouldn’t boot! I just couldn’t figure it out, so I decided it would be easier to make a separate boot partition and manually alter the GRUB configuration file to choose which OS to boot the next time. Since I want to be able to do this from both Ubuntu and Windows, I opted for a FAT32 partition, but boot-repair refused to recognize it as an option for installing the boot system. So, EXT2 was my best bet.

About the other partitions:

  • I could have left the Windows partition as free space and installed Windows there directly, but then the Windows installer would have created two partitions, one for boot and the other for Windows. Since we don’t want this clutter, pre-formating the partition with NTFS prevents the installer from creating the extra partition.
  • For the storage partition, I wanted to have something that works nicely across all the operating systems I use. UDF looked like a very nice option. It works well on Windows (since Windows Vista?) and also on Linux and MacOS. But, to format a disk using UDF, you’ll have to abandon GParted. NO! I hate having to memorize a new set of commands just to do it. EXFat is the same. It should work nicely everywhere, but its support doesn’t come out of the box in Ubuntu, so another no. NTFS on the other hand, worked very well in all the three systems, except that you can’t write from MacOS without a hassle. I can live with that. If I ever need to change something from MacOS, I’ll copy it to the MacOS partition, modify it, reboot into Ubuntu and pull it back. NTFS also allows you to compress the partition to allow more to fit in. In my cramped HDD, this looked like a nice option. So, let it be NTFS.

Notes:

  • You can’t have more than 4 primary partitions. If you won’t create the storage partition, then you are good to go. Otherwise, we’ll have to delete the swap partition, create a new logical/extended partition then create both the storage and swap partitions there.
  • If you think the names of your partitions are out of order and confusing, you may want to rename (sort) them. To do this:
    • sudo gdisk
    • Enter /dev/sda (not necessarily sda, select your HDD).
    • Press s (sort partitions).
    • Press r (recovery and transformations).
    • Press g (convert GPT into MBR and exit).
    • Press w (write table to disk and exit).
    • Note: GPT doesn’t play well with extended partitions. If you have to use gdisk, use it before creating these partitions).

To continue, we might have to boot in the original Ubuntu installation to prepare the Windows USB installer (unless you have another machine). To do so, you can use boot-repair and perform the Recommended repair option. This should make your system bootable again.

Now, before jumping onto installing Windows, we need to get the necessary drivers.

Getting the Drivers

We can get all the necessary drivers and make a Windows USB installer from within MacOS using Boot Camp. To do so, follow this tutorial. Just stop after finishing step 5. We don’t need the rest of the steps. However, I didn’t use this method. Instead, I used the Windows USB/DVD download tool, but more about that later. Not, lets just get the drivers. If you are feeling luck (I wasn’t!) you may try figuring out the correct package out of these:

https://support.apple.com/downloads/macoscomponents

Now, lets actually get the correct package! It’s time to use the MacOS HDD:

  • Boot the machine from the MacOS external drive.
  • Open the System Preferences, then:
    • Select Startup disk.
    • Select the internal HDD. This will remove the 30 seconds grey-screen delay when booting up the Mac.
  • Open the Boot Camp utility:
    • Insert a FAT32 formatted USB Storage device (not necessarily empty) with about 2 GBs of free disk space (we need a little more than 1.3 GB, but just in case).
    • Check the Download the latest Windows support software from Apple option only. Uncheck everything else.
    • Wait patiently until it downloads the software from the internet and place it on your USB device.
  • You don’t actually need these files to be on a USB device at all. Just copy them where you can access them later in the process. Here are the downloaded files/folders:
    BootCamp (folder)
    $WinPEDriver$ (folder)
    AutoUnattend.xml (file)
    

Preparing the Windows Installer

To use a WinXP machine, install these:

After installing the later, use it to create the USB installer. More recent Windows versions don’t need all these steps. Just try running the tool and it will tell you what you should install.

I could have avoided this entire hassle and just used dd to make a raw copy of the image to the USB flash. I didn’t, and I don’t know if it works, but if it works then I recommend it.

It’s time to install Windows.

  • Boot the machine from the USB device and follow the instructions.
  • Remember to choose the custom installation option and to select the Windows partition that we’ve created before for the installation.
  • When done, boot into Windows and install the boot camp software we’ve downloaded earlier.

Congratulations! Now we have a running Windows installation, but we can’t boot into Linux!

Repairing Boot

  • Boot from a Ubuntu live-cd (you may have to make it again. Sorry!).
  • Make sure you have an internet connection (remember the wireless driver?).
  • Install boot-repair.

Now lets get serious:

  • Run boot-repair.
  • Choose Advanced options.
  • From the GRUB location tab, choose:
    • your Ubuntu partition as the OS to boot by default.
    • your boot partition as the separate /boot partition.
    • to place GRUB into your HDD.
  • From the GRUB options tab, make sure that the Purge kernels then reinstall the last kernel option is unchecked.
  • Press Apply.
  • Follow the instructions, and choose the boot partition when asked to.

Lets call this procedure 1. If it fails:

  • Repeat procedure 1 with only one difference. Uncheck using a separate /boot partition. It should work now.
  • boot-repair again! This time, perform a Recommended repair.
  • Finally, repeat procedure 1 without any changes. This time it should work.

Voila! The system can now dual boot into the two operating systems. If your keyboard works in the GRUB menu, you are a lucky one (Logitech keyboards are known to work). Otherwise, you’ll have to modify the GRUB configuration manually.

Manually Setting the Default Boot Option

From Ubuntu

  • Edit /boot/grub/grub.cfg.
  • After this block:
    if [ "${next_entry}" ] ; then
       set default="${next_entry}"
       set next_entry=
       save_env next_entry
       set boot_once=true
    else
       set default="0"
    fi
    
    insert:
    set default="0"
    
    Instead of 0, use the index of your choice (from the GRUB boot menu). Normally, 0 would be for Ubuntu and 2 would be for Windows 10.
  • Reboot.

From Windows

Use the same procedure used in Ubuntu, but to be able to access the boot partition from within Windows, use the Ext2Fsd tool.

Final Remarks

  • You might have changed your swap partition during the process. This can make your Ubuntu boot too slow. To fix this, edit /etc/fstab and set the correct UUID of your swap partition (you can get it using GParted).
  • You might want to shorten the GRUB timeout period. You can do this from within /boot/grub/grub.cfg. Change the timeout value throughout the file and that’s it.

Thanks for reading! I wish you best of luck (and no data loss!).

Comments are closed