I roll pretty hard when I put together a build. Mostly, it’s that I don’t screw around, I find a challenge, and then I beat it into submission. Unless, of course, I don’t, in which case I sulk off and go back to trolling Facebook or Reddit. But that hardly ever happens, yo.

Take for instance the Goat Webcam project. As soon as I knew I was going to do this, I checked out the Raspberry Pi wifi adapter listing and tried finding something that would be able to do dual-band networking on 802.11n. It’s not that I need (or that the RPi can support) 300Mbps throughput, because I seriously doubt this little board could sustain that kind of beating. Realistically, this is more about being able to play in the 5GHz radio spectrum, with the ability to stream something at about 4-5Mbps wirelessly without being completely hosed by everything else that crowds the 2.4GHz band (for instance, the neighbor’s 2.4GHz WiFi access point with the SSID “F*ck Off”, except without the *).

It turns out there is a WiFi chipset that does exactly that, and that kinda, sorta works on the RPi: The Ralink 5572.

Well, this should be painful.

Well, this should be painful.

The problems with it are two-fold:

  • The words “no native driver available” (cue ominous theme music) Fear not, however, because Realtek (purchased by MediaTek) provides Linux drivers. Yessir!
  • The Ralink 5572 is a chip, and I need a USB dongle!

Lucky for me, there is mention on the same page of actual USB dongles that use the 5572. One is the “TeckNet TK-WD688N5” and the other is the “TP-LINK TL-WDN3200”. As it turns out, the TeckNet dongle is from a UK company, and they didn’t seem too easy to source on this end of the Atlantic (read: nobody out here stocks it). No so with the TP-LINK dongle, which Amazon happily stocks and ships to me. A couple days later, the piece shows up, and again the ominous music cues in my mind.

The vexing continues.

The vexing continues.

This is a company that loves Windows, and doesn’t care much about Mac or Linux or anything not named Windows, apparently. I care not, the eLinux.org page says I can get and build drivers for it, so I fear nothing.

And then this happened…

All I have to do is compile the drivers that Ralink apparently makes available for Linux, right?

Not so fast.

This is embedded Linux we’re talking about, and the pain is only just getting started. Turns out, you have two choices when it comes to customizing an embedded Linux installation like Raspberry Pi: you can always build the software on the device itself, or you can put together a cross-compiler toolchain (which is really just jargon for “build it on your big computer, but make it so it runs on the embedded computer”). Turns out this is not as simple a task as I had originally thought, and therefore I stand again at a crossroads.

  • Build the drivers on the Raspberry Pi (sounds simple enough), or
  • Build a cross-compiler toolchain and build the drivers there, then copy them over to the RPi (more complicated, but probably faster in the long run)

I chose to build the toolchain on a VirtualBox install of Debian Linux and try that angle. However, I’ll save both of us the grief of reliving that choice in this blog and tell you that for building external third-party drivers for Raspberry Pi, you do not need to do this. That’s right, this simple realization will save you a bunch of time. You’re welcome.

Let’s instead put the pieces together for how to do this correctly.

Doing it the right way

So I found a couple resources for building the drivers, and had to synthesize it into a set of instructions that worked for me. These instructions work for Debian, other distributions are left as an exercise to the reader. As always, YMMV.

1. Log into your Raspberry Pi

I tend to do this over SSH rather than the console, but that’s just me. It’s obviously necessary to have it hooked up to the Internet.

2. Download the driver

I had done this using my desktop web browser, mostly because MediaTek makes you provide your name and email in order to download the Linux drivers for the Ralink 5572. So perhaps this is a point in favor of using the GUI on RPi for this.

Once it’s downloaded, get that tarball onto your Pi’s home directory (aka “/home/pi“). I used scp to do this, but whatever gets it done is just as valid. The version I got was rather verbosely named “DPO_RT5572_LinuxSTA_2.6.1.3_20121022.tar.bz2“. The following will un-bzip2 the tarball and then extract it:

> tar xvjf DPO_RT5572_LinuxSTA_2.6.1.3_20121022.tar.bz2

Once you have the driver source, you’re not done. Now you have to go in and make some changes.

3. Tweak the driver

In a couple files in the extracted tarball, you should make the following changes:

/os/linux/config.mk

Set HAS_WPA_SUPPLICANT and HAS_NATIVE_WPA_SUPPLICANT to “y”:

# Support Wpa_Supplicant

# i.e. wpa_supplicant -Dralink
HAS_WPA_SUPPLICANT=y
# Support Native WpaSupplicant for Network Manager
# i.e. wpa_supplicant -Dwext
HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y
/os/linux/usb_main_dev.c

Add (or at least make sure) that MODULE_LICENSE("GPL"); is present right after MODULE_DESCRIPTION(...);

MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
MODULE_LICENSE("GPL");
<driver>/common/cmm_mac_usb.c

Near the top of the file (just under #define RTMP_MAC_USB), add the following #defines for usb_buffer_alloc() and usb_buffer_free():

#ifdef RTMP_MAC_USB

#define usb_buffer_alloc(a, b, c, d) usb_alloc_coherent(a, b, c, d)
#define usb_buffer_free(a, b, c, d) usb_free_coherent(a, b, c, d)

#include "rt_config.h"

You are now able to move onto creating some preliminary kernel build assets to make the driver build possible.

4. Download the sources for your RPi build

You should know what version of the kernel you’re using. You can find this out pretty easily:

> uname -r

Take the first and second numbers (the major and minor versions) and get yourself the source code (as of this writing, you can ignore the third and subsequent numbers, if any). In my case, it was the 3.10 branch (rpi-3.10.y), which is what we’ll download here:

> wget https://github.com/raspberrypi/linux/archive/rpi-3.10.y.tar.gz

Go away for a bit, your Pi is going to chug away at this for a while (basically about 120MB worth of waiting). Once it’s done, it’s time to go into Super-User-Mode!

5. Wanton use of the superuser account (or, unpack and move the source code around)

So, for RPi users, this is ridiculously simple. If only they knew how crazy irresponsible this is:

> sudo su

Once you’re blessed with the # prompt, you can safely get to work. Get yourself over to the /usr/src directory:

# cd /usr/src

Now un-tar that naughty tarball.

# tar xvzf /home/pi/rpi-3.10.y.tar.gz

This should create a directory named something like /usr/src/linux-rpi-3.10.y. Next, we will do a symbolic link for the kernel sources to the location of the modules:

# ln -s /usr/src/linux-rpi-3.10.y /lib/modules/`uname -r`/build

Move into that new directory link and we can get started with the good stuff:

# cd /lib/modules/`uname -r`/build

6. More wanton superuser abuse (or, build the preliminary module files)

Now that we’re in the build directory as root, let’s do some make-ing!

# make mrproper

This shouldn’t really do anything if you just downloaded the source code, but it’s a good preliminary safety for what you’re about to do next.

# gzip -dc /proc/config.gz > .config

This will take the configuration that was used to build the running kernel (which is nice, since you won’t need to figure it out blindly) and make it the configuration for the build directory you’ve just set up. Good job! Next you can make those preliminary module files! (This should only take a 10-15 minutes on a Pi)

# make modules_prepare

And now, you can copy the Modules.symvers from the Raspberry Pi GitHub repository. This is generally up-to-date. If it isn’t working, you are now off in the weeds and may be forced to actually build the kernel. But give it a try anyway:

# wget https://github.com/raspberrypi/firmware/raw/master/extra/Module.symvers

Finally, you’re at the point where you can become a responsible user again and get out of that superuser shell!

# exit

Whew!

7. Build yourself a driver

Getting back to the Pi home directory (/home/pi) and the driver source code that you’ve modified from step 3 above, you can now do this:

> cd /home/pi/DPO_RT5572_LinuxSTA_2.6.1.3_20121022
> sudo make

You can once again step away from the Pi for a few, as this will take a while, at least 10-15 minutes. Once it’s done (assuming it completed successfully), you can then move to installing it.

> sudo make install

Again, assuming all goes well, you should pat yourself on the back for a job well done!

Nicely done, go eat some sand.

Nicely done, go eat some sand.

Now, given how long I spent on this solution, aren’t you glad I didn’t send you on the wild-goose-chase that was the “cross-compiler toolchain” method? It would’ve been every bit as complicated but with even more steps (read: opportunities for horrific failure). Again, you’re welcome. Now all there is to do is finish getting the wireless dongle configured to work with the Pi!

Wait… You mean I’m not done??

Nope. We gotta configure that thing before we can use it. But we’ve gone on long enough for now, we’ll do final configuration another time. In the meanwhile, I gotta go find a suitable case for the Pi Camera.

What’s a case like you doin’ in a joint like this?

Advertisements