Installing Linux on a Macbook Pro on an external Firewire drive

Or, how Apple's EFI firmware boots "legacy" operating systems

The other day I got a fancy new 1.5TB external disk for Time Machine, and after setting that up, I had my previous backup disk (250GB, not too small) available to do something cool with. I figured a good thing to try and do would be install GNU/Linux (Ubuntu 9.10, specifically) on the external drive -- the Macbook Pro can boot from firewire after all, so maybe I don't have to touch the internal disk. (Back when I had desktop machines I always ran Linux, but since 2004 when I got a laptop I've been using Mac OS X. Maybe it's time to see how far they've come in taking all the fun out of installing Linux by making it totally automatic.)

So I plug the disk in, hold option, and boot from an Ubuntu 9.10 amd64 CD (despite it being labeled "Windows"). Turns out it's pretty automatic after that. It detects everything and installs without any help from me -- save one step at the end, where I specifically tell it to install the bootloader on the external disk. When I reboot and hold option again, I see the Firewire disk as a boot option (once again labeled "Windows"). Hooray! That was easy. So I select it, and wait a moment while it brings up...

Huh. Well I'm pretty sure that device is bootable. Rebooting into the install CD and checking by hand (yes, I can actually read the output of hexdump -C /dev/sdb), it's most certainly bootable. So why won't it boot? I try Google; there are many hits for this message, and accidentally mistyped versions of it, but everybody who's complaining about it is some recent Windows convert who still thinks they need to run it and has botched an install. The problem they're having is not that they see this message after selecting an external boot device, but that they see it always, and don't know how to get back to OS X or Windows (which isn't even installed correctly anyway).

So how does this relate to the problem I'm having? Where is this message coming from, anyway? Several of these people seem to think it's coming from Windows somewhere, but clearly that's not the case for me. After some more searching I find rEFIt which provides a few clues. I try setting up a GUID partition table and creating a small HFS+ partition on the external drive to install it on, then reinstall Ubuntu in the remaining space, but I get the same result when selecting the "legacy OS" in rEFIT's menu. (You might wonder at this point why I don't try to boot Linux from EFI directly, rather than trying to get it to boot as a legacy OS. The rEFIt site answers that as well: if you don't boot it via the firmware's legacy OS facility, you won't get a video BIOS, which the proprietary nVidia drivers require.)

The Problem, Isolated

Still, I look around the rEFIt site a bit -- its authors clearly know a lot about how EFI works and how Apple hardware boots. Finally, after running several of the diagnostic tools they have to help you set up systems to boot, it dawns on me what's going on. Apple's firmware only looks at the internal disk when booting a legacy OS, even if you selected it from an external disk. And I have no legacy OS on the internal disk, so the firmware can't figure out what to do and shows this message. Remember all those Windows people? The problem they're having is that Boot Camp set the firmware to boot in legacy OS mode automatically, but it did that before Windows was actually installed. If the installation is interrupted before Windows installs its (legacy) bootloader, then you'll get this message every time you boot unless you hold down option to select the OS X partition.

So I have two options here, or maybe three. The one I don't really count is to try booting Linux with EFI, but I already mentioned that I don't really want to do that since I'd like my video card to actually work. (Hey, video card manufacturers! This situation sucks! Release some damn source code or specifications, and the open source community will take care of it for you. Seriously.) The real options both involve basically putting /boot on something the firmware knows how to boot: either a CD, which I'd have to update every time I updated the kernel but which would avoid touching my internal disk, or the internal disk. I decided to investigate using the internal disk.

The Solution

As luck would have it, Apple's Disk Utility is one of those many partitioning utilities that for some reason or another feels compelled to waste space in the name of aligning partitions on some sort of huge invisible grid on the disk. It left me 134MB of unpartitioned space at the end of my internal disk, even though I'd originally told it to use all available space. That sounds perfect for a /boot. So hooray, I create a little ext2 partition there with parted, copy my /boot into it, and install GRUB into it (sudo grub-install /dev/sda3 after mounting /dev/sda3 on /boot). GRUB's config files also need some updates, which can be done automatically by running sudo update-grub even though I did it by hand the first time. So far, this is all still totally reversible by just deleting the partition. I get the MBR utility (sudo apt-get install mbr) and install that on /dev/sda (sudo install-mbr /dev/sda). Also reversible, with care.

Update: it turns out that that extra space after the partition is actually left there on purpose - it's 128MiB reserved for some purpose during OS upgrades, and its absence makes the OS X installer insist that the disk is not bootable. Why they didn't just build this into the file system is beyond me, but that's the way it is. It's best to resize the HFS+ partition instead, so that you can keep this reserved space.

Now I just need the MBR partition table to match the GPT, so I can set the third partition bootable and so GRUB will actually work once it gets loaded. It turns out Disk Utility will kind of automatically do that if it wanders across a disk that has a legacy bootloader and whose MBR partition table doesn't match. So a quick trip into OS X to run Disk Utility fixes that right up, and then a final step back in Linux is to use fdisk to set the newly-created MBR partition bootable. (Disk Utility at this point recognizes the disk as being set up for Boot Camp, and again mislabels things as "Windows." Sigh.)

And now, the moment of truth -- I boot holding option, and get three options: OS X, "Windows," and "Windows." The two latter options are the internal partition, and the external disk. Of course, because of the problem that caused this whole story, it doesn't matter which of those I select, as they do the same thing anyway. So I select "Windows" since I want to boot Linux, and lo and behold, I get the GRUB menu! Success! Well, let's not count our chickens before they hatch. I actually want to run Linux, not just GRUB. So I wait while it loads a kernel, and an initrd, and then my external disk's access light starts flashing as the system boots up correctly. Success!

Some Comments

It's also worth pointing out that since the boot procedure is actually totally contained on the internal disk, and the external disk is only involved once the kernel is already running, there's no reason this is limited to Firewire. You could do the same thing with a USB disk, or for that matter any other root file system Linux knows how to use. I've also left out some of the technical details that are necessary to actually follow this procedure step-by-step; for instance, you need to edit /etc/fstab to mount the new /boot on every boot. (Maybe you can avoid this step by reinstalling yet again and telling the installer to use the separate /boot partition. I didn't try.)

I've written this page in the hopes that it contains enough of the keywords I was searching for ("Linux," "Ubuntu," "Macbook," "external disk/drive," "Firewire," "boot," "install," and that totally-accurate-in-its-own-useless-way error message "No bootable device -- insert boot disk and press any key") that somebody else having the same problem might find it and be helped by it. (Maybe even the Windows people too, despise them as I might for their complacent acceptance of shoddy software and closed hardware that keeps better systems from being able to really gain any significant ground. But OK, I'll throw you a bone. Hold down option as soon as you hear the chime. That's the button that's also labeled "alt" in case you don't know which one it is. Then boot back into OS X, set it as the startup disk, and just give up installing Windows. You don't need it anyway.)

Still need help? Not one of those Windows people? Maybe I can be of assistance. Go figure out my email address at my main page and email me!