Tuxation

Linux on a Macintosh

Since Apple introduced the Intel chip in their Macintosh computers, people have been using this technology to run other software that they would normally run on their PCs, such as Windows or various blends of *nix. Because of their specialized hardware, Macs present somewhat of a challenge to get a PC operating system that would run without a hitch on a normal PC computer, running on an Intel Mac. This guide aims to highlight, avoid and deal with main complications that arise when running (or trying to run) Linux on a Macintosh.

Before you start, the first thing you should do is backup any important data stored on the machine. Installing Linux on Macs is becoming increasingly reliable, however, bugs are still present, and accidents happen. Don't trust all your data with Linux installation software.

EFI and GPT

One of the biggest difficulties with installing Linux on a Mac is partitioning. This is due to several factors. Macs don't have a BIOS like normal PCs do; instead they have an Extensible Firmware Interface (EFI), which is supposed to be an advanced version of a BIOS. Not only does it boot differently, but it can boot GUID partition tables (GPT). It just so happens that Apple uses GPT by default on OS X installations, which is where the complications arise. GPT isn't directly backwards-compatible with the old style MBR-based partition tables, so you need a couple of things:

  1. partitioning software that can support and edit GUID partition tables
  2. a bootloader that supports EFI booting

Fortunately, these aren't hard to find if you know where to look.

Partitioning

Here are the most common partitioning softwares that you can use:

Now, before going any further, it is important to point out how GPT will work on your system. GPT is a sort of advanced partition table, having many technological advantages over MBR-based partition tables, in particular, the end of extended partitions and an unlimited number of primary partitions. However, for backwards compatibility, it is possible to have an MBR partition table also present on a GPT-partitioned hard disk, creating a sort of GPT/MBR hybrid partition table. The GPT is basically copied into the MBR, allowing operating systems that don't support GPT to read off of the MBR to get partition coordinates. Linux supports GPT, so an MBR backwards-compatbility partition table shouldn't really be necessary, except that many Linux distributions don't include a GPT-enabled kernel by default, and secondly, the GRUB bootloader reads from the MBR table.

This means that installing Linux on a Mac will require a GPT/MBR hybrid table. However, since MBR only allows a maximum of 4 primary partitions, and GPT doesn't allow extended partitions, this will effectively limit you to a maximum of 4 partitions in your GPT/MBR hybrid table. A Mac OS X installation will eat up the first two partitions, leaving you with two for your Linux installation. This shouldn't be a problem for most people, but it's important that you know about it. Finally, it's possible to add additional partitions to a GPT/MBR hybrid table by adding extra partitions solely to the GPT table (i.e. not syncing the MBR to the GPT), and then reading these partitions from GPT-capable software (Linux).

Boot Camp

The main use for Boot Camp is for quickly resizing your OS X partition in preparation for a Linux install. The only hitch is that the Linux you choose *must* include a GPT-aware partitioning program. Ubuntu is one such Linux. In the partitioner, simply delete the Boot Camp partition, and in its place create a root and swap partition. Make sure that you install GRUB onto your root partition (most likely (hd0,2) or (hd0,3), depending on the ordering of your root and swap partitions). Installing GRUB to the root partition ensures that GRUB can be loaded through the Boot Camp interface when holding down the Option key during boot-up. Choosing 'Windows' will start GRUB and, hopefully, Linux.

diskutil

diskutil is basically a way to use Boot Camp without buying the latest version of Mac OS X. While resizing, you can also create new partitions. This is the syntax for resizing a volume, taken directly from the diskutil help screen:

Usage:  diskutil resizeVolume MountPoint|DiskIdentifier|DeviceNode size
        [part1Format part1Name part1Size part2Format part2Name part2Size
         part3Format part3Name part3Size ...]

First, you should print out your partition table:

$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *55.9 Gi    disk0
   1:                        EFI                          0.2 Gi    disk0s1
   2:                  Apple_HFS OSX                     55.7 Gi    disk0s2

Here, the OS X volume that needs to be resized is disk0s2. This is an example of how you would do it at the command line:

$ sudo diskutil resizeVolume disk0s2 40G Linux linux 15G

While diskutil supports creation of Linux data partitions, it does not support Linux swap partitions. You have two options:

The actual type and size of the last partition doesn't matter, it's just a placeholder so that the Linux partition doesn't use up all your disk space. After you've resized the volume, you can go back and delete this partition, and create a Linux swap partition.

gpt

This is probably the most powerful partition editor available to you, however, it works best when you do *not* have a GPT/MBR hybrid partition table. You can print out your partition table by opening a terminal, and running the following:

$ sudo gpt -r show /dev/disk0

Password:
gpt show: /dev/disk0: Suspicious MBR at sector 0
      start       size  index  contents
          0          1         MBR
          1          1         Pri GPT header
          2         32         Pri GPT table
         34          6         
         40     409600      1  GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B
     409640  116784536      2  GPT part - 48465300-0000-11AA-AA11-00306543ECAC
  117194176      16030         
  117210206         32         Sec GPT table
  117210238          1         
  117210239          1         Sec GPT header

The "suspicious MBR at sector 0" means that the MBR is synced to the GPT. The gpt utility will still work, but it's better if you use it before you sync your MBR table (another way to remove the MBR table is to modify the partition table in parted, explained later). To actually use gpt, you'll have to boot off your OS X installation disk as mentioned earlier. From the Utilities menu, choose Terminal to open a new shell. Once you've loaded that up, you're ready to start editing your GPT. If you don't have root access, run "sudo su" at the prompt before starting. Deleting a partition is fairly straightforward:

# gpt remove -i 2 /dev/disk0

Replace '2' with the number of the partition you wish to delete.

Adding a partition is slightly more complex. Below is the section of the gpt manual page describing it:

     gpt add [-b number] [-i index] [-s count] [-t type] device ...
             The add command allows the user to add a new partition to an
             existing table.  By default, it will create an HFS partition cov-
             ering the first available block of an unused disk space.  The
             command-specific options can be used to control this behaviour.

             The -b number option allows the user to specify the starting
             (beginning) sector number of the partition.  The minimum sector
             number is 1, but has to fall inside an unused region of disk
             space that is covered by the GPT.

             The -i index option allows the user to specify which (free) entry
             in the GPT table is to be used for the new partition.  By
             default, the first free entry is selected.

             The -s count option allows the user to specify the size of the
             partition in sectors.  The minimum size is 1.

             The -t type option allows the user to specify the partition type.
             The type is given as an UUID, but gpt accepts efi, hfs, linux and
             windows as aliases for the most commonly used partition types.

In other words, -b is where the partition starts, -i is the partition number, and -t is the partition type. Partition types are worth explaining a bit more. GUID partition tables keep track of the different types of partitions by using UUIDs as unique identifiers. That is, if you want to create, say, a Linux swap partition, you need to know the UUID for it. Here is the list of all the possible UUIDs you can use (taken from Wikipedia):

Assoc. OS Partition type Globally-Unique Identifier (GUID)
(None) Unused entry 00000000-0000-0000-0000-000000000000
MBR partition scheme 024DEE41-33E7-11D3-9D69-0008C781F39F
EFI System Partition C12A7328-F81F-11D2-BA4B-00A0C93EC93B
Windows Microsoft Reserved Partition E3C9E316-0B5C-4DB8-817D-F92DF00215AE
Basic Data Partition EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
Logical Disk Manager metadata partition 5808C8AA-7E8F-42E0-85D2-E1E90434CFB3
Logical Disk Manager data partition AF9B60A0-1431-4F62-BC68-3311714A69AD
HP-UX Data partition 75894C1E-3AEB-11D3-B7C1-7B03A0000000
Service Partition E2A1E728-32E3-11D6-A682-7B03A0000000
Linux Data partition EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
RAID partition A19D880F-05FC-4D3B-A006-743F0F84911E
Swap partition 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
Logical Volume Manager (LVM) partition E6D6D379-F507-44C2-A23C-238F2A3DF928
Reserved 8DA63339-0007-60C0-C436-083AC8230908
FreeBSD Data partition 516E7CB4-6ECF-11D6-8FF8-00022D09712B
Swap partition 516E7CB5-6ECF-11D6-8FF8-00022D09712B
Unix File System (UFS) partition 516E7CB6-6ECF-11D6-8FF8-00022D09712B
Vinum volume manager partition 516E7CB8-6ECF-11D6-8FF8-00022D09712B
Mac OS X Hierarchical File System (HFS+) partition 48465300-0000-11AA-AA11-00306543ECAC
Apple UFS 55465300-0000-11AA-AA11-00306543ECAC
Apple RAID partition 52414944-0000-11AA-AA11-00306543ECAC
Apple RAID partition, offline 52414944-5F4F-11AA-AA11-00306543ECAC
Apple Boot partition 426F6F74-0000-11AA-AA11-00306543ECAC
Apple Label 4C616265-6C00-11AA-AA11-00306543ECAC
Apple TV Recovery partition 5265636F-7665-11AA-AA11-00306543ECAC
Solaris Boot partition 6A82CB45-1DD2-11B2-99A6-080020736631
Root partition 6A85CF4D-1DD2-11B2-99A6-080020736631
Swap partition 6A87C46F-1DD2-11B2-99A6-080020736631
Backup partition 6A8B642B-1DD2-11B2-99A6-080020736631
/usr partition 6A898CC3-1DD2-11B2-99A6-080020736631
/var partition 6A8EF2E9-1DD2-11B2-99A6-080020736631
/home partition 6A90BA39-1DD2-11B2-99A6-080020736631
EFI_ALTSCTR 6A9283A5-1DD2-11B2-99A6-080020736631
Reserved partition 6A945A3B-1DD2-11B2-99A6-080020736631
6A9630D1-1DD2-11B2-99A6-080020736631
6A980767-1DD2-11B2-99A6-080020736631
6A96237F-1DD2-11B2-99A6-080020736631
6A8D2AC7-1DD2-11B2-99A6-080020736631

So if you want to create a new Linux swap partition that starts on sector 86130728, uses partition space #3, and whose size is 31063448 sectors, this is what you would do (assuming you had enough hard drive space):

# gpt add -b 86130728 -i 3 -s 31063448 -t \
0657FD6D-A4AB-43C4-84E5-0933C84B4F4F /dev/disk0

Print your partition table to see if it created successfully:

gpt show: /dev/disk0: Suspicious MBR at sector 0
      start       size  index  contents
          0          1         MBR
          1          1         Pri GPT header
          2         32         Pri GPT table
         34          6         
         40     409600      1  GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B
     409640   85721088      2  GPT part - 48465300-0000-11AA-AA11-00306543ECAC
   86130728   31063448      3  GPT part - 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
  117194176      16030         
  117210206         32         Sec GPT table
  117210238          1         
  117210239          1         Sec GPT header

Once you're finished editing your partition table, reboot by typing 'reboot' at the command line.

parted

As mentioned previously, parted comes in various GUI forms, as well as providing a command line interface and a developer library. In this article, only the command line version of parted is used.

It is important to know before using parted that it tends to be a little bit more forceful in the way it operates. As soon as you start modifying the partition table, it will remove any GPT/MBR hybrid table and change it into a purely GPT-based partition table. While this may be seen as a feature, it also makes parted unusable for certain tasks (such as a situation where all 4 primary partitions of a GPT/MBR table are used, and one simply wants to add a fifth partition to the GPT). Another thing worth noting is that all partition changes made in parted are live, so if you screw up, there's no safety net.

One final warning: parted reports disk and partition sizes larger than they actually are. The disk used in this example was actually 55.9 gigabytes, while parted reported it as 60 gigabytes. The partition sizes are similarly enlarged. This shouldn't cause any problems since all sizes are to scale, but if you need to work with actual sizes, run the command 'unit cyl' to set the default unit as cylinders. Then you can multiply the cylinder size to find out the actual size.

parted comes with many Linux installation disks. If yours doesn't, it is recommended to download a Gentoo Minimal CD from gentoo.org. To start parted from the command line, run the following command:

# parted /dev/sda

You should eventually get a prompt that looks like this:

(parted)

The first thing you should do is print out your partition table:

(parted) print
Disk geometry for /dev/sda: 0kb - 60GB
Disk label type: gpt
Number  Start   End     Size    File system  Name                  Flags
   1    20kB    210MB   210MB   fat32        EFI System Partition  boot
   2    210MB   44GB    44GB    hfs+         Apple_HFS_Untitled_1
   3    44GB    60GB    16GB    ext3

As you can see, there are three partitions on the disk. An EFI partition takes up the first 200 megabytes, while Mac OS X and Linux use up the remaining space. In this example, we're going to delete the Linux partition, and in its place create an ext3 and a Linux swap partition.

To delete a partition, we use the 'rm' command:

(parted) rm 3

Now we're going to create some partitions. To do this, we use the 'mkpart' command. Its syntax is as follows:
mkpart partition-type filesystem-type start end

The first partition we want to create is a new ext3 root partition. Looking back, we see that the OS X partition ended at the 44th gigabyte, so that is where this new partition is going to start. It's going to be 10 gigabytes (or what parted says is 10 gigabytes), which means it's going to end on the 54th gigabyte:

(parted) mkpart primary ext3 44gb 54gb

Now, let's create a 1 gb swap partition:

(parted) mkpart primary linux-swap 54gb 55gb

Finally, print the partition table to check that everything went okay:

(parted) print
Disk geometry for /dev/sda: 0kb - 60GB
Disk label type: gpt
Number  Start   End     Size    File system  Name                  Flags
1       20kB    210MB   210MB   fat32        EFI System Partition  boot
2       210MB   44GB    44GB    hfs+         Apple_HFS_Untitled_1
3       44GB    54GB    10GB    ext3
4       54GB    55GB    1000MB

Notice that parted doesn't print the filesystem type for the swap partition. This is because you haven't created a filesystem on it yet (the ext3 partition shows up because you previously had an ext3 partition that began there, which is where parted is reading the filesystem type from). To exit parted, use the 'quit' command:

(parted) quit
Information: Don't forget to update /etc/fstab, if necessary.

Bootloaders

An extremely invaluable boot utility for your Mac is rEFIt *(refit.sourceforge.net)*. It provides a pretty boot screen when you turn on your computer, and gives you the choice to boot between Mac OS X, Linux, or any other operating systems installed on your system. In addition, it provides 'gptsync', a utility you can use for creating or resyncing a GPT/MBR hybrid partition table. In fact, the only time you don't necessarily need rEFIt is if the distribution you've chosen meets both of the following criteria (for example, Ubuntu):

If you've installed GRUB to the MBR or you've installed LILO, you'll almost certainly need rEFIt to start it. Only neglect installing rEFIt if you're absolutely sure you won't need it, and installing rEFIt never hurt anyone.

As for actually installing the boot loader, it's fairly simple. If you're installing GRUB, it doesn't really matter where you install it (MBR executable code area or the boot sector of your Linux root partition). If you're installing LILO, it's highly recommended that you install it to the MBR, as it tends to work far better in this configuration.

The Linux kernel

The kernel that you choose plays a large role in the operation of the your operating system. For example, many people have reported tremendous speed gains from compiling their own kernel compared to the stock kernel that came with their distro (for example, Ubuntu). Here is a good kernel configuration for version 2.6.23-12 (it supports numerous things specific to Mac, for example, support for EFI booting, HFS+ drivers, intel framebuffer, and lots more):
http://www.tuxation.com/tutorials/linux-mac/kernel-config-2.6.23-12.txt

The next thing you probably want to do is install the mactel kernel patches, which make a few hardware-related things a little bit easier in Linux on a Mac. Make sure you have an svn client installed, then do something like the following (lines have been broken up for readability; you can put this all on one line if you remove the backslash first):

svn co https://mactel-linux.svn.sourceforge.net/svnroot/mactel-linux/trunk/kernel/\
mactel-patches-version mactel-patches-version

Replace version with the kernel version you want to compile (in the format 2.x.x -- patches aren't released for specific versions). Now apply the patches:

cd mactel-patches
./apply /usr/src/linux

You can use this with newer kernel versions as well. Follow these commands to correctly configure your kernel:

cd /usr/src/linux
wget http://www.tuxation.com/tutorials/linux-mac/kernel-config-2.6.23-12.txt
mv kernel-config-2.6.23-12.txt .config
make oldconfig

'make oldconfig' might ask you some questions about new kernel options, most of the time it's safe to say no to them unless they're hardware support advancements that specifically apply to Macs. Now run 'make menuconfig' to make some final changes before compiling the kernel.

Xorg

For Macs with the Intel integrated graphics card, you should use the xf86-video-intel driver for best results. While it's possible to use drivers specific to the cards (e.g. xf86-video-i810 for the Intel 810 serieis of cards), most users have reported more success using the intel drivers, as they tend to be more current. Also, the intel drivers can use the MacBook (Pro)'s native screen resolutions, eliminating the need for 915resolution. However, you can try both to see how it works.

There's not much to say about Macs that have dedicated video cards installed. Just follow the instructions on the manufacturer's website (NVIDIA, ATI) and they should work fine.

Touchpad

In most distros, the trackpad of the MacBook and MacBook Pro work fine out of the box (the default touchpad driver tends to be synaptics, which is fine). If it doesn't work for some reason, or you want more control over the behavior of your touchpad, make sure that you install the appletouch driver.

Airport

For Airport to work, you need the madwifi (http://madwifi.org/) drivers. Grab the source code from their site, either directly from HTTP, or for some more-recent Macs you may be required to grab the latest source code the SVN repository (download madiwifi-hal as opposed to madwifi-ng if you have trouble getting Airport discovered). You can also check your distro to see if they already offer precompiled madwifi kernel modules, which would save you the trouble of compiling it yourself.

You'll also need kernel headers if you don't already have the kernel source downloaded. First, check in /usr/src to see if there's a folder named 'linux' or 'kernel-xxx' or something similar. If not, you'll need to download kernel headers from your distro's package repository. You can find out the kernel version that you're currently using with uname -r.

Once you've downloaded the madwifi source code and the kernel headers, go to the terminal, change directories to wherever you downloaded the madwifi source, and type:

make

If it compiles successfully, you can install it with

make install

You can now load the driver into memory and start using your wireless card:

modprobe ath_pci
ifconfig ath0 up

Sharing files across the operating systems

Mounting HFS+ from Linux

One of the easiest ways to share files between Linux and Mac OS X is to mount OS X's HFS+ partition under Linux. The Linux kernel has fairly solid support for this filesystem, as long as you've compiled the HFS+ driver for it, and the filesystem you intend to mount has journaling turned off.

To turn off filesystem journaling from OS X:

sudo diskutil disableJournal /

You can then mount it in Linux like this:

mount -t hfsplus /dev/sda2 /mnt/osx

Replacing /dev/sda2 with the device that represents your OS X partition that you want to mount, and /mnt/linux with a suitable mount point.

If you want to create a shared HFS+ partition that both operating systems can use to store their userdata, see Creating a shared home partition between Linux and Mac OS X.

Mounting ext2/ext3 from Mac OS X

It's not recommended to use this method as it's very unreliable. An OS X port of the ext2fs drivers from BSD called ext2fsx is available, but the current stable version is only available for PowerPC. The development version is a universal binary, but it has known to crash the kernel quite often (particularly with repeated mounts and unmounts), and should only be used when absolutely necessary.

Using your EFI partition

By default, Mac OS X includes a 200 MB Fat32 EFI partition that does basically nothing, except occasionally store EFI updates when installing new firmware. This can come in handy when transferring small files, as both operating systems by default have full read/write support for this filesystem, and the drivers are very mature. On Mac OS X, you can do something like this at the terminal to mount the EFI partition. It should show up on your desktop or in the sidebar of open Finder windows: sudo mkdir /efi sudo mount -t msdos /dev/disk0s1 /efi On Linux, the commands are similar, however, these must be run with root access. Or prepend "sudo " (without the quotes) to each command:
mkdir /mnt/efi
mount -t vfat /dev/sda1 /mnt/efi

Audio

To get sound working on Linux, you need the Intel HD audio driver. If you used the kernel configuration above, this driver will be already built into the kernel, but if not, you'll need to reconfigure your kernel to include (and, if you don't have the source code, download it).

Once the driver is installed, all you need is ALSA and its OSS drivers (as the Intel HD Audio driver actually requires use of the OSS API), and you're set to go.

References