Defeating programmed obsolescence: Apple's 32bit EFI implementation

April 12, 2014

We moved away from the traditional BIOS, towars something nicer, easier to use. From excessivly memory limited and obscure BIOSes we moved to fully graphical base setup environment. EFI is great. Sadly, the transition did not happen overnight, and this had for result various interesting implementations.

Where most “traditional PC” early EFI implementation headed towards immediate compatibility with “BIOS ready” software, Apple’s original EFI implementation was unique. As such, to Apple systems, every media is EFI unless it’s a “Windows” media. That is, something that shows distinctive “BIOS boot” characteristics. It is also worth noting that the actual implementation for CDs/DVDs seems to be looking specifically for some Windows related parts, seemingly leaving no chance to Linux users.

The guys at Canonical have a special “+ Mac” ISO you can grab, yet it’s interesting to see that installing other distributions on an aging Mac seems quite a headache. When I’m saying “aging” I’m actually refering to the Original Mac 1.1 and 2.1. Even though built on Core2Duo/Core2Quad generation hardware, the machines where well built and the two Xeon’s actually make for an interestingly powerfull machine. Sadly Apple dropped support and these machines won’t be getting the newest and greatest anymore As a Software Engineering student-on-a-budget who got an axis towards more “systems” stuff (hear Security, Virtualization, Operating Systems…), used Macs are a great way of getting workstation class hardware for a more decent price. Of course I could have tried to get a Lenovo or Dell workstation, but the prospect of having easy access to Mac OS X for testing was the last argument to convince me. Off course Richard Stallman would probably say that the mere idea of buying a Mac is a bad one, even more so considering Apple’s track record of not respecting users freedom. But I’m getting off tracks…

Conditions

So the problem I want to explore here is the situation where you are trying to install a GNU/Linux Distribution on one of these EFI32 Macs, where we have the following conditions:

  1. We want to install something else than Ubuntu. We are here going to explore Fedora 19 / 20
  2. The Mac won’t boot that distro’s liveCD or DVD (showing “denied” symbol or otherwise)
  3. LiveUSB don’t seem to be helping. “Regular” liveUSB techniques fail to bring up a Live Environment

Instructions showed here may be out of grasp of some less experienced users. If you only want to get Linux running on your machine in a very simple way, you might be better off with Ubuntu… At least for now.

IMPORTANT NOTE: If you can pull out the target hard-drive and install on a diffenrent machine without too much hassle, doing it that way would probably be recommanded. From the moment the target disk is on another system, non-EFI install should be just fine.

Sadly, at the time of this writting I have yet to figure out how to get Fedora running in GPT (and thus EFI) mode.

The theory

Now that we have established conditions, we can explore the theory of how to fix the issue.

As stated before, these Macs have a 32bit EFI implementation. Because of implementation details, they will only accept to boot 32bit code. As such they can’t boot into the regular 64bit EFI Grub2 of the Fedora liveMedia. So what we are going to do is create a liveUSB media with 32bit Grub2 parts that these Macs can tap into. From the point where we can boot into Grub, we can use it to boot into 64bit Linux, since it is a lot more flexible than the Mac’s included bits.

NOTE: Sadly at this point I have not found how to install the system in EFI mode, partly due to a chronic lack of time partly caused by the fact I’m studying engineering and that initial experimentation and writting happened days before the final exams. People have reported they were able to do so, but I could not reproduce that behavior following their instructions, indicating either a flaw in said instructions or the way I’m trying to execute them.

The solution

To do this, we are first going to create a liveUSB. But to make things easier, we are going to do so from the liveCD, in a VM. It’s out of the scope of this document to enforce a specific Virtual Machine technology on you, so as long as you can forward your USB stick into the VM you should be fine.

# export PATH=/run/initramfs/live/LiveOS:$PATH
# livecd-iso-to-disk \
  --noverify \
  --format \
  --msdos \
  --reset-mbr \
  --efi \
  --overlay-size-mb 512 \
  --swap-size-mb 512 \
  --home-size-mb 1024 \
  --crypted-home \
  /run/initramfs/livedev /dev/sdb

Where you replace sdb by whatever device your USB stick ended up being.

Then mount the device (if it didnt mount automagically):

# mkdir /run/media/liveuser/LIVE/
# mount /dev/sdb/ /run/media/liveuser/LIVE/

We will also download the i686 version of Grub2 and extract the bits we need for this purpose:

# rpm2cpio grub2-efi-2.00-23.fc20.i686.rpm | cpio -imVd
# cp -r ./user/lib/grub/i386-efi /usr/lib/grub

The next thing will be to build the EFI32 compatible BOOTIA32.efi file, and add it to the liveUSB

# grub2-mkimage -d /usr/lib/grub/i386-efi -o BOOTIA32.efi -O i386-efi \
  --prefix /efi/boot part_gpt part_msdos lvm fat ext2 btrfs chain boot \
  configfile normal minicmd linux reboot halt search gfxterm gfxmenu \
  efi_gop efi_uga video loadbios gzio video_bochs video_cirrus echo true \
  loadenv linuxefi
# cp BOOTIA32.efi /run/media/liveuser/LIVE/EFI/BOOT/BOOTIA32.efi

At this point, your Grub is bootable by your Mac. Sadly, we apparently need to do more to reach a working system.

So we are going to add the following to the EFI/BOOT/grub.cfg on the USB stick:

NOTE: You WILL have to make sure that you are using the good UUID. This can generally be done using blkid. The grub.cfg should normally also contain it in the existing entries. Also make sure that the initrd0.img and vmlinuz0 files locations are correct. If you are doing this for Fedora 19 / 20, it should not be a problem.

menuentry "Fedora fakebios, askmethod" {
        fakebios
        search --set -f /syslinux/vmlinuz0
        linux /syslinux/vmlinuz0 root=live:UUID=FD8D-206A rw rd.live.image overlay=UUID=FD8D-206A rhgb rd.live.check askmethod
        initrd /syslinux/initrd0.img
}

At this point, you should be able to reboot and get to the live environment to install your system.

Interestingly enough, the new open source Radeon drivers seem to do a very nice job with my HD5770.

Installing proprietary code to get all devices up and running properly is out of the scope of this document.

I might try to get an additionnal Hard Drive to do more tests and attempt to reach a full EFI boot. If so, this document will be updated.

References

Those resources were useful throughout this project: