Installing Gentoo on a MacBookPro5,5

This describes the steps I used to install Gentoo Linux on my MacBook Pro 13” (early 2009 model). Common/normal install steps have been omitted; those unfamiliar with a standard Gentoo install should consult the Gentoo Handbook.

Contents:

  1. DMI Identification
  2. Device List
  3. Partitioning, Part I
  4. rEFIt
  5. Install Media
  6. Partitioning, Part II
  7. Gentoo Install
  8. Bootloader
  9. Kernel
  10. Video (works, needs patches)
  11. Keyboard Backlight (works)
  12. Touchpad (works)
  13. WiFi (works)
  14. Bluetooth (untested)
  15. iSight Camera (works)
  16. Sound (mostly works, needs patches)
  17. Suspend/Hibernate (works)
  18. Battery Life
  19. Miscellaneous
  20. BIOS Mode vs. EFI Mode

DMI Identification

My laptop has the DMI identifier “MacBookPro5,5”. To determine if yours matches, you can run the command (usually need to be root):

1dmidecode -t system | grep 'Product Name'

Device List

Additionally, here is the output of ‘lspci’ for comparison:

 100:00.0 Host bridge: nVidia Corporation Device 0a82 (rev b1)
 200:00.1 RAM memory: nVidia Corporation Device 0a88 (rev b1)
 300:03.0 ISA bridge: nVidia Corporation Device 0aae (rev b3)
 400:03.1 RAM memory: nVidia Corporation Device 0aa4 (rev b1)
 500:03.2 SMBus: nVidia Corporation Device 0aa2 (rev b1)
 600:03.3 RAM memory: nVidia Corporation Device 0a89 (rev b1)
 700:03.4 RAM memory: nVidia Corporation Device 0a98 (rev b1)
 800:03.5 Co-processor: nVidia Corporation Device 0aa3 (rev b1)
 900:04.0 USB Controller: nVidia Corporation Device 0aa5 (rev b1)
1000:04.1 USB Controller: nVidia Corporation Device 0aa6 (rev b1)
1100:06.0 USB Controller: nVidia Corporation Device 0aa7 (rev b1)
1200:06.1 USB Controller: nVidia Corporation Device 0aa9 (rev b1)
1300:08.0 Audio device: nVidia Corporation Device 0ac0 (rev b1)
1400:09.0 PCI bridge: nVidia Corporation Device 0aab (rev b1)
1500:0a.0 Ethernet controller: nVidia Corporation MCP79 Ethernet (rev b1)
1600:0b.0 IDE interface: nVidia Corporation Device 0ab5 (rev b1)
1700:10.0 PCI bridge: nVidia Corporation Device 0aa0 (rev b1)
1800:15.0 PCI bridge: nVidia Corporation Device 0ac6 (rev b1)
1900:16.0 PCI bridge: nVidia Corporation Device 0ac7 (rev b1)
2002:00.0 VGA compatible controller: nVidia Corporation Device 0863 (rev b1)
2103:00.0 Network controller: Broadcom Corporation BCM4322 802.11a/b/g/n Wireless LAN Controller (rev 01)
2204:00.0 FireWire (IEEE 1394): Agere Systems Device 5901 (rev 07)

Partitioning, Part I

Since I wanted to save the MacOS X partition to boot sometimes, I fired up Disk Utility to repartition. I was able to shrink the MacOS X HFS+ partition down to 60GB quite easily (and it did the resize live, without a reboot needed). I left the rest as unpartitioned space.

rEFIt

rEFIt provides a nice graphical EFI-based boot menu. I downloaded the MacOS X DMG installer, installed it, and rebooted. I was greeted with the boot menu, and selected MacOS X, which booted again just fine.

Install Media

At first, I tried the Gentoo amd64 minimal install CD (dated 20090618). Unfortunately, after booting I found that the keyboard didn’t work. Instead I downloaded an Ubuntu Jaunty x86_64 install CD, which booted fine. (You can boot from CD by holding down the “c” key after powering on the laptop.)

Partitioning, Part II

I fired up GParted (comes on the Ubuntu install disc) and set up some partitions on the free space. I ended up with (sizes are approximate):

  1. sda1: EFI partition (FAT32), 26MB
  2. sda2: MacOS X partition (HFS+), 60GB
  3. sda4: /boot (ext2), 96MB
  4. sda3: / (ext3), 45GB
  5. sda5: /home (ext3), 120GB
  6. sda7: swap, 4GB
  7. sda6: /mnt/shared (HFS+), 1GB

Note that some of those partitions are out of order. I actually ended up revising my partition layout a couple times later, and the numbers got out of sync. It doesn’t really matter even though it looks a little ugly.

Since we are booting using legacy BIOS mode (more on that later), the partition containing the Linux kernel must be on one of the first four primary partitions. You cannot have any Extended/Logical partitions because the GPT format doesn’t support them (instead, you can just have a bunch of primary partitions).

The partition layout is somewhat arbitrary. You could just partition the entire rest of your free space as one big root partition. If you don’t care about hibernate support, you can probably leave out the swap partition (in favor of a small swap file on the root partition for RAM emergencies). I created a small partition using unjournaled HFS+ (the unjournaled bit is important) for transferring files easier between MacOS X and Linux; in practice I found I really don’t need it.

At this point, to be safe, it’s probably a good idea to reboot after saving the partition layout and use the “GPT/MBR sync” tool in rEFIt’s boot menu. You may not have to do this, but it’s good to make sure, or GRUB will be unable to find your /boot partition later. Afterward, boot back to the Ubuntu install CD.

Gentoo Install

At this point it’s time to break out the Gentoo Handbook and follow the steps you’d usually follow to install a Gentoo system. You can get yourself a root shell using ‘sudo’, and create mount points for your new Gentoo system in /mnt.

Bootloader

I used “legacy” GRUB (not GRUB2) to boot in BIOS mode. I installed GRUB to the boot block of my /boot partition. After this is done, upon boot you’ll see a penguin icon in rEFIt that will allow you to boot GRUB. GRUB, in turn, will be used to load the Linux kernel. Linux is GPT-aware (GRUB is not), so it will be able to see past the fourth partition on the drive. My /boot/grub/grub.conf looks like this:

1default 0
2timeout 3
3title Gentoo Linux 2.6.31-rc4
4    root (hd0,3)
5    kernel /boot/vmlinuz-2.6.31-rc4 root=/dev/sda3 ro resume=/dev/sda7 video=uvesafb:1280x800-32,mtrr:3,ywrap usbcore.autosuspend=1

You’ll of course want to modify the root partiton and kernel file names to suit your setup. If you’ve omitted a swap partition, you’ll want to leave out the resume= parameter.

Kernel

I started off with gentoo-sources-2.6.30-r1. I was able to boot with that, and most things worked. Currently I’m using 2.6.31-rc4 from Takashi Iwai’s sound-2.6 git tree. See below for more about sound. My current kernel config is here. I’m using the uvesafb framebuffer driver, which works great. (It requires some user-space setup, so you’ll want to follow the directions at the URL above.)

Video

I installed nvidia-drivers-180.60. For 2.6.31, it requires this patch. I attempted to half-upstream the patch to Gentoo, but it was rejected due to a non-support policy for pre-release kernels. This is somewhat stupid, since the same patch will have to go in after 2.6.31 is released. Oh well. That’s Gentoo for you.

I created a minimal /etc/X11/xorg.conf file to select “nvidia” as the driver, and let the X server autoc-config the rest. It appears to work fine; came up the first time at 1280x800 automatically. I didn’t test the external monitor support, as I don’t have any DisplayPort devices, and I didn’t buy the DVI adapter. You can emerge nvidia-settings for a GUI that will set up some other parameters for the card.

The display backlight requires the mbp_nvidia_bl kernel driver. Unfortunately it doesn’t work out of the box because our new model string doesn’t match. Also, the nvidia proprietary driver disables the method it uses to set brightness while X is running. My kernel patch fixes that, but in a potentially unsafe way. It works ok for me, but it’s possible that it could cause crashes, lockups, or other weird behavior.

Keyboard Backlight

The keyboard illumination works with the applesmc kernel driver. It creates an LED class device. The machine’s light sensor is also exposed, though it seems to behave a little differently than it does in MacOS X. You’ll want to emerge pommed to get a daemon that will manage that for you and dynamically control the keyboard brightness. As of version 1.26, our model isn’t supported, but 1.27 will/does have support.

However, pommed is very battery-unfriendly, waking up every 200ms to check various things. This patch reduces the frequency of those timeouts to once every 2 seconds with minimal loss of functionality (there’s at most a 2-second lag before the keyboard backlight will react to a change in ambient light, which I think is no big deal).

Touchpad

The touchpad works fine with the bcm5974 kernel driver and xf86-input-synaptics X.org driver. A recent version of hal-info is required so HAL will properly advertize the device as supported by the synaptics driver. I have a custom fdi file for HAL that sets some default options. I set it up so left click is a single press, right click is a press with two fingers, and middle click is a press with three fingers. Unfortunately multi-touch/multi-finger support in synaptics is pretty rudimentary. I filed a feature request, but it looks like it might be a while before the situation is improved. Palm detection also appears to be broken (as of 1.1.2).

WiFi

The wireless card works, but unfortunately not with the open source b43 kernel driver, as that driver does not yet support 802.11n chipsets. Broadcom provides a closed-source proprietary driver which seems to work. In Gentoo you can simply emerge broadcom-sta. Performance feels poorer than with MacOS X, and it takes a while to find 5GHz APs sometimes (on the order of several minutes). NetworkManager seems to handle the interface fine.

Compiling the driver against 2.6.31 didn’t work at first; I cooked up a patch to fix that, but it’s been accepted into Gentoo’s tree. (Apparently some Gentoo maintainers are more reasonable than others.)

One oddity: selecting CONFIG_LIB80211 in the kernel does not seem to be enough; none of the lib80211 crypto modules get built, which is required for WEP and WPA support. I worked around this by also selecting CONFIG_HOSTAP, which causes the crpyto modules to be built as well.

Bluetooth

The chipset is recognized and supported with the btusb kernel driver. I haven’t tested this yet due to userspace software issues.

iSight Camera

The iSight works just fine with the uvcvideo kernel driver. On this laptop, extracted firmware files seem not to be required. Sometimes the driver fails to load properly, complaining about not finding a “video chain,” but removing and reloading the driver usually fixes it.

Sound

While Apple is using the “standard” Intel HD-Audio interface on this model, they decided to use a codec chip (Cirrus Logic CS4206) that didn’t previously have any support in the ALSA driver. Fortunately, one was written in short order. The driver is available in Takashi Iwai’s sound-2.6 git tree. It’s scheduled to be merged with mainline for 2.6.32. Currently the main speakers and headphones work. I was unable to get the microphone to work with Skype or Audacity, however.

Suspend/Hibernate

Suspend works out of the box using pm-utils. I have not yet tested hibernate.

Battery Life

Battery life is ok running Linux, but nowhere near as good as while running MacOS X. Linux gives me at best 3-4 hours (with backlight dimmed and WiFi turned on), but with MacOS X I can usually hit around 7 hours (also BL dimmed, WiFi on). I’m using the “ondemand” CPU frequency scaling governor, which keeps the CPU running at 798MHz most of the time.

PowerTOP indicates some kernel core and kernel IPI wakeups, as well as some interrupts firing. Killing Firefox when you’re not using it also helps. Even then, a <kernel core> item wakes up the CPU anywhere between 130 and 250 times per second, in hrtimer_start_range_ns(), and <kernel ipi> is resonsible for around 50 wakeups per second, “Rescheduling interrupts.” Presumably this is something that can be worked on by the kernel developers, but I don’t have the time to report and track problems. Even with all these wakeups, the CPU manages to stay in C4 a good 93% of the time.

Miscellaneous

Shutdown and reboot don’t quite work. According to Benjamin Herrenschmidt, Apple implemented it poorly in BIOS mode. If the CPU is throttled down to its lowest speed, most of the time it will work (the proper procedure relies on a small delay between two PCI writes; the delay is too short when the CPU is at full speed). I’m told it will be natively supported properly in a future kernel version (I’d guess 2.6.32, possibly .33). If you just suspend and resume all the time like I do and never shut down, this isn’t a problem.

USB works fine for mass storage devices, at least. The SD card reader appears to the system as a USB device and works as well.

The firewire drivers load and detect the chipset properly (I used the kernel’s “new” firewire stack). I haven’t tested it due to lack of devices.

The laptop has an accelerometer (aka Apple Motion Sensor). It appears to work, and you can read the laptop’s orientation as an (x,y,z) triplet via a file in /sys, but I’m not sure if there’s any software that does anything cool with this.

Addendum: BIOS Mode vs. EFI Mode

The above install procedure uses legacy BIOS mode to boot the machine. Apple was kind enough to include BIOS emulation for those of us who want to run alternative OSes. It’s not perfect (note the shutdown/reboot bug above), but it’s done very well. It feels “wrong” in a geek-purist sort of way, so I did try later to boot via EFI.

However, my experience was… less than stellar. Neither GRUB2 nor elilo seem to work very well. The SVN versions I tried were very buggy (in ways unrelated to their EFI support) and are poorly-documented.

In addition, there’s some doubt as to whether or not things will work properly in EFI mode. The nvidia proprietary driver allegedly requires access to the video BIOS, which isn’t present in BIOS mode. The nouveau driver could theoretically be taught how to find the VBIOS even when booted in EFI mode, but this hasn’t been done yet. I’m told the nv driver doesn’t support the 9600M chipset (though this may be incorrect). GRUB2 has a module that allows loading BIOS images during EFI boot, and includes a tool to dump the video BIOS, but I’m not sure if it works.

So for now I think I’ll stick with BIOS mode. Pretty much everything works, and the stuff that doesn’t should be working in short order.