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
.
- Shrink the Ubuntu partition to leave
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 thestorage
partition, then you are good to go. Otherwise, we’ll have to delete theswap
partition, create a new logical/extended partition then create both thestorage
andswap
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 necessarilysda
, select your HDD). - Press
s
(sort partitions). - Press
r
(recovery and transformations). - Press
g
(convertGPT
intoMBR
and exit). - Press
w
(write table to disk and exit). - Note:
GPT
doesn’t play well with extended partitions. If you have to usegdisk
, 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.
- Select
- Open the Boot Camp utility:
- Insert a
FAT32
formatted USB Storage device (not necessarily empty) with about2 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.
- Insert a
- 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:
- .NET framework 2.0 SP2.
- bootsect7600x86 (just search for it).
- IMAPI v2.0.
- Windows7-USB-DVD-Download-Tool-Installer-en-US.
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 thePurge 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 of0
, use the index of your choice (from the GRUB boot menu). Normally,0
would be for Ubuntu and2
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 correctUUID
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 thetimeout
value throughout the file and that’s it.
Thanks for reading! I wish you best of luck (and no data loss!).