经验分享 · 2018年7月1日

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

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:

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::0

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

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::1

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:

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”:

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::2

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.

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::3

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

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::4

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:

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::5

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:

At the GRUB console, do:

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:

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:

Nope, not that one.

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:

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

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

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):

Finally type:

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:

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

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

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.

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

Now we delete that EF00 partition:

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

Just press enter for the first and last sector options:

…but enter AF00 for the filesystem code:

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

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

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:

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

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:

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

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

Test it out by remounting /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:

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:

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:

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

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

The final step is to create the grub configuration:

The system should now be bootable!

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

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

 
::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::6

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:

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:

edit your fstab file by running:

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

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

::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::7

::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::8

::__IHACKLOG_REMOTE_IMAGE_AUTODOWN_BLOCK__::9