Google TV and Native Libraries

  • October 5, 2012
  • Brian Tarricone

The Google TV runs a fairly unusual flavor of Android (at least the 2nd-gen ARM-based devices). I have a Sony Internet Player (not the Blu-Ray version), so what I’m about to write applies to that device, but maybe not any other, though it stands to reason that the other ARM-based GTVs are the same.

Phone-and-tablet Android doesn’t look much like a Linux desktop or server system. It uses the Linux kernel, to be sure, but a lot of the userspace libraries are custom. It even does not use Glibc, but a C library that Google wrote called Bionic. It’s fairly stripped down and lightweight, and while it implements most things you might need out of a standard libc, it does not pretend to be POSIX compliant.

Due to this, a Native Development Kit (NDK) is not yet available for the GTV. So the question remains: can we hack one together that works? The answer is… sorta.

From some simple investigation, I’ve learned that the Sony GTV is running a EGlibc 2.12.2, and probably a mostly-unmodified version of it. Someone with an @google.com email address stated that the reason for this was that they couldn’t get Chrome running against the Honeycomb version of Bionic.

With this knowledge in hand, I built a relatively standard arm-linux-gnueabi toolchain using crosstool-ng. Then I ‘adb pull’-ed the contents of /system/lib from my GTV and merged them with the new toolchain’s sysroot, copied some headers out of a stock NDK, and ended up with a sysroot that approximates what you’d find in platforms/ in a stock NDK, just without Bionic, and with EGlibc.

I didn’t get to modifying the NDK’s build system (it would need to be changed to find the new toolchain), so I built my native library manually, and got a simple “hello world” type app with a native lib. (It just calls a native method that returns a string, and displays the string on a label.)

One annoying thing is that the ABI string in the Sony GTV is set to “none”, so you have to unpack the APK, rename lib/armeabi-v7a/ to lib/none/, and repack and resign it. All of this means that this would be strictly hobbyist for now: no chance that you could distribute something in the Play Store. Not only does Google have to release an officially-working NDK, but they need to decide on an ABI string, and get Sony (etc.) to push updates out to their customers that update build.prop on the devices with the new ABI string.

There’s also the possibility that Google doesn’t want to create and officially support that much native drift between phone-and-tablet Android and GTV Android, and will wait until manufacturers are running a more-stock Android 4.x on GTV (that uses the 4.x version of Bionic) before releasing an NDK that works… in which case we’re at the mercy of Sony for updates, unless XDA or CyanogenMod wants to take a crack at it. My money’s on this scenario, unfortunately.

One of the main things people have been screaming for is a version of XBMC that runs on GTV. I have been able to get it to build using my hacked-together toolchain, but not actually to run. I ran into problems with runtime linking: the built binaries depend on a shared libstdc++ and libgcc_s, neither of which appear to be included on the GTV’s filesystem. I tried including them in the APK, but, weirdly, when the GTV unpacks the native libs from the APK at install time, it discards those two libraries. Static linking of those two may not be possible since XBMC’s APK includes a bunch of native libs. A possible solution would be to build all of libxbmc.so’s dependencies as static libs, and then just make one big static library.

But I haven’t had time to work on this over the past couple weeks…

Techie TODO

  • April 16, 2012
  • Brian Tarricone

In no particular order.

  • Start blogging again.
  • Suck less at Javascript, even if it’s a shitty language.
  • Learn jQuery, even if it’s just a library to make a shitty language less shitty.
  • Learn Rails properly.
  • Get back into open source dev.
  • Find a project/idea I can potentially monetize, and build and launch it.
  • Throw out my website entirely and start from scratch.
  • Stop running MacOSX all the time on my laptop and get back to using Linux as my primary desktop OS.

How To Save Artwork from Weavesilk.com

  • January 25, 2011
  • Brian Tarricone

I just discovered weavesilk.com, which I think is pretty cool. However, it looks like they don’t give you a way to save your generated artwork. If you’re running Google Chrome (or, as I am, Chromium), there’s a trick you can use to save what you’ve created. This can probably be done with Firefox using Firebug, and maybe in some other ways, but here’s how I do it with Chromium.

  1. Create your artwork by dragging around.
  2. Right-click somewhere on the page and select “Inspect Element.”
  3. In the new browser pane that comes up, click to the “Console” tab and enter the following:
    canvas = document.getElementById('render')
    img = document.createElement('img');
    img.src = canvas.toDataURL()
  4. The browser will probably freeze for a few seconds (or more than a few), and your CPU usage will shoot up. Be patient.
  5. Click to the “Resources” tab in the developer pane, and look in the list for something that starts with “data:image/png”. Click it, and you should see your artwork to the right, on a transparent checkerboard background.
  6. Right-click the image and select “Save Image As.”

The image will save with a transparent background, but you can open it up in an image editor and add a solid background color if you like.

Gentoo Linux on an 11? MacBook Air (October 2010)

  • December 6, 2010
  • Brian Tarricone

I just posted a page detailing my experience installing Gentoo on one of the new MacBook Air models (in my case the MacBookAir3,1 with 1.6GHz CPU, 128GB SSD, and 4GB RAM). Hopefully it’ll be useful for others.

Amazon MP3 Downloader on 64bit Gentoo Linux

  • December 26, 2009
  • Brian Tarricone

(This is going to be a bit of a narrative. If you’re impatient, scroll to the “How-To” section at the bottom of the post.)

Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the whole album vs. downloading each individual song. So click through, and find that it requires the Amazon Download Manager thingo.

Lame, I think. I click the download link, and it actually gives me some buttons to choose from that have to do with Linux. Huh. Nice work. However, I assume it’s closed-source proprietary crap. But hey, why not give it a try.

My choices are two .deb files, one for Ubuntu Jaunty, and one for Debian 5, or two .rpm files, one for Fedora 11, and one for OpenSuse somethingorother.

So I grab the Ubuntu one. I’m on Gentoo, so I “emerge dpkg”, and then run “dpkg -x amazonmp3.deb .” in an empty directory. I look in usr/bin that it created, and find a binary. But it’s a 32bit binary.


I run ‘ldd’ on it, and of course it needs gtk and a bunch of other stuff that I don’t have 32bit libraries for. Like boost.

So I think, ok, I can install a 32bit chroot. So I download the stage3 Gentoo i686 tarball and unpack it in /opt/gentoo32. I also “emerge schroot” in my regular system, and set that up. I recently found schroot while using Ubuntu at work. It’s awesome. Eventually the stage3 tarball finishes up, so I schroot into my new 32bit environment and “emerge libboost”. After it’s finished, I note a problem. Amazon’s binary is expecting some weird version of boost that has “gcc42″ in the filename. Also, I just installed boost 1.35, and it wants 1.34. Out of desperation, I try to make symlinks to the correct file names, assuming it probably won’t work. I was right: it doesn’t work. Balls.

Then I think… well, why not install a chroot of 32bit Ubuntu Jaunty? I “emerge debootstrap” and pray… yep, it’s in portage, excellent. I install it, schroot into it, and apt-get a bunch of the libboost packages, and… holy crap, it works.


Here’s a step-by-step. This is for Gentoo, but it should work equally well on any system where you can install debootstrap and chroot. The following instructions assume you’ve installed them already.

As root on the “main” system:

# mkdir -p /opt/ubuntu-jaunty-32
# debootstrap --arch i386 jaunty /opt/ubuntu-jaunty-32 http://archive.ubuntu.com/ubuntu/
# cat >/etc/schroot/chroot.d/jaunty32.conf
description=Ubuntu Jaunty (32-bit)
[hit ctrl+d]
# cat >/etc/schroot/mount-defaults
/proc		/proc		none	rw,bind 	0	0
/proc/bus/usb	/proc/bus/usb	none	rw,bind		0	0
/sys		/sys		none    rw,bind		0	0
/dev		/dev		none	rw,bind		0	0
/dev/pts	/dev/pts	none	rw,bind		0	0
/dev/shm	/dev/shm	none	rw,bind		0	0
/home		/home		none	rw,bind		0	0
/tmp		/tmp		none	rw,bind		0	0
/var/run/dbus	/var/run/dbus	none	rw,bind		0	0
/usr/portage	/usr/portage	none	rw,bind		0	0
[hit ctrl+d]
# schroot -c jaunty
(32bit)# groupadd -r staff
(32bit)# apt-get update
(32bit)# apt-get install sudo curl libglademm-2.4-1c2a xdg-utils libboost-date-time1.34.1 libboost-filesystem1.34.1 libboost-iostreams1.34.1 libboost-regex1.34.1 libboost-signals1.34.1 libboost-thread1.34.1
(32bit)# dpkg -i $DOWNLOAD_DIR/amazonmp3.deb

Note that I didn’t just type all this verbatim… this was just my memory of what I did. So if something’s missing, please leave a note in the comments and I’ll update this.

Next you can try running “amazonmp3″ to test it. If that works, you can go back out to your “real” system (just type “exit” in that shell), and do this:

# mkdir -p /usr/local/bin
# cat >/usr/local/bin/amazonmp3
schroot -c jaunty -p /usr/bin/amazonmp3 -- "$@"
[hit ctrl+d]
# chmod +x amazonmp3

This creates a script in your “real” system that will chain to the 32bit amazonmp3 binary in your Jaunty chroot. You can set up your browser of choice to automatically launch this script when you download .amz files. At this point you can try running “amazonmp3″ from your “real” system (outside the chroot) and see if that works.

There are also a few other things:

  1. If you are running a system that uses GDM to log in, you may need to add /var/run/gdm to the bind mounts in the mount-defaults file or else apps started in your chroot won’t be able to connect to your X server.
  2. If you’re using non-default gtk2 theme engines on your “real” desktop”, you’ll need to install them in the chroot (via apt-get) as well. Well, ok, you don’t have to, but if you don’t, the Amazon app will look uglier than it should.
  3. Remember to always pass the “-p” option to schroot. If you don’t, the environment in the chroot will get reset, which means you’ll lose your DISPLAY env var, and you won’t be able to connect to the X server without manually setting it.
  4. When I first ran the apt-get command in the chroot, I got some weird errors at the end of the process about some packages not being configured because another package (gtk, I think) that it depended on hadn’t been configured yet. Just running the same apt-get command a couple times fixed it, strangely.
  5. Make sure your “real” system has /usr/local/bin in the PATH.

Anyhow, that’s it. Works like a charm.

Code Comments

  • August 18, 2009
  • Brian Tarricone

I’m a bit of a minimalist when it comes to commenting my code. This is probably in some ways a bad thing; code that is completely obvious to me in its function may be difficult to understand for others, and I’m often not so great at realizing this on the first pass.

So that leads me to the purpose of code comments:

The purpose of commenting your code is to inform readers of that code what a section of nontrivial or non-obvious code does.

At least, this is my definition. Opinions differ, I’m sure. I might also add to that a clarification: “readers” in this case may include yourself. Code you wrote may even be incomprehensible to you if a decent amount of time has passed.

From this definition you can also infer something else, that I believe it’s unnecessary to comment obvious code. In fact, I’d argue that it’s harmful to comment obvious code, because you’re making it harder to follow, and you’re adding a barrier in front of the reader being easily able to distinguish between trivial and nontrivial code at a glance. You also increase the length of the code fragment, which may make it more difficult to read and understand in its entirety (if you can’t fit the entire fragment on one screen, you’ll have to scroll back and forth to see the entire thing).

However, too often — very often, it turns out — I see things like the following:

/* take a reference */
/* free string */

And one of my favorites:

/* set the label text to "Time Left:" */
gtk_label_set_text(GTK_LABEL(label), "Time Left:");

(Yes, I actually have seen something very similar to that, though I don’t remember what the label text was.)

How do these comments actually add anything useful to the file? Every time I see one of these, a little part of me dies inside.

Now, the last one is just silly. Even someone who has never developed using the gtk+ UI toolkit can figure out what that line of code does without the comment. If you can’t, then a code comment there probably isn’t going to be enough to help you overall in any case.

The middle one is equally silly, though it’s understandable that someone might not know that g_free() is the glib equivalent of free(). However, consider your audience: is an extra line of code for a comment really useful here?

The first one is not quite so easy for me to dismiss. It presupposes a few bits of knowledge:

  1. Understanding of what reference-counted memory management is.
  2. Familiarity with the “ref/unref” pair, as opposed to only being exposed to something like the OpenStep “retain/release” (or even the COM/XPCOM “AddRef/Release”) terminology
  3. At least passing knowledge of what a GObject is

Now, for code that makes heavy use of reference counting, I think presupposing #1 is not unreasonable. In this case, it doesn’t matter: the comment as presented will not help you if you don’t know what reference counting is.

Points #2 and #3 depend on your goals and potential audience. If you think that a decent number of readers may not be familiar with the “ref/unref” terminology, “take a reference” is probably enough to generate an “oh, duh!” moment in the reader’s head. As for #3, unless you intend your code to be able to act as a sort of GObject tutorial, that is, something that people aspiring to learn GObject programming might want to read, I think the comment there does not serve people unfamiliar with GObject. Regardless, most GObject-using code will probably be pretty confusing to someone who doesn’t know GObject, so whether or not you should comment g_object_ref() is going to be the least of your worries.

Now, I’m not going to claim that my code commenting is perfect… far from it. I could certainly stand to sprinkle comments a bit more liberally throughout my code. I tend to only comment public API (and then just a description of what the function does, not how it does it), and code fragments that are really nontrivial[1] and potentially hard to understand.

But there has to be a happy medium somewhere. While too-infrequent commenting can certainly make code harder to understand, I’d argue that too-frequent commenting is worse. It’s sorta like “the boy who cried wolf” in the sense that comments draw my eyes to them as a way of saying, “pay attention! This bit here is important!” (or tricky, or whatever). Overuse of comments just makes me start skipping over all of them, useful or otherwise.

[1] It’s worth noting here that this point further reduces my volume of comments. I generally prefer clear code over neat hacks, even if the neat hack represents a reduction in lines of code or a moderate increase in performance. If I write a section of code and then look at it again and see that it looks too complex, I’ll usually try to immediately rewrite it to be simpler.

New Laptop (aka Gentoo On MacBook Pro 5,5)

  • July 6, 2009
  • Brian Tarricone

NB: I’ve cleaned up this guide and moved it, and I’ll continue to update it there. This blog post will not get any more updates.

Those of you who have chatted with me over the past… er… 18 months or so… know I’ve been wanting a new laptop for a while. Those of you who have chatted with me over the past 6 months know that I’d settled on a 13″ MacBook, but I wanted to wait until Apple’s next refresh/update before making the purchase.

Apple updated their laptop line at WWDC in June 2009, and I was pretty much perfectly sold on the 13″ MacBook Pro (one of the “updates” was to rebrand the 13″ aluminum unibody MacBooks as Pro models).

I was in Maryland for a wedding, and decided to take advantage of the lower tax rate (than California’s) and my sister’s educational discount (she’s a teacher). As a nice bonus of the edu pricing, I also got a free 8GB iPod Touch (which I really like a lot more than I expected to).

So ok, enough background.

Vital stuff: this describes my experience installing Linux on a June 2009 era MacBook Pro 13″. DMI reports that this model name is “MacBookPro5,5″. This guide may work for other similar systems, or it may not.

lspci output for this laptop:

00:00.0 Host bridge: nVidia Corporation Device 0a82 (rev b1)
00:00.1 RAM memory: nVidia Corporation Device 0a88 (rev b1)
00:03.0 ISA bridge: nVidia Corporation Device 0aae (rev b3)
00:03.1 RAM memory: nVidia Corporation Device 0aa4 (rev b1)
00:03.2 SMBus: nVidia Corporation Device 0aa2 (rev b1)
00:03.3 RAM memory: nVidia Corporation Device 0a89 (rev b1)
00:03.4 RAM memory: nVidia Corporation Device 0a98 (rev b1)
00:03.5 Co-processor: nVidia Corporation Device 0aa3 (rev b1)
00:04.0 USB Controller: nVidia Corporation Device 0aa5 (rev b1)
00:04.1 USB Controller: nVidia Corporation Device 0aa6 (rev b1)
00:06.0 USB Controller: nVidia Corporation Device 0aa7 (rev b1)
00:06.1 USB Controller: nVidia Corporation Device 0aa9 (rev b1)
00:08.0 Audio device: nVidia Corporation Device 0ac0 (rev b1)
00:09.0 PCI bridge: nVidia Corporation Device 0aab (rev b1)
00:0a.0 Ethernet controller: nVidia Corporation MCP79 Ethernet (rev b1)
00:0b.0 IDE interface: nVidia Corporation Device 0ab5 (rev b1)
00:10.0 PCI bridge: nVidia Corporation Device 0aa0 (rev b1)
00:15.0 PCI bridge: nVidia Corporation Device 0ac6 (rev b1)
00:16.0 PCI bridge: nVidia Corporation Device 0ac7 (rev b1)
02:00.0 VGA compatible controller: nVidia Corporation Device 0863 (rev b1)
03:00.0 Network controller: Broadcom Corporation BCM4322 802.11a/b/g/n Wireless LAN Controller (rev 01)
04:00.0 FireWire (IEEE 1394): Agere Systems Device 5901 (rev 07)

Install Media

I decided to put Gentoo (the x86_64 version) on it. So, I grabbed the latest minimal installer (dated 20090618) and booted it. I was disappointed to find that the keyboard didn’t work after boot, so I couldn’t go anywhere with it. I Googled around a bit, but wasn’t able to find anything (except for the possibility of the usbhid driver failing to load due to an unrecognised option, which I thought a bit unlikely). After some head-scratching, I downloaded the install/live CD of Ubuntu 9.04, and booted that. To my happiness, the keyboard was working fine.


Backing up a little… Before booting the Linux CD, first I installed rEFIt from inside MacOS X. I didn’t burn the rEFIt bootable CD; I just went ahead and used the Mac installer which did the job without rebooting. After that I could still boot other CDs by holding down the “c” key while booting, but if I didn’t, I got a nifty boot menu with MacOS X listed.

Dual Boot

I decided I wanted to keep my MacOS X partition, so I fired up Disk Utility and resized the HFS+ MacOS partition down to 40GB. Yes, amazingly, current Leopard (10.5.7) Disk Utility can resize the startup volume while MacOS is running, without needing to use the installer DVD or reboot at all. It just resizes it live and you’re done. It was very quick, too.

BIOS Mode and Partitioning

I’ve read various sources that said that the proprietary nvidia drivers would not work with the machine in native EFI mode (though this seems to suggest otherwise, but I haven’t tried it), so it would have to be booted in BIOS mode. Unfortunately, this makes partitioning the drive a little annoying, as I wanted to keep MacOS X to dual-boot. The GPT partition table layout has a legacy MBR mode for booting BIOS-mode OSes (in our case, grub is the legacy OS).

The MBR compatibility mode only supports four primary partitions, and no extended partitions, so the partition with your kernel on it needs to be one of the first four. Since Apple takes up the first two partition slots (I’m told MacOS X will boot without the first partition, but it’s unclear as to whether or not missing that partition will screw up Apple-supplied updates later), that leaves two left. Plenty. Three and four ended up being /boot (96MB), and / (around 60GB). Initially, I was debating leaving out the swap partition, but Linux’s suspend to disk (aka hibernate) requires a swap partition, so I allocated 4GB for it. The rest of the space I allocated for /home. I used ext3 for the root and home partitions, since I don’t trust ext4 yet, and tools for manipulating ext4 volumes from other OSes are currently nonexistent. For the boot partition I used ext2, and set ‘noauto’ in the mount options so it doesn’t get mounted unless I tell it to. Note that *all* of these partitions should be primary partitions. GPT doesn’t use anything else. Grub will only be able to see my first two Linux partitions (/boot and /), but that’s fine, as the kernel will be on /boot, and once Linux comes up it will know how to read the real GPT partition table to find the rest of the partitions.

GPT Resync

After partitioning, I rebooted and selected the GPT/MBR partition table sync item from the rEFIt boot menu. This turned out to be unnecessary for me (I think gparted did it for me?), but this might be needed in some cases.

Gentoo Install

After partitioning, I pretty much followed the normal Gentoo install procedure (downloading a stage3 tarball, unpacking it to the root partition, chrooting, setting up a new kernel and various stuff, installing grub, and rebooting). It was remarkably painless. After the reboot, the rEFIt boot menu had an entry for Linux (with a cute penguin icon) next to the MacOS X entry, so I selected that and booted.


I started off with the gentoo-sources-2.6.30-r1 kernel (and just today updated to -r2 with no trouble). Here’s my kernel config. I set up the uvesafb framebuffer console driver, which seems to work great.


I installed nvidia-drivers-180.60. Previous versions did not compile against the 2.6.30 kernel. I created a minimal /etc/X11/xorg.conf file that only had 4 lines in it to set the video driver to “nvidia” and let the X server auto-config the rest. It appears to work fine; came up the first time at 1280×800 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.

Display Backlight

The backlight didn’t work at first, because it looks for specific MBP models, and this new laptop has a newer model number. I simply patched the ‘mbp-nvidia-bl’ driver (update: see below for a better patch) in the kernel to add “MacBookPro5,5″ as a recognised model. However, the backlight controls for some reason do not work while X is running. I suspect the nvidia driver to be at fault here, but more investigation is needed. I’m going to give nouveau a try at some point to see if this fixes any issues (though of course I’ll lose 3D accel with that).

Update (2009/07/14): The ‘nvclock’ program is able to set the backlight brightness while X is running, so I ‘ported’ the code that does that to the kernel driver. It’s not the best patch in the world, but it’s here if you want to give it a try. I’m told that this is not really a correct way of fixing the problem, as it’s not reasonable to poke at memory addresses owned/reserved by another driver (nvidia, in this case). So expect that some weirdness might occur if you use my patch.

Keyboard Illumination

The keyboard illumination works. The ‘applesmc’ driver detects it and creates a LED-class device (you can see it in /sys/class/leds). The ‘pommed’ daemon is supposed to support this, but I haven’t tried it yet because it requires patching to support the “MacBookPro5,5″ string. Otherwise I can manually set the keyboard lighting via the sysfs interface (just to verify it works). The ‘pommed’ daemon will monitor the light sensor and adjust the keyboard brightness accordingly. I needed to patch it to get it to recognise the new model string. Apparently upstream already has a patch and support will work in the next release. I also patched it to increase some ridiculously-stupid battery-wasting 200ms timeouts into equally-useful 2s timeouts. Ideally it shouldn’t poll at all, but I don’t care enough to put in the work to make that happen.


The touchpad works with the ‘bcm5974′ kernel driver and xf86-input-synaptics X.org driver. Note that to make X.org correctly use the synaptics driver when you aren’t providing an xorg.conf file, you need a very recent version of the hal-info package (otherwise it will use the evdev driver). I also have a custom .fdi file to specify some extra options for the driver. Left click works, and 2-finger clicking for right click and 3-finger clicking for middle click work as well. Two-finger horizontal and vertical scrolling work fine. One major annoyance is drag and drop: with MacOS running, I can click and hold with my thumb, and drag with my index finger (while keeping my thumb still). With Linux, I have to click and drag with the same finger, which is very awkward. I filed a feature request about this.


The WiFi works, but unfortunately not with the open source ‘b43′ driver, as that driver does not yet support Broadcom 802.11n chipsets. Broadcom provides a closed-source proprietary driver which seems to work decently, though the speeds I’m getting aren’t great, and it has a lot of trouble finding my 5GHz 11n AP sometimes (it finds the 2.4GHz 11g AP just fine though). Udev initially assigned the device the “eth1″ name, which I didn’t like, so I edited /etc/udev/rules.d/70-persistent-net.rules to change it to “wlan0″. NetworkManager works, though intermittently it won’t be able to find any APs (despite the fact that “iwlist wlan0 scan” shows APs). I anxiously await support from the ‘b43′ driver.

When compiling the Broadcom ‘wl’ driver, be sure to read the README on their website. The compilation is a little weird as they only provide a stub Makefile for use with the kernel’s build system. You’ll probably want to add ‘wl’ to /etc/conf.d/modules (or /etc/modules.autoload.d/kernel-2.6) to get loaded on startup. You may want to add ‘b43′ and ‘ssb’ to the blacklist in /etc/modprobe.d to be safe. If even the ssb driver gets loaded (even if b43 is not loaded), wl won’t work.

One oddity: wl requires the full suite of lib80211 helper modules, including the crypto ones. For some reason these don’t get built properly unless you compile another driver into the kernel that needs them, like CONFIG_HOSTAP (you can just compile it as a module).


The bluetooth chipset is detected, using the standard ‘btusb’ driver. I haven’t tested functionality yet because Bluez 4 is giving me issues.

iSight Camera

The iSight works just fine with the ‘uvcvideo’ module. Interestingly, on this laptop I did not have to extract the firmware from Apple’s MacOS X driver. Oddly, sometimes the driver for it fails to load properly, complaining about not finding a “video chain” or something similar, but removing and reloading the driver usually fixes it (very occasionally a reboot seems to be required).


I haven’t been able to get sound to work yet. The snd-hda-intel driver appears to detect the device, and I can unmute it and change the volume, but playing .wav files using aplay doesn’t produce sound. I didn’t get any output from the dual-purpose audio in/out jack either. I’ve tried the patch here, as well as trying ALSA’s git repository, but no luck. My current guess is that Apple decided to use a new sound chip. I filed an issue report with ALSA here. My bug hasn’t appeared to gain any attention, but someone else’s post to alsa-devel has gotten some response, so it looks like this is being worked on.

Update (2009/07/10): There’s now experimental support for the Cirrus Logic codec in the hda-cirrus branch of Takashi Iwai’s sound-unstable-2.6 tree. I imagine this’ll end up in 2.6.31 or .32. I haven’t tried it yet, but it’s been reported to work on the MacBookPro5,5 (and was indeed the motivation for writing the codec support).

Update (2009/07/12): The new driver works for me, though the sound-unstable-2.6 tree is based on 2.6.31rc1 as of this writing, so it’s a little bit of a pain because neither the Broadcom wl driver nor the nvidia binary driver compile correctly against it. I whipped up a couple patches and submitted them to Gentoo’s bug tracker (for broadcom-sta, for nvidia-drivers), so hopefully they’ll get included in the portage tree soon (and presumably added to future releases). Here’s my new kernel config; you just need hda-intel with Cirrus Logic codec support. You could also compile it into the kernel, but I’ve left it as modules for now.



Update (2009/07/16): I wish I’d tested this first off, because suspend at least worked perfectly out of the box. No tweaks necessary. I just installed pm-utils and suspended via HAL (using xfce4-power-manager in my case). I imagine calling ‘pm-suspend’ from the command line would work as well.


Shutdown and reboot do not work. The system just halts and locks up. You’ll need to hold down the power button for 5 seconds to shut it off. On a rare occasion shutdown will actually power off the unit, but reboot has never worked. I suspect that dropping the BIOS emulation and booting in EFI mode will solve this problem.

USB works fine for mass storage devices, at least. The SD card reader is detected as a usb-storage device, and works as it should.

Firewire drivers load (I used the kernel’s “new” firewire stack) and detect the chipset just fine, but I don’t have any devices to test it with.

This laptop has an accelerometer (aka Apple Motion Sensor). It appears to work; I can read the machine’s orientation via sysfs, but I don’t know if there are any daemons that will watch it and park the heads on the hard drive if the laptop gets shaken/dropped. There are also other nifty things you can do with it that I haven’t tried.

All things considered, I’m pretty happy. I haven’t gotten to a point where I can give meaningful battery life numbers, but I’ll try to get to that soon. The machine seems to run pretty cool and quiet, even while compiling for a while. My only major outstanding issue is sound.

BIOS mode vs. EFI mode

In order to get shutdown and reboot working, I’ve been trying to boot in EFI mode, with no success yet. I’ve tried the latest SVN versions of grub2, but I’ve had a lot of trouble. rEFIt only seems to find grub.efi if I put it on the HFS+ MacOS X partition; if put it on the Linux partition, it doesn’t work. Running rEFIt’s EFI console and poking at the disk partitions seems to indicate that it’s failing to read the ext3 partitions for some reason.

Grub2 otherwise just seems very buggy. The config file parsing doesn’t appear to work (when grub2 loads, it prints messages about “menuentry” being an invalid command). Despite the fact that linux.mod is loaded, “linux” isn’t being recognised as a valid command. In fact, after I use many commands once, successive uses claim that the command is invalid. Even the “help” command doesn’t work (fortunately, hitting the tab key lists valid commands). I’ve mostly given up on grub2. One of the nice things about grub2 is that, if you boot in BIOS mode, you can dump your main and video BIOS images which grub2 can later load/emulate on bootup in EFI mode, which presumably would allow the nvidia drivers to work correctly.

So next I’ll be giving elilo a try. It apparently doesn’t have support for loading BIOS images, but maybe I can get that to work eventually.

iTunes Protected vs. Unprotected

  • July 2, 2009
  • Brian Tarricone

Dear lazyweb,

A friend of mine has released an album on the iTunes store, and I want to buy it to support her. Of course, I don’t want to buy it there if it’s a DRM-protected AAC file. Anybody know how you can tell before you buy? I checked both using iTunes on a Mac, and on the iTunes Store app on my iPod Touch, but I can’t seem to figure it out.

It seems her album is also sold on Amazon (cheaper, even), and they sell 256kbps MP3s, so I’ll probably end up doing that regardless. But it would be nice to know if you can figure this out for Apple’s store too.

Update: It appears everything on the iTunes store is now DRM-free. Interesting.

On In-Kernel Drivers

  • June 17, 2009
  • Brian Tarricone

It’s pretty well-known that the Linux kernel developers advocate getting your drivers into the main line kernel tree. Doing so ensures that your driver always gets fixed to conform to the latest “correct” internal interfaces when they change, and in-kernel device drivers always get distributed with the kernel, so you get automatic end-user distribution for free.

While I agree with that (without touching the question of whether or not a stable driver binary API/ABI would be useful), I’m not entirely sure it’s the best thing in the world for some types of device drivers.

While reading a post by Carl Worth on recent (perceived?) driver stability issues with the Intel video driver for Linux, I came across this bit of insight:

It used to be that getting the latest Intel driver just meant updating an xf86-video-intel module or upgrading an xserver-xorg-video-intel package. But now it’s essential to get a recent kernel as well… And these fixes aren’t in a major kernel release until 2.6.30 which appeared only today.

This is a problem that perhaps highlights some types of drivers that may be served better by being maintained outside the main line Linux kernel tree. Of course, this is only true while the driver is actively maintained and maintainers are able to quickly update the driver for new kernels (without breaking backward compatibility) as in-kernel interfaces change.

He also notes that distribution maintainers tend to update critical parts of the system (like the kernel) less often than userspace portions (like X.org video drivers). Since the xorg-video-intel driver depends on an in-kernel driver, it’s easy for these two things to become out of sync on an end-user’s system without testing. Or, frustratingly, the maintainer of the userspace package for a video driver might be unable to update to a newer version of the userspace driver because the kernel packager doesn’t wish to upgrade the entire kernel to become compatible with that userspace package (which is an entirely reasonable position to take).

And with more video drivers expected to move toward having significant kernel portions, this problem can only get worse. What if the latest userspace package for drivers A and B both depend on kernel 2.6.30, and the maintainer of package A wants to update, but the package B maintainer doesn’t (perhaps there’s a bad bug in the latest version of B)? Even if the A package maintainer can convince the kernel maintainer to update, doing so might break things for other users.

Now, sure, having dependency issues like that is nothing new, but I submit that this is a bit different. The kernel contains so much “unrelated” functionality that it has the potential to be a root dependency of many unrelated packages. For example, if a video player depends on a particular version of a codec library, you can often update that codec library without causing issues with other video players (ignoring, for a moment, ffmpeg’s inability to maintain a stable API). But updating the kernel because a userspace video driver requires a new kernel version could potentially cause problems with anything ranging from a USB storage device, to a hard disk controller, to an audio card.

Now, of course, the Intel video driver has been undergoing some very large changes lately. In theory, these things will settle down, interfaces will stabilize, and you can expect the tight coupling between the kernel version and userspace package version to relax a bit. But perhaps during this transition period it might make sense to avoid merging kernel code like this at all, and instead do separate releases of (in this case) the DRM modules that are paired to the userspace package. I imagine it wouldn’t be too much of a burden for distro packagers to disable building the in-kernel versions of these drivers, and instead ship an extra module package that the userspace driver packages can depend on.

Git Weirdness, Part 2

  • March 18, 2009
  • Brian Tarricone

Ok, now this is just ridiculous:

[brian@machine1 airconfig $] pwd
[brian@machine1 airconfig $] git branch -a
* master
[brian@machine1 airconfig $] cd .. && mkdir t && cd t
[brian@machine1 t $] git clone ../airconfig
Initialized empty Git repository in /home/brian/src/t/airconfig/.git/
[brian@machine1 t $] cd airconfig
[brian@machine1 airconfig $] git branch -a
* master

Ok, that makes sense! Now:

[brian@machine1 airconfig $] cd ..
[brian@machine1 t $] rm -rf airconfig
[brian@machine1 t $]  git clone file:///home/brian/src/airconfig
Initialized empty Git repository in /home/brian/src/t/airconfig/.git/
remote: Counting objects: 1272, done.
remote: Compressing objects: 100% (486/486), done.
remote: Total 1272 (delta 778), reused 1270 (delta 776)
Receiving objects: 100% (1272/1272), 360.40 KiB, done.
Resolving deltas: 100% (778/778), done.
[brian@machine1 t $] cd airconfig
[brian@machine1 airconfig $] git branch -a
* master

What. The. Fuck.

Yes, the git-clone man page tells me that, when using a local pathname (and not using a file: URI), it assumes the other repo is local and uses hardlinks between the repos. But hey, if I specify –no-hardlinks when cloning, I still get all branches if I use the “../airconfig” method.

And if I go to machine2 and do “git clone machine1:src/airconfig” I get the same broken result with the file:// method.

Git, I think you rock. But why does your user interface suck so much? And why do you just appear to be broken right now? I can’t seem to find anything else in the man page to help here. (I’m using git if that matters.)