Ubuntu – MacBook Pro and Ubuntu 17.04 on USB Drive

17.04grub-efimacbook prousb

I've been searching around for a while and have not really found an answer to this question other than install rEFInd…which I want to reserve as a last resort. If that's the only answer, then it's the only answer. I just want to be sure.

I have had no issues creating a bootable USB drive with the 17.04 ISO, and my MacBook Pro has no issues booting from that USB drive to run 17.04 live.

What I want to do is install 17.04 to another 64 GB USB drive, be able to boot off of that USB, and run 17.04 like it is installed on my hard drive.

To prepare, I used Gpartd in the live environment to create a GUID partition table on the 64 GB USB stick, created a EFI system partition at the beginning of the drive (FAT32 marked as ESP and Boot), created a swap partition (primary linux-swap), and created the main partition (primary ext4).

I started the 17.04 installer, instructed it to put GRUB on the ESP, and install the root file system to the ext4 partition. Everything ran fine, but, of course, the MacBook Pro's boot manager does not recognize it. It still recognizes the install USB stick just fine.

Any help would be appreciated. Like I said, I would rather avoid rEFInd just because I like to make as few changes to the system as possible. But, I'm cool with that being the only answer.

Best Answer

The trouble is that under EFI (which Intel-based Macs use), removable disks boot differently than internal disks, and the Ubuntu installer is set up to install for internal disks but not removable disks. To elaborate:

  • Internal disks boot by putting a boot loader (grubx64.efi in the case of Ubuntu, at least by default) on the EFI System Partition (ESP) of the disk, typically in a subdirectory of EFI named after the OS. That is, for Ubuntu, GRUB is called EFI/ubuntu/grubx64.efi. For Fedora, it's EFI/fedora/grubx64.efi. For Windows, it's EFI/Microsoft/Boot/bootmgfw.efi. Because the filename varies depending on the OS, the computer needs to be told what filename to launch, and that information is stored in NVRAM. Ubuntu, like other Linux distributions, uses a tool called efibootmgr to manipulate the NVRAM.
  • Removable disks boot in a similar way to internal disks, but because removable disks are usually meant to be carried from one computer to another (as OS installers or emergency utility disks, for instance), they can't rely on information stored in the computer's NVRAM. Instead, they store their boot loaders using the fallback filename, EFI/BOOT/bootx64.efi for x86-64/AMD64/x64 systems. EFI-based computers can boot removable media using the fallback filename on the disk's ESP.

There are some twists and caveats. Most notably, Macs can also boot from HFS+ volumes using the default macOS boot loader filename of System/Library/CoreServices/boot.efi; and to support UEFI-based PCs with Secure Boot, Ubuntu boots through a program known as Shim, which is stored as EFI/ubuntu/shimx64.efi or given the fallback filename on removable disks. Shim then launched grubx64.efi in a way that enables Secure Boot to work. Neither of these issues needs to be a factor for you on a Mac, since Macs can boot from the standard EFI boot loader locations and Macs don't use Secure Boot. You might run into references to these factors, though, and if you wanted to create something that would boot on UEFI-based PCs, you might need to add Shim for Secure Boot support.

One further complication is that Ubuntu's installer puts GRUB on the first ESP that it finds. This is likely to have been your internal hard disk, not the external disk. Thus, your main Ubuntu installation is likely to be on the external disk, but GRUB is likely to be on the internal disk. Ubuntu won't boot without GRUB or some other boot loader, so your external disk needs something else before it can boot.

In short, your task is to put a boot loader on your external disk using the fallback filename. There are quite a few options for this; see my EFI Boot Loaders for Linux page for a rundown of what's available, and for installation instructions. Two options are likely to be easiest to install, though:

  • GRUB -- If you can locate your existing GRUB installation, you should be able to copy it to the fallback boot loader position on the external disk's ESP. As I said, your GRUB is probably stored as EFI/ubuntu/grubx64.efi (along with shimx64.efi in the same location) on your internal disk's ESP; however, I can't be 100% positive of that. Once you locate GRUB, you should be able to copy it to the external disk's ESP under the fallback filename -- that is, copy all the files from that directory to EFI/BOOT on the external disk's ESP and rename either shimx64.efi or grubx64.efi to bootx64.efi. This should render the external disk discoverable to and bootable by the Mac's boot manager.
  • rEFInd -- You can download the rEFInd .zip file from the rEFInd downloads page. You can then run the refind-install script, passing it the --usedefault {device_file} option, as in sudo ./refind-install --usedefault /dev/disk1s1 to install it using the fallback filename to /dev/disk1s1 (which I'm assuming is your removable disk's ESP; but it could be something else). If you do this from Ubuntu, it should copy the right filesystem driver to read the Linux filesystem on which the kernel is installed. If you do it from macOS, it should copy the ext4fs driver. If you want to copy all the filesystem drivers, you can add the --alldrivers option to refind-install. This is sometimes helpful, but unnecessary drivers add to the risk of rEFInd malfunctioning, perhaps to the point of hanging. In any event, once this is done, the external disk should be bootable, and if the right filesystem driver is included, when you boot, rEFInd should appear and give you the option of booting Linux or anything else that's installed. Note that this installs rEFInd to the external disk, not to the internal disk.

Note that if you install rEFInd to the external disk in this way, that disk will become a useful emergency boot tool. When it launches, rEFInd actively scans for boot loaders on all media, which can be useful in case the boot process has become damaged in some way. rEFInd can also launch emergency EFI tools (if they're installed), adjust SIP settings, etc. GRUB can do some of these things, but it's not configured to do any of them by default.

If you were to install rEFInd to your internal disk (which is the method of installation to which I believe you were referring in your question), rEFInd should be able to boot the external disk, provided the right filesystem driver was installed. This would not help you boot the external disk on another computer, though, just on the Mac to which you installed rEFInd.

Related Question