Linux and Mac OS X dual-boot on Macbooks

Published: 2013-02-18
Updated: 2014-01-04

Start with the normal install of OS X.

Partitioning

Start "Disk Utility" in OS X, it can do an online-resize of the OS X partition

  1. in the list on the left select the drive, not the partition
  2. click the "Partition" tab button
  3. drag the lower right corner of the "Macintosh HD" block up to resize, and Apply

Note that there are 2 other partitions which Disk Utility hides from you. In /dev there are disk0, disk0s1, disk0s2, disk0s3.

  • disk0s1 is 200 MiB fat32 filesystem related to EFI, not used for much yet, but we'll use it
  • disk0s2 is "Macintosh HD" which you just resized
  • disk0s3 is "Recovery HD" for reinstalling OS X, around 1GiB, seems to move along with the end of the "Macintosh HD" partition

You can make a disk0s4 from linux (which linux calls sda4) and use that for the linux root filesystem. Boot into the installer for whatever linux distro you're installing, if it has the "gdisk" tool, or into SystemRescueCd if not. Use gdisk to to make a partition for linux in the free space, and tell the installer to re-use that partition, and format it with your preferred filesystem.

Prepare grub2 EFI

After installing the linux distro but before rebooting, make sure the partition you installed to is mounted, and chroot into it. That might look like this:

mount /dev/sda4 /mnt
cp /etc/resolv.conf /mnt/etc/resolv.conf
mount -o bind /dev /mnt/dev
mount -t proc /proc /mnt/proc
mount -t sysfs /sys /mnt/sys
chroot /mnt bash

Make sure the grub2 efi x86_64 package is installed. If it wasn't installed during the initial distro install, install it now. That might look like this:

pacman -Sy
pacman -S grub2-efi-x86_64

Generate a grub config file:

grub-mkconfig -o /boot/grub/grub.cfg

You may need to tweak it, or create the /boot/grub directory manually first.

Generate a standalone grub efi executable (/usr/lib/grub-x86_64-efi may be different for your distro):

cd /
grub-mkstandalone --directory="/usr/lib/grub-x86_64-efi" --format="x86_64-efi" --compress="xz" \
                  --output="/root/grub2-standalone.efi" "boot/grub/grub.cfg"

Note that if you update grub2 or change your config (and need the changes to take effect), you need to regenerate this executable and re-install it (as I'm about to describe).

Install Grub2 EFI

Mount that nifty EFI partition that already exists.

mkdir -p /boot/efi
mount LABEL=EFI /boot/efi

Now we put our grub2 standalone EFI executable in a magic place: "EFI/BOOT/BOOTX64.EFI"

mkdir -p /boot/efi/EFI/BOOT
cp /root/grub2-standalone.efi /boot/efi/EFI/BOOT/BOOTX64.EFI

That should be all that's needed.

Cleanup

It's probably best to cleanly unmount stuff before rebooting:

umount /boot/efi
exit # (the chroot)
umount /mnt/dev
umount /mnt/proc
umount /mnt/sys
umount /mnt
reboot

Setting Default Boot

You can already use the "option" key during boot to boot grub2 (and thus linux). To make that the default, try this:

Boot up OS X, and open Terminal. Mount the EFI partition in /Volumes, and try using the "bless" command.

sudo mkdir /Volumes/EFI
sudo mount -t msdos /dev/disk0s1 /Volumes/EFI
# change the "active volume" which is the default that the EFI firmware boots
sudo bless --mount "/Volumes/EFI" --setBoot

There's a length man-page for bless in OS X. I didn't have the patience to figure out any more than the above, though.

First Boot

If the linux installer booted up in EFI mode, you should be fine, ignore this section.

If your linux installer booted up in BIOS emulation mode, it may have prepared an initramfs with kernel modules needed for BIOS emulation mode boot, not EFI mode. You'll need to somehow get an initramfs with all the modules needed to boot in EFI mode, and then regenerate the normal initramfs.

I only have specific tips for Arch Linux. Arch Linux has a "fallback" initramfs and boot option which has all the needed modules, so simply boot that the first time, then regenerate the normal initramfs with:

mkinitcpio -p linux