I have been using Linux as my primary desktop environment for a long time. It can be impractical, annoying, even infuriating. But it’s still my favorite operating system, and over the years I have grown accustom to its quirks and shortcomings. I also suffer from an occasional obsessive disorder with regards to problem solving. Specifically trivial, unimportant problems. Such was the case two weeks ago when I decided to ditch a virtual Linux environment running in Mac OS for a native Linux install.
Don’t get me wrong, running Linux using a virtual environment like Parallels is a pleasant and pretty smooth experience. I felt however that it should be snappier, should run faster on the super slick Mac hardware, so I innocently decided to dual-boot the machine and compare a native Linux install to what Parallels provides. It took a wee bit longer than I hoped to get things working as well as I wanted, but I’m happy to say the effort has been worth while. Here is a summary of things learned so far running Linux on a Macbook Pro 10,1. For the most part these are not distro specific, and I’m not using any high level configuration tools from a desktop environment like Gnome or KDE.
There are plenty of how-tos out there to get the installation bits figured out. I’m a Debian man myself, so I found this particular post a useful jumping off point. The tips with regards to rEFInd and getting the wireless card to work during the installation process where very useful, and within an hour or two I had a bootable Debian Sid/Unstable setup, without any breakage to Mac OS.
In my experience laptops running Linux tend to run hot, and this Macbook is no exception. Before tweaking a few things it was consistently 10 C degrees warmer than in Mac OS, and would quickly raise to out-of-control hot when doing any CPU intensive work (I triggered CPU temp throttling with a make -j8 in less than a minute). I tried a number of things to reduce the temperature and managed to find two that help bring things back into Mac OS comparable levels. First is to use the Intel Pstate kernel driver for CPU scaling. The only tweaking required is to disable CPU “turbo” mode as the driver is IMHO too liberal with frequency ranges over the normal non-turbo maximum. This eliminates conditions spiraling to dangerous levels when all the cores are pegged. Secondly I’m running a simple Bash script from root’s crontab every minute that does a core temp evaluation and adjusts the minimum fan speed if required. This brings down the average idle temp with negligible additional fan noise. This requires the standard kernel coretemp driver as well as the applesmc kernel module.
To date the best estimated battery life value I have seen under Linux is 5 hours (I have not run an actual timed test yet) as compared to 7.5 in Mac OS. After some acpid rules fiddling I managed to scale the CPU to 75% of max and dim the display significantly when the power is unplugged. Both can be independently restored of course, but this goes a long way toward getting the most out of the battery. The powertop app has also been useful to identify devices that are not taking advantage of available power savings modes, though I can’t say for sure how much power savings they provide.
This Macbook has a Broadcom BCM4331 wireless adapter. The b43 kernel driver is the only one that recognizes the hardware, but it’s been hit or miss in the stability department (regardless of power saving mode). Some days are solid, some days are laden with network drops. I’m still working the issue and so far the 3.10.7 kernel seems more reliable than the stock Debian kernel, albeit with limited testing. In the meantime I stuck a tiny Panda Wireless USB card in, built the kernel module, and with the exception of some excessive but seemingly harmless logging, everything has been stable since.
- Retina Display
The Retina display is incredible. 2880×1800 pixels packed into a slim bright package. With the apple_gmux kernel driver the brightness is controllable, both from the function keys (using xbindkeys) or when changing from battery to plugged in (using acpid). Everything is really tiny at this res, so adjusting font sizes where possible is a must. I ended up modifying the defaults for my terminal (Mrxvt) and window manager (FVWM), as well as for QT and GTK. This pretty much does the trick for everything I use with the exception of bumping the default zoom level in Chromium.
The mtrack Xorg input module works well with the multi-touch device. I added a few bindings into the xorg.conf file to set up some click and tap combos, and so far it’s working well. I’m not a big trackpad fan but I have to admit this one is slick. I’m laughably clumsy with it but I’m getting better.
- Function Keys
Using xev I was able to identify the keycodes for the function keys and bind them to actions with xbindkeys. Brightness and keyboard back-lights are controlled via simple Bash scripts that manipulate /sys entries directly, and the volume controls use amixer. I have not mapped the remaining keys to anything yet.
This works quite a bit better than I expected (with nothing but kernel support and standard power management related packages). The only issue so far is that the network needs to be reset after a resume. I have not put any effort into automating this yet but plan to look into it soon. Acpid makes it trivial to trigger suspend on a lid close which is pretty handy (though sometimes annoying).
I’m using the Nouveau kernel driver to power the display on the Nvidia GeForce GT 650M. There is an alternate Intel i915 GPU but I have not tried to activate it yet. I did build modular support for it in the kernel, and I enabled options to allow switching between graphic devices. The Nvidia GPU continues to work fine with the Intel drivers enabled which is better than the last time I tried to run multiple kernel drivers for different GPU vendors simultaneously. Hardware 3D works and the frame rates are what you would expect from a mobile GPU.
- Hard drive
This rig has a peppy 251Gb Apple SSD (SM26E). Works great with the standard SATA kernel drivers. I have not run any specific benchmarks, but I’m sort of new to using SSDs and they all seem so fast I could be completely unoptimized and still loving the performance.
No issues here. I’m using the standard UHCI, OHCI, XHCI kernel modules to support USB interfaces. Everything I have plugged into a USB port has worked perfectly so far.
The Intel HDA ALSA audio driver works with no tweaking. The volume gets pretty loud for a laptop which is nice. Plugging in headphones correctly mutes speaker output and work fine. Overall the sound quality is better than I thought it would be.
The webcam is an Apple “FaceTime” HD Camera that is connected internally using USB. Tested with mplayer, it works without issue using the kernel’s generic uvcvideo driver.
- Card Reader
This is a Broadcom Corporation NetXtreme BCM57765 Memory Card Reader. The MMC drivers spit out a non fatal hardware interrupt warning when I insert a card and then nothing happens. In all fairness though it might be a bad 😄 card. I could only find one to test with and it’s ancient.
Here is a shot of my very fancy not old-fashioned at all looking new Macbook Pro Linux desktop (click for full res).
And here are some of the scripts and configs referenced above in case anybody finds them useful:
- Bash script run from root’s crontab every minute to bump up the CPU fan speed
- Bash scripts that control the keyboard back-light level
- Bash scripts that control the screen brightness level
- Example of xbindkeys configuration for the keyboard FN buttons
- xorg.conf file to define the video device and trackpad settings
- Recommended power savings adjustments produced by powertop
- Example of tweaking the Intel CPU scaling Pstate driver
- Linux 3.10.7 minimal Macbook Pro kernel configuration
- Linux 3.11-rc5 minimal Macbook Pro kernel configuration