ADB with the vanilla Linux 3.8 kernel

So at ABS, I was talking with +mark gross and he expressed his frustration in getting ADB up and running during device bring-up. I mentioned that the Android gadget driver had been upstreamed into staging, but was re-named as the ccg driver, but mark pointed out that it was missing the ADB functionality. So I dug in and sure enough, the ADB bits were dropped when ccg was merged into staging.

I played around a little bit to add the ADB functionality to the ccg driver, but as I read up around it, I found that there's a similar gadget driver called the FunctionFS driver already upstream. Interestingly Andrzej Pietrasiewicz, the same developer who was working on the ccg driver, submitted patches to AOSP to get the adbd daemon to use the FunctionFS gadget. +Benoit Goby then reworked and merged those changes in AOSP last summer.

The net of it is, ADB can already work with the vanilla Linux kernel! Its just not well documented.

For me the process was as follows:

1) Make sure you have Jelly Bean 4.2 Android userland image.
Linaro provides a number of images for different boards here:
    http://www.linaro.org/downloads/

2) When building your kernel, make sure to configure in FunctionFS:
    Device Drivers -> USB Support -> USB Gadget Support
        -> USB Gadget Driver -> Function Filesystem

3) Modify your boot parameters to set the vendor and product ids so adb on your host recognizes the device.
    g_ffs.idVendor=0x18d1 g_ffs.idProduct=0x4e26

Alternatively this can also be done if you built the gadget driver as a module at load time:
    insmod g_ffs.ko idVendor=0x18d1 idProduct=0x4e26

4) Now here I'm assuming you've got a serial port working. Boot your target device with your new kernel (and insmod the g_ffs driver if necessary), and setup the functionfs directory:
    # mkdir /dev/usb-ffs
    # mkdir /dev/usb-ffs/adb
    # mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb

5) If everything is working, you can kill adbd and when it restarts it should find the functionfs mount and make use of it.
    # ps adbd
    # kill <pid for adbd>

6) On your host system, connect to the target using the adb program:
    $ ./adb shell
    root@android:/#

    Hooray there's your shell!

Now for something more permanent, you should probably modify init.rc to include the steps in #4 above prior to loading adbd. That way adbd starts up using the functionfs gadget and you don't need the serial console to get it going.

There's still some quirks with the instructions above:
* I ran into problems with functionfs somehow causing hangs at boot. Its a bit of a Heisenbug, as adding initcall_debug to my boot parameters causes the issue to disappear.

* While the above works fine, FunctionFS alone is fairly static configuration wise, which means once you've set it up as in the case above, you're not able to dynamically change what devices it composites, which contrasts with the more flexible Android gadget driver. Apparently in the future, some configfs based gadget will be merged which will provide the dynamic configuration aspect of the Android gadget driver.
Shared publiclyView activity