This page is a writeup about my experience in setting up Debian GNU/Linux on the MacBookPro8,2 (late 2011 edition), in pure EFI booting fashion.
While it certainly does not aim at being an exhaustive documentation on how to perform that, I'll be happy to receive feedback, corrections and tips to make the experience better for libre software enthusiasts using this very hardware.
I will try to update this page as I go. So, please, if you see something wrongly documented or know how to solve an issue or two, drop me a mail!
Bear in mind there's various versions of the MacBookPro8,2 2011 out there. Apart from different RAM/video options, the line was slightly refreshed end of October 2011. While this move seems to have mostly (if not exclusively) brought a speedbump for CPU, GPU & storage, there may be other differences, in hardware and/or firmware, that may lead to different results when trying to reproduce these steps on early 2011 MBP82 machines.
So, just so we're clear, the laptop I carried this install on is a late 2011 MacBookPro 15", with the following options :
I also switched the internal SATA2 500GB HDD (5400rpm, so slow) with a SATA3 240GB SSD (very fast), but that should not affect your ability to install. Due to the numerous problems that this series of machines has had to run SATA3 disks at full speed though, I feel it's important to mention that it works fine for me.
The laptop comes with MacOS X installed. I advise you not to get rid of it, for it is the only way to carry EFI & SMC firmware updates (which sometimes bring fixes & improvements).
Note: if you laptop shipped with OS X Lion like mine did, I advise you to create a USB Lion Recovery Disk Assistant.
Warning: if you're planning to use MacOS X on an external USB drive, for instance, in order to dedicate the internal disk to Debian only, you will be able to run MacOS X, but it won't allow EFI & SMC firmware updates to be carried, unfortunately.
Of course, MacOS X spans the entire disk by default, so we need to shrink its
partition. To do so, You can either use diskutil
from the command-line, or the
graphical Partition Manager which you'll find in Applications/Utilities
.
Because Intel Macs use modern GPT partitionning instead of the traditionnal DOS style partitionning, GPT fdisk is a tool of choice to partition the empty space. It is available both for GNU/Linux and MacOS X. However, I found that it wouldn't rename partitions under Lion, so I used it within the Ubuntu installer instead.
Intel Macs use a proprietary variant of UEFI, not BIOS, though they can be booted in BIOS emulation mode. The easiest solution to install GNU/Linux on these machines is to install using an CD or DVD (given EFI firmware restrictions on booting legacy USB devices). However, this proves to be very difficult to do when booting the MacBookPro8,2 in BIOS emulation mode, for the kernel fails to see the CD-ROM device after it booted. You can then mount a USB key containing the installer components, or... boot directly in EFI mode and setup a native EFI system, which is what I did and what I will document further.
Note that the late 2011 model is believed to be incapable of booting grub in BIOS emulation mode due to new firmware restrictions, and that EFI may be the only way to go. Here's some chat from the ##apple IRC channel on Freenode, on November 18th 2011. I sure can't confirm it's true, though I can testify that I've been unable to boot in BIOS emulation mode from a BIOS boot partition:
18:23 <Branes> Apple changed the UEFI structure with the newest MacBook Pro's and the latest
iMac refresh.
18:23 <Branes> As such, neither rEFIt nor grub (nor grub+) will work.
18:25 <Branes> The change is a little over five weeks old.
18:26 <Branes> Until the rEFIt people wake up and fix the limitation, it won't work at all
with the newest EFI firmware that's been shipping in all machines for just over
a month.
18:26 <Branes> rf you just bought it, then it has the new UEFI structure.
18:28 <Branes> Apple use 'Protected GPT' which is a dogs' breakfast.
18:30 <Branes> The main problem with pGPT is twofold: 1) no linux loader knows how to deal
with it, and 2) it is no better than MBR in that you are limited to four
partitions ... and Apple already use three, one for EFI, one for the main OSX volume,
and a third for the Recovery partition.
18:34 <Branes> Best be thankful, then, that you bought a new machine now, and not in four
months :)
18:35 <klausa> What will they change in 4 months ;)?
18:35 <Branes> klausa: They adopt the changes to UEFI proposed by Microsoft.
18:35 <Branes> Machines then will *only* be able to boot Mac OS X, iOS Desktop, or
Windows 7 -- the hardware will not aloow any other OS.
Some of that info is at least partially wrong, since I'm writing this from Debian on the previously mentionned laptop, which now has 6 GPT partitions, and I did install rEFIt with no issue, as far as EFI booting is concerned...
Anyways, since Debian has no support (yet) for EFI booting an installation media (to my knowledge), I used Ubuntu Oneiric's alternate installer, which is basically the Debian installer with a few things changed, like the ability to boot in EFI mode and provide the user with a familiar Debian-based environment.
Like I said, I'm not sure there's much choice on the specific MacBookPro model I'm talking about, but please prove me wrong (it's possible to boot in BIOS emulation from a CD, for instance, but you'll most probably need the kernel to be patched to see the CD drive).
In any case, there's benefits to booting in pure EFI over BIOS emulation:
There's some drawbacks too:
So, boot in EFI mode using Oneiric's alternate installer, configure the
basics (keyboard, lang, etc.) and when you reach partman, drop to a shell. I
then used gdisk
to create my partitions (/boot & another for dm-crypt /).
Luckily, it comes pre-installed on the alternate CD.
I carried the rest of the install manually, by using:
I won't go into details on how to install a system using the wonderful debootstrap, as it is documented elsewhere on the net. You can retrace most of my steps by reading the relevant sections of my previous tutorial on how to install Debian on a MacBookAir3,1. A few things have changed (partition alignment should now be automatic due to the use of more recent tools, as far as I know), but it mostly remains the same.
The two things you need to do to achieve a successful EFI booting before exiting the installer are:
As previously mentionned, the MBP82 has two GPUs:
If you want a laptop that doesn't have a fan blowing on a permanent basis, and whose battery lasts as long as possible, you'll want to disable the ATI card and use the intel IGD.
Unfortunately, it's not a piece of cake:
As a result, the only viable solution I found was to:
Or, you can do the contrary, and boot using the radeon driver. To do so properly, you will need a few more things:
you'll need to boot in BIOS emulation mode and dump useful bits of the memory so the GPU has access to them in EFI mode when there's no BIOS to ask such things; to do so, I booted in BIOS emulation mode using the same Ubuntu alternate installer, dropped to a shell as soon as possible (you can't get very far anyways, for the CD drive fails to be detected after booting), mounted my boot partition, and issued the following commands:
dd if=/dev/mem of=/boot/vbios.bin bs=65536 skip=12 count=1
dd if=/dev/mem of=/boot/int10.bin bs=4 skip=16 count=1
you'll need a radeon bios kernel patch that allows to load vbios.bin
from the kernel at bootup, in addition to some non-free firmware (which you can get through the firmware-linux-nonfree package in Debian);
/lib/firmware/radeon/TURKS*
files, as well as vbios.bin
which you will have copied to this location — into the kernel;There should be a third option, though I couldn't get it to work properly, that involves applying another patch on top of the two previously mentionned ones, enabling dynamic graphic switching using the vga_switcheroo mecanism. Please send some feedback about making that work if you managed to do so!
There's a very long thread on ubuntuforums which has a lot of different patches. It was quite hard to figure out which ones were still relevant by kernel 3.1.1 for the particular setup I was trying to achieve, but I've got it (mostly) right for me at least.
Since I want my laptop to be silent and have a long battery life, and don't care about 3D effects, the intel IGD is the perfect choice for me. So, from the alternate installer, after chrooting in my freshly installed system, I did the following:
ran make menuconfig
and only left the following graphical drivers (important: they need to be compiled in, not as modules):
CONFIG_DRM_I915=y
CONFIG_DRM_I915_KMS=y
compiled a kernel with
make-kpkg --initrd --jobs 8 --append_to_version +i915+lvds+bl kernel_image
dpkg
You will find my .config file and the patches which I updated against kernel 3.1.1 underneath the files directory.
Within the system's chroot and after having mounted /boot, install the grub-efi-amd64-bin package and do the following:
mount Apple's EFI partition in /boot/efi
:
mkdir /boot/efi
mount /dev/sda1 /boot/efi
create the relevant dir :
mkdir /boot/efi/EFI/BOOT
compile the grub EFI binary:
cd /usr/lib/grub/x86_64-efi/
grub-mkimage -O x86_64-efi -d . -o /boot/efi/EFI/BOOT/BOOTX64.EFI \
-p "" part_gpt part_msdos ntfs ntfscomp hfsplus fat ext2 normal \
chain boot configfile linux multiboot
copy the relevant files to the EFI partition:
cp *.mod *.lst /boot/efi/EFI/BOOT/
You now have a grub EFI binary (named BOOTX64.EFI so the Apple EFI
bootloader can see it - upon reboot press left alt to show the bootmenu) and
its modules, and you only lack a /boot/efi/EFI/BOOT/grub.cfg
configuration
file containing the following (to be adapted to your setup):
menuentry 'Debian GNU/Linux, with Linux 3.1.1' {
insmod gzio
insmod part_gpt
insmod ext2
set gfxpayload=keep
# Switch gmux to IGD
outb 0x728 1
outb 0x710 2
outb 0x740 2
# Power down ATI
outb 0x750 0
set root='(hd0,gpt5)'
echo 'Loading Linux 3.1.1...'
linux /vmlinuz-3.1.1+i915+lvds+bl root=/dev/mapper/system-root ro \
i915.lvds_channels=2 i915.modeset=1 i915.lvds_use_ssc=0 i915.i915_enable_rc6=1 \
acpi_backlight=vendor elevator=noop
echo 'Loading initial ramdisk ...'
initrd /initrd.img-3.1.1+i915+lvds+bl
}
Note: the important lines are the outb lines which switch the Intel card on and the ATI card off, as well as the options on the linux line:
Thanks to the apple_bl patch, it is possible to adjust the screen backlight by passing the use_gmux=1 option to the apple_bl driver. To make it permanent, create /etc/modprobe.d/apple_bl.conf
with the following contents:
options apple_bl use_gmux=1
Note you can add debug=1 if things don't work as they should and you'd like to try and figure out why.
You can then set the backlight with the xbacklight program, or by fiddling
directly with /sys/class/backlight/acpi_video0/brightness
.
I'd love to get pommed and the F1/F2 keys to work though, but I have had no success so far. Please share you recipes if it works for you!
Lits up when pommed starts, then shuts. Please contribute solutions. I see that in the logs:
[ 14.117009] Registered led device: smc::kbd_backlight
[...]
[ 22.356982] applesmc: light sensor data length set to 10
[ 36.577601] applesmc: ALV0: read data fail
Note that apart from lighting up my keyboard for a few minutes, that's the only visible thing pommed does, unfortunately.
No success using them to control backlights, sound, eject or any other thing. Any clue ?
You can get the normal Function keys to work without having to press Fn at the same time by issuing the following as root:
echo 2 > /sys/module/hid_apple/parameters/fnmode
This one is a bit of a mystery to me, but I finally got it to work by enabling... Wi-Fi (thanks to alvinwu from the gentoo forums who suggested that in the first place) ! In short, if you want Wi-Fi and the ability to read SD cards, chances are this will work out of the box for you, after having jumped through the Wi-Fi section below. If like me, you don't want Wi-Fi, read further.
Unless the bcma and b43 modules are compiled and loaded, IRQ17 is shut early in the process. Here's what the logs vomit on startup:
[ 20.627887] irq 17: nobody cared (try booting with the "irqpoll" option)
[ 20.627891] Pid: 0, comm: swapper Not tainted 3.1.1-patches #3
[ 20.627893] Call Trace:
[ 20.627895] <IRQ> [<ffffffff81084b0a>] ? __report_bad_irq+0x25/0xb5
[ 20.627904] [<ffffffff81084eda>] ? note_interrupt+0x170/0x1f2
[ 20.627907] [<ffffffff81083700>] ? handle_irq_event_percpu+0x163/0x182
[ 20.627911] [<ffffffff81007efd>] ? read_tsc+0x5/0x14
[ 20.627915] [<ffffffff8105a643>] ? timekeeping_get_ns+0xd/0x2a
[ 20.627917] [<ffffffff81083754>] ? handle_irq_event+0x35/0x55
[ 20.627921] [<ffffffff810603b1>] ? arch_local_irq_save+0x11/0x17
[ 20.627924] [<ffffffff810855c6>] ? handle_fasteoi_irq+0x7c/0x9e
[ 20.627927] [<ffffffff81003ea9>] ? handle_irq+0x1d/0x21
[ 20.627929] [<ffffffff81003bd9>] ? do_IRQ+0x42/0x98
[ 20.627933] [<ffffffff81363bae>] ? common_interrupt+0x6e/0x6e
[ 20.627934] <EOI> [<ffffffff810561ae>] ? enqueue_hrtimer+0x43/0x6a
[ 20.627942] [<ffffffff811c3124>] ? intel_idle+0xd5/0xfd
[ 20.627944] [<ffffffff811c3103>] ? intel_idle+0xb4/0xfd
[ 20.627948] [<ffffffff81295c8e>] ? cpuidle_idle_call+0xf0/0x175
[ 20.627951] [<ffffffff81001251>] ? cpu_idle+0x9d/0xe1
[ 20.627955] [<ffffffff816a5b39>] ? start_kernel+0x3be/0x3ca
[ 20.627958] [<ffffffff816a5140>] ? early_idt_handlers+0x140/0x140
[ 20.627962] [<ffffffff816a53a9>] ? x86_64_start_kernel+0x105/0x113
[ 20.627963] handlers:
[ 20.627969] [<ffffffffa0146727>] sdhci_irq
[ 20.627971] Disabling IRQ #17
When blacklisting b43 (I don't want wifi, sorry !), the mmc driver initializes as such:
[ 3.641398] sdhci-pci 0000:02:00.1: found 1 slot(s)
[ 3.641421] sdhci-pci 0000:02:00.1: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[ 3.641425] sdhci-pci 0000:02:00.1: Invalid iomem size. You may experience problems.
[ 3.641503] sdhci-pci 0000:02:00.1: setting latency timer to 64
[ 3.641508] sdhci [sdhci_add_host()]: mmc0: Auto-CMD23 available
[ 3.641527] mmc0: no vmmc regulator found
[ 3.641564] sdhci: =========== REGISTER DUMP (mmc0)===========
[ 3.641570] sdhci: Sys addr: 0x00000000 | Version: 0x00001502
[ 3.641576] sdhci: Blk size: 0x00000000 | Blk cnt: 0x00000000
[ 3.641582] sdhci: Argument: 0x00000000 | Trn mode: 0x00000000
[ 3.641588] sdhci: Present: 0x1ff80000 | Host ctl: 0x00000000
[ 3.641594] sdhci: Power: 0x00000000 | Blk gap: 0x00000000
[ 3.641600] sdhci: Wake-up: 0x00000000 | Clock: 0x00000000
[ 3.641606] sdhci: Timeout: 0x00000000 | Int stat: 0x00000000
[ 3.641612] sdhci: Int enab: 0x00ff0003 | Sig enab: 0x00ff0003
[ 3.641618] sdhci: AC12 err: 0x00000000 | Slot int: 0x00000000
[ 3.641624] sdhci: Caps: 0x176ec8b0 | Caps_1: 0x03002177
[ 3.641630] sdhci: Cmd: 0x00000000 | Max curr: 0x00000000
[ 3.641634] sdhci: Host ctl2: 0x00000000
[ 3.641640] sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x00000000
[ 3.641642] sdhci: ===========================================
[ 3.641672] Registered led device: mmc0::
[ 3.641723] mmc0: clock 0Hz busmode 1 powermode 0 cs 0 Vdd 0 width 0 timing 0
[ 3.641781] mmc0: SDHCI controller on PCI [0000:02:00.1] using ADMA
[ 3.641874] mmc0: mmc_rescan_try_freq: trying to init card at 400000 Hz
[ 3.641878] mmc0: clock 0Hz busmode 1 powermode 1 cs 0 Vdd 21 width 0 timing 0
[ 3.652705] mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0
But then disables IRQ17 and issues the previously mentionned output in the logs. Loading the b43 module and {un,re}loading the sdhci & sdhci_pci seems to do the trick.
Note: once b43 has been loaded, it can be safely unloaded for continued SD card operation. If you happen to be more clever and/or more patient than I am and feel like debugging further to get to the core of the problem, be my guest, as I'll be glad to know!
You need to install the following packages:
To enable suspend-to-ram, uncomment the following in
/etc/default/acpi-support
:
LID_SLEEP=true
...and make sure there's a file in /etc/pm/config.d/
with the following:
SLEEP_MODULE="uswsusp"
SUSPEND_MODULES="b43 bcma"
When the laptop suspends to RAM and then comes back from sleep, the discrete graphics (ATI) is awoken. We need to shut it down again so the intel display can take over. To do so, you just need to compile a little C program and have pm-utils call it upon each wakeup:
sudo -s
cd /root
cat > fixgpu.c << EOF
#include <stdio.h>
#include <sys/io.h>
#define PORT_SWITCH_DISPLAY 0x710
#define PORT_SWITCH_SELECT 0x728
#define PORT_SWITCH_DDC 0x740
#define PORT_DISCRETE_POWER 0x750
static int gmux_switch_to_igd()
{
outb(1, PORT_SWITCH_SELECT);
outb(2, PORT_SWITCH_DISPLAY);
outb(2, PORT_SWITCH_DDC);
return 0;
}
static void mbp_gpu_power(int state)
{
outb(state, PORT_DISCRETE_POWER);
}
int main(int argc, char **argv)
{
if (iopl(3) < 0) {
perror ("No IO permissions");
return 1;
}
mbp_gpu_power(0);
gmux_switch_to_igd();
return 0;
}
EOF
gcc -O2 -o /usr/local/sbin/fixgpu fixgpu.c
cat > /etc/pm/sleep.d/10-fixgpu << EOF
#!/bin/sh
#
# reset the IGD
case "${1}" in
hibernate|suspend)
;;
resume|thaw)
/usr/local/sbin/fixgpu
;;
esac
EOF
chmod a+x /etc/pm/sleep.d/10-fixgpu
Note: you need to make sure you have the vbetool package uninstalled, else it will eat 99% CPU resources and prevent your laptop from going back to sleep.
Works out of the box with the following section in /etc/X11/xorg.conf
:
Section "InputClass"
MatchIsTouchpad "true"
MatchProduct "bcm5974"
Identifier "Multitouch Touchpad"
Driver "multitouch"
MatchDevicePath "/dev/input/event*"
EndSection
For those who like the OS X Lion "natural scrolling", it is possible to emulate it with the synaptics driver (thanks to Sascha Teske for mentionning this to me). To do so, just issue the following:
xmodmap -e "pointer = 1 2 3 5 4 7 6 8 9 10 11 12"
If you like it, you can add the "pointer = ..."
argument to your
.xmodmaprc
. For details on how this works, please refer to the archwiki page
about Xmodmap.
Works out of the box when installing alsa.
Untested (please contribute).
Seems to work fine out of the box when EFI booting. Burning CD's works, but I fucked two CDs up before getting one properly burnt. I suspect one has to reduce the speed, for writing at top speed (and it is fast indeed) seems to not do things right. It seems like OS X caps writing speed, so emulating it seems wise.
I'll have to carry more tests to figure out the best combination. Feedback welcome.
Seems to work fine out of the box. Haven't made an extensive use of USB devices though.
Gigabit Ethernet works out of the box, using the tg3 driver.
Doesn't work out of the box. Not that I really care, but some people out there have made it work with passion. Well, I didn't care, until I realized I needed the working b43 module loaded to get my SD card reader work (see above).
So, to get Wi-Fi working, you need to patch your 3.0-3.1 kernel with some more
patches (quite a few, actually), enable BCMA in the kernel, and add firmware
to /lib/firmware/b43
. You'll find the patch I used against 3.1.1, as well as
the firmware binaries (which you should extract with b43-fwcutter, possibly
with some help from this bcm43xx reference page) in my files directory.
Note: I got the firmware from the walkthrough Baughn posted on ubuntuforums, as I couldn't be bothered to spend much time on this Wi-Fi thing. So I figured you may want to go down the easy firmware path too ;)
Linux 3.2rc3 (see this post) is supposed to bring out-of-the box support for the BCM4331 802.11a/b/g/n, but I haven't managed to get the intel display to work with it, unfortunately. Fixes highly welcome, for I don't intend to be stuck with kernel 3.1.x all my MBP82 life ! ;)
Untested. Modules are loaded, but I blacklisted them. Please contribute.
Please feel free to help with the following:
Please contribute corrections/remarks/tips/solutions (by mailing them to fluor at poivron dot org) and fuel the bugreports, be they on bugs.debian.org or elsewhere, so things go forward!
mike dentifrice, 2011/12/03