Ubuntu installation on USB stick with pure EFI boot (Mac compatible)

Marco Miglierina
10 min readAug 4, 2016

--

All I wanted was just:

  • an USB key with Ubuntu 16.04 LTS installed on it,
  • with /home and swap encrypted,
  • that I could boot from any of my 2 Macs, by simply pressing and holding the “option” (or “alt”) key immediately after boot,
  • without messing around with their respective boot loaders.

After trying dozens of solutions on all available blogs on the Internet I finally found THE solution that worked for me!

I must thank Jason Heeris who enlighted me with his tutorial: “UBUNTU + MAC: PURE EFI BOOT”, and to whom should go part of the credit for this guide. He explained how to install Ubuntu natively on a Mac with pure EFI boot. This guide will contain parts of his instructions, with some changes you need to consider if you want to have a full Ubuntu installation on USB (or on an external hard drive) without touching your Mac’s hard drive: just the tutorial I would have liked to find while googling for help few days ago.

Disclaimer

Even though the process should leave your Mac’s hard drive intact (this was my case), I strongly recommend to backup your data and have an OS X recovery usb ready, just in case something goes wrong… and things often go wrong. I don’t take any responsibility of any damage for lost data or unbootable Mac.

Equipment

  • Your Mac, obviously,
  • a USB stick with the Ubuntu installer on it (instructions here),
  • the USB stick where you are going to install Ubuntu on.

Ubuntu installation

Shut down your Mac, insert the installer USB stick and power on the machine while holding “option” or “alt” key until the boot menu appears. You should see something like this:

Select EFI Boot and press enter. You will be presented with a GRUB bootloader menu:

Select Install “Try Ubuntu without installing” and press enter. Once the live version of Ubuntu is fully loaded, insert the USB stick where you want to install Ubuntu on, open the Terminal and run the following command:

ubiquity --no-bootloader

The Ubuntu installer will come up. This is an important step, if you started the Ubuntu installer from the Desktop icon or by selecting “Install Ubuntu” from the previous GRUB bootloader menu, the installation would replace your Mac’s default bootloader. You must start the installer through the terminal with the “ — no-bootloader” option.

Proceed with the normal installation steps: select your language, choose if you want to install third-party software bla bla… You may be prompted then with a message asking whether you want to unmount any of the partitions of the destination USB drive before getting to this step, if it happens, click “Yes”. Finally get to the “Installation type” screen. Select “Erase disk and install Ubuntu”:

Click “Continue” and NOW BE VERY CAREFUL to select the correct drive. Under “select drive” you should find and select your destination USB drive, “sdd” in my case. If you select your internal hard drive, which is usually “sda”, you will erase all of your OS X installation and data.

After selecting your USB drive, you can click on “Install Now”. You will be prompted with a message like this:

Double check that only “sdd” (or whatever the name of your USB drive is) is specified, and click “Continue”. In the following and last step of the installation you have to choose your username, password and whether you want your home folder encrypted (recommended if you are going to store confidential data on your Ubuntu home folder). Finally click “Continue” and wait for the installation to finish, it will take some time. Once finished you can restart your system. Ubuntu may get stuck while trying to restart, at least this was my case, just press and hold the power button until your Mac shuts down.

At this point your Ubuntu installation is done, but you cannot boot from it yet. But don’t despair, we are going to fix this by following Jason Heeris’ instructions.

The manual boot

While keeping both your USB sticks inserted, power on the machine while holding “option” or “alt” key until the boot menu appears, as you did before. You should see the Mac’s boot menu with the following options:

Again, select “EFI Boot” and press enter to boot again from the Ubuntu installer USB and get to the previous GRUB bootloader menu. Don’t select any of the entries. Instead, press “c” to bring up the GRUB console. Now you should be looking at a GRUB console:

grub>

At the GRUB console, do:

grub> ls
(memdisk) (hd0) (hd1) (hd1,gpt3) (hd1, gpt2) (hd1,gpt1) ...

You want to look for your new installation, not the installer/live system. Finding a partition with your new user’s home directory on it:

grub> ls (hd2,gpt2)/home
mmiglier/

Keep trying this pattern until you find it. The result from the last step has two parts: (hdX,gptY). You need to keep the hdX part, but go through all the gptY options looking for a /boot/grub directory:

grub> ls (hd2,gpt1)/boot/grub
error: file `/boot/grub' not found.

Nope, not that one.

grub> ls (hd2,gpt2)/boot/grub
unicode.pf2 ...

Found it! If you went with the default partition scheme, the boot folder should be in the same partition as your home directory.

Now you want to set this as your root for further commands:

grub> set root=(hd2,gpt2)

You then need to find out the UUID of the drive:

grub> ls -l (hd2,gpt2)
Partition hd2,gpt2: Filesystem type ext* 〈...snip...〉 UUID e86c20b9-83e1-447d-a3be-d1ddaad6c4c6 - Partition start at [...]

Note the UUID string! Yours will be different. Now tell GRUB where Linux is:

grub> linux /boot/vmlinuz〈...tab here!...〉.efi.signed root=UUID=〈the UUID from above〉

The GRUB console can do tab completion, so if you just type out the vmlinuz part and hit tab, then hit “.” and tab again… you won’t have to type out the whole filename. But do make sure the .efi.signed bit is there! And yes, you will have to type out that whole UUID.

Now set the initrd (initial RAM disk):

grub> initrd /boot/initrd〈...tab here!...〉

Finally type:

grub> boot

You should find yourself booted into your installation!

Fixing the EFI partition

So why is the system unbootable? The problem is that the Mac bootloader expects the EFI partition to be formatted as HFS+, the typical Mac filesystem. It also expects certain files to be present. The Ubuntu installer actually formats it as VFAT and doesn’t create the files that are necessary for booting on a Mac.

The first thing you’ll need to do is to install some extra utilities. Fire up the Terminal and enter:

$ sudo add-apt-repository ppa:detly/mactel-utils
[...]
Utilities for Intel based Macs (eg. recent MacBooks, Mac Minis). Includes a
fan control (macfanctld) and the HFS "bless" utility.
More info: https://launchpad.net/~detly/+archive/ubuntu/mactel-utils
Press [ENTER] to continue or ctrl-c to cancel adding it

Press enter to add the PPA. Then update your package list and install the necessary utilities:

$ sudo apt-get update
$ sudo apt-get install mactel-boot hfsprogs gdisk grub-efi-amd64

Run the following command to check what is the name of the device where Ubuntu is installed:

$ sudo fdisk -l
[...]
Disk /dev/sdd: 57,9 GiB, ...
[...]

In my case, it is /dev/sdd. We now use gdisk to delete the VFAT partition and create an HFS+ one. gdisk is interactive, and doesn’t write changes to the disk until you tell it to, so don’t panic if you make a mistake. Replace sdd with your USB device name.

$ sudo gdisk /dev/sdd
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
MBR: hybrid
BSD: not present
APM: not present
GPT: present
Found valid GPT with hybrid MBR; using GPT.Command (? for help):

Print the partition table and confirm that the first partition has type EF00:

Command (? for help): p
Disk /dev/sdd: ...
[...]Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 EFI System Partition
[...]

Now we delete that EF00 partition:

Command (? for help): d
Partition number (1-3): 1

…and create a new HFS+ one in its place:

Command (? for help): n
Partition number (1-128, default 1): 1

Just press enter for the first and last sector options:

First sector (34-121307102, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-1050623, default = 1050623) or {+-}size{KMGTP}:

…but enter AF00 for the filesystem code:

Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): AF00
Changed type of partition to 'Apple HFS/HFS+'

Now we’re ready to write the changes. Use the p command to double-check your changes, and then w to write:

Command (? for help): wFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdd.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.

Now we have an unformatted HFS+ partition. We can format it with (replace sdd with your USB device name):

$ sudo mkfs.hfsplus /dev/sdd1 -v Ubuntu
Initialized /dev/sdd1 as a 512 MB HFS Plus volume

For system partitions (eg. /, /boot, /boot/efi) Ubuntu uses the UUID (universally unique identifier) of a disk partition to mount it (rather than the device node, eg. /dev/sdd1). This means we need to update /etc/fstab:

$ sudoedit /etc/fstab

This will launch the nano text editor. Look the two lines that refers to /boot/efi:

# /boot/efi was on /dev/sda1 during installation
UUID=C59D-1B30 /boot/efi vfat defaults 0 1

Use ↓/↑ to position the cursor at the start of these lines and hit ctrl+K to delete them. Press ctrl+X and then Y to save and exit nano. Now, check that no partition is mounted on /boot/efi by running:

$ mount | grep /boot/efi
/dev/sda1 on /boot/efi ...

In my case, sda1 was mounted on /boot/efi. Unmount /dev/sda1:

$ sudo umount /dev/sda1

Then run this to add the necessary entries to your fstab file, replacing sdd with your USB device name:

$ sudo bash -c 'echo UUID=$(blkid -o value -s UUID /dev/sdd1) /boot/efi auto defaults 0 0 >> /etc/fstab'

Test it out by remounting /boot/efi:

$ sudo mount /boot/efi

Note that you shouldn’t use extra options here. If it doesn’t work from that command alone, it means your /etc/fstab entry is wrong.

If you run the previous command you should see your USB partition mounted on /boot/efi:

$ mount | grep /boot/efi
/dev/sdd1 on /boot/efi ...

Now we’ll reinstall GRUB so it can use the newly formatted HFS+ partition for its EFI data. First, create the necessary directory on the EFI partition:

$ sudo mkdir -p "/boot/efi/EFI/$(lsb_release -ds)/"

The $(lsb_release -ds) part automatically produces a label for the distribution like Ubuntu 16.04 LTS.

Now, there’s a bug in GRUB that means that on HFS+ it requires a file named mach_kernel to exist in a particular place before it runs. In fact, it’s really the Mac bootloader that requires this file, but GRUB seems to look for it in the wrong place and refuses to run if it’s not there, so we need to create it twice:

$ sudo bash -c 'echo "This file is required for booting" > "/boot/efi/EFI/$(lsb_release -ds)/mach_kernel"'
$ sudo bash -c 'echo "This file is required for booting" > /boot/efi/mach_kernel'

Now we need to install GRUB, and we need to be a bit explicit about where it should put its files:

$ sudo grub-install --target x86_64-efi --boot-directory=/boot --efi-directory=/boot/efi --bootloader-id="$(lsb_release -ds)"

We then need to “bless” the bootloader code, so that the Mac bootloader will boot it:

$ sudo hfs-bless "/boot/efi/EFI/$(lsb_release -ds)/System/Library/CoreServices/boot.efi"

The final step is to create the grub configuration:

$ sudo sed -i 's/GRUB_HIDDEN/#GRUB_HIDDEN/g' /etc/default/grub
$ sudo sed -i 's/GRUB_TIMEOUT=10/GRUB_TIMEOUT=0.1/' /etc/default/grub
$ sudo grub-mkconfig -o /boot/grub/grub.cfg

The system should now be bootable!

Let’s just finish by adding the Ubuntu icon that will be displayed at boot. Simply do:

$ sudo apt-get install mactel-boot-logo
$ sudo cp /usr/share/mactel-boot-logo/ubuntu.icns /boot/efi/.VolumeIcon.icns

Reboot your system, press and hold the “option”/“alt” key and you should finally be able to boot Ubuntu from your USB key!

If you don’t press and hold the “option”/“alt” key at startup it should boot directly into OS X as usual. However the second time I went through all this process I’m not sure what I did wrong or what was different from the first time and by default my Mac was booting into Ubuntu. If it is also your case, try to mount your /dev/sda1 partition and remove the EFI folder in it:

$ sudo mkdir -p /mnt/sda1
$ sudo mount /dev/sda1 /mnt/sda1
$ sudo rm -r /mnt/sda1/EFI

This solved the problem for me. After reboot, OS X was again my default OS.

Final make up

If you are going to keep the USB always inserted, like me, you will notice that when starting OS X, the ESP partition will be automatically mounted. To prevent this, annotate the partition UUID by running from OS X:

$ diskutil info /Volumes/Ubuntu | grep "Volume UUID" | awk 'NF>1{print $NF}'
5F2578EF-237A-3AC9-BC32-0BD4D520A0A7

edit your fstab file by running:

$ sudo vifs

move down until you reach the end of the file, press “o” and paste the following line after replacing the UUID with yours:

UUID=5F2578EF-237A-3AC9-BC32-0BD4D520A0A7 none hfs rw,noauto

Then press “ESC” to exit the editing mode, “:wq” and finally “Enter” to save and exit.

--

--

Marco Miglierina

PhD candidate in Computer Science and Engineering. Technology and Software Enthusiast. Husband. Father²