Unvacationed

Ange and I just returned from a long weekend in Florida with my family. After a perfect storm of flight delays and down computers, and US Airways personnel blaming the passengers over the intercom for ruining their holiday, we arrived in the state a mere six hours late. Everything from then on was smooth sailing though: sparkling sandy beaches, excellent weather, lots of playtime with the kids, and so on. My nephews’ superhero kites did in fact fly — after a trip to the local kite store to pick up some tails. We got in a full day of standing in line at Disney World, and an afternoon traipsing through ye olde shopping centre of St. Augustine. And I mostly didn’t touch the computer the whole time.

Anyway we are back and reinserted to the river of normal life. This trip should hold us until a month from now when we will be flying off to Berlin, Germany. I get two days of being nerdy at the Linux wireless mini-summit, and then the rest of it will be spent enjoying the city.

First scan

Success! Scanning with wl12xx on my ADP1 works. I’ll post more later but here’s a teaser. That’s a real SSID, however apt.

# ./iwlist wlan0 scan
wlan0     Scan completed :
          Cell 01 - Address: 00:0F:B5:63:30:4E
                    Channel:11
                    Frequency:2.462 GHz (Channel 11)
                    Quality=14/70  Signal level=-96 dBm
                    Encryption key:on
                    ESSID:"SERENDIPITY"
                    Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 18 Mb/s
                              24 Mb/s; 36 Mb/s; 54 Mb/s
                    Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 48 Mb/s
                    Mode:Master
                    Extra:tsf=000001dec907e41c
                    Extra: Last beacon: 160ms ago
                    (Unknown Wireless Token 0x8C05)

wl12xx update

I won’t claim success until I actually transfer data, but so far, it looks like wl12xx SDIO support is baked:

[  111.247063] cfg80211: Using static regulatory domain info
[  111.253472] cfg80211: Regulatory domain: US
[  111.262810] 	(start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[  111.271568] 	(2402000 KHz - 2472000 KHz @ 40000 KHz), (600 mBi, 2700 mBm)
[  111.279472] 	(5170000 KHz - 5190000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.287254] 	(5190000 KHz - 5210000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.294975] 	(5210000 KHz - 5230000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.302482] 	(5230000 KHz - 5330000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.310264] 	(5735000 KHz - 5835000 KHz @ 40000 KHz), (600 mBi, 3000 mBm)
[  111.317894] cfg80211: Calling CRDA for country: US
[  112.684807] lib80211: common routines for IEEE802.11 drivers
[  112.690972] lib80211_crypt: registered algorithm 'NULL'
[  112.744713] lib80211_crypt: registered algorithm 'TKIP'
[  112.787467] lib80211_crypt: registered algorithm 'WEP'
[  112.845267] lib80211_crypt: registered algorithm 'CCMP'
[  113.251671] wl12xx: registering driver
[  113.256462] wifi_probe
[  113.259208] trout_wifi_power: 1
[  113.569452] trout_wifi_reset: 0
[  113.623681] trout_wifi_set_carddetect: 1
[  113.628290] mmc0: card_present 1
[  113.631921] mmc0: Slot status change detected (0 -> 1)
[  113.653283] mmc0: Command timeout
[  113.664788] mmc0: card claims to support voltages below the defined range. These will be ignored.
[  113.678429] mmc0: SDIO card claims to support the incompletely defined 'low voltage range'. This will be ignored.
[  113.692773] mmc0: new SDIO card at address 0001
[  113.702813] wl12xx: in probe
[  113.728844] phy0: Selected rate control algorithm 'minstrel'
[  113.738915] wl12xx: loaded
[  113.743919] wl12xx: initialized

Unfortunately, I can’t really test it yet because the wpa_supplicant already on the phone doesn’t support -Dwext or -Dnl80211, and there are no wireless-tools. So I need to cross-compile those before attempting to associate. In the meantime, here’s a very rough patch that implements the goods from wireless-testing wl12xx. I need to work on read() and write() – right now they are a copy of what is in the google driver because it appears the host driver has issues with RW_EXTENDED. I don’t believe the readb/writeb fallbacks should be strictly necessary. Ditto with the platform code, that needs a slightly better solution.

On Annoying Startup Chimes

I like my MacBook well enough, but it certainly does have its share of issues. One such bile-inspiring misfeature is that it sees fit to loudly blare its “I’m a Mac!” chime every time you turn the thing on. According to those in the know, this is actually a feature to let you know the computer started properly. Hmm, I see a big Apple logo, screen is on, I think it’s started. So, Mr. Computer, how about making the big ugly noise when you know it isn’t working instead, and save us the ear strain the other 99.9% of the time? Did they really think no one would want to use the laptop in, say, a library, or a classroom?

The bonus of this brain-o is that older Macs gave you the ability to hold down the mute key while booting to temporarily turn off the sound, a useful feature abandoned for the Intel Macs. Also, plugging something into the headphone jack doesn’t work, because “the headphone jack isn’t available at boot time.” (Why? I can still see it there!) Apple actually recommends, and I’m not making this up, that you “fix” it by remembering to mute your audio every time you shut down your computer. Some people have even written little daemon programs for OSX to do that for you. Amazing.

Of course, the fanboys rationalize this crazy behavior in predictably nonsensical ways: “You should always use sleep instead of turning off your computer” or “I like the sound because it lets people know I’m using a Mac.”

As it happens, the boot noise volume is configured by an NVRAM variable, which seems to be synced with the volume control at shutdown time. Setting it to 0x80 turns off the boot chime. Why 0x80, I do not know, but I stole this very useful information from some mailing list post and can attest that it works.

Here’s how I think this variable was born in Cupertino:

    Engineer 1: This noise is driving me mad, can't we turn it off?
    Engineer 2: Sure, we'll just put a switch in NVRAM.  That way, only the
                users have to deal with it.
    Marketing: Some users, probably miserable Windows lovers all, are whining
               about our awesome boot noise feature.  What should we tell them?
    Engineer 2: Just tell them to mute the audio when they turn it off.
                Heh heh.

So, here are some solutions: you can use the nvram program in OSX as in my previous link. And I’m sure you could, with proper EFI support in Linux (CONFIG_EFI_VARS), do a similar thing from Linux. But I am presently missing the EFI kit and I hate booting OSX, so here’s my other, much more insane way of fixing this problem.

You need:

  1. a Mac with rEFIt already installed
  2. a USB key with a [V]FAT partition

Procedure:

  1. Plug in the USB drive and turn on the machine.
  2. At the rEFIt boot screen, cursor down to the EFI shell. This will start a shell in the firmware reminiscent of the heydey of MS-DOS 3.0, when edlin was king of the text editors.
  3. Type ‘help -b’ to get your bearings.
  4. Get the current audio level via:
    Shell> dmpstore SystemAudioVolume
  5. Now, figure out where your FAT partition got mounted. Useful commands include ‘map’ and ‘ls’ (mine was on fs3):

    Shell> map -b
    Shell> ls fs3:
  6. Use dmpstore to save the NVRAM variable to a file.
  7. Shell> dmpstore SystemAudioVolume -s fs3:volume.txt

  8. Use the built-in hex editor to change the last byte from the value in step 4 to 0x80. Yes, rEFIt has a built-in hex editor!
  9. Shell> hexedit fs3:volume.txt

  10. Now load the new value, check it, and reboot.
  11. Shell> dmpstore SystemAudioVolume -l fs3:volume.txt
    Shell> dmpstore SystemAudioVolume
    Shell> reset

That’s it! It should be gone for good, until you somehow enable it again. When that happens, you can pop the key back in, and redo step 8 with the volume.txt file you remembered to not delete.

Hmm, on second thought, maybe it is easier to just use the sysfs files.

Spiderman kite

Batman, Meet SpidermanI finished up the bridle and spars for the Batman kite and moved on to the second featuring a Spiderman logo (actually, the black Spiderman logo, but who’s counting). Until now, I have done all of my appliqué using a technique known as reverse appliqué. With this technique, I would create a stack of all of the layers of ripstop nylon that will be visible, usually with the lightest colors on the bottom. Then, I’d draw the design on the top layer in washable pencil, sew along those lines, then cut layers off the top one at a time until the proper colors show through. This photo is partway through that process on the Snorlax rok.

For this logo, I decided that cutting out so many sharp corners would be difficult, and cutting appliqué is when I invariably punch a hole in the sail and have to reach for the superglue. So on this one I tried forward (normal) appliqué instead. First I cut out the entire spider then taped the legs down to a piece of cardboard. I sprayed the whole thing with spray glue, waited a minute for it to set, then carefully placed the sail on top of the spider. Then I flipped it over, repositioned the spider legs to get all the air bubbles out, and voilà — I had the logo nicely attached to the sail. The glue isn’t permanent though, so then I spent an hour or so sewing around the inside edges of the design. I expected to go outside the lines of a few of the stitches, but surprisingly I did it all without a hitch, so to speak.

wl12xx merged

commit 00d8979d598d5461a06d800c779f15e03888d9d8
Author: Kalle Valo 
Date:   Wed Apr 29 23:33:31 2009 +0300

    wl12xx: add driver

    wl12xx is a driver for TI wl1251 802.11 chipset designed for embedded
    devices, supporting both SDIO and SPI busses. Currently the driver
    supports only SPI. Adding support 1253 (the 5 GHz version) should be
    relatively easy. More information here:

    http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?contentId=4711

    (Collapsed original sequence of pre-merge patches into single commit for
    initial merge. -- JWL)

    Signed-off-by: Kalle Valo 
    Signed-off-by: Bob Copeland 
    Signed-off-by: John W. Linville 

Hooray, wl12xx is now in wireless-testing! As the commit log states, SDIO support isn’t there yet, because I haven’t written it yet. Well, I wrote some of it, but nothing worth even compile-testing yet.

As for the Android itself, I bought a snazzy serial breakout board for the phone so now I can do some real work on it. It works just fine with screen(1) as the terminal program.

Also, I solved the problem with booting: apparently the init program for 2.6.25 doesn’t work with 2.6.27 — when I put my own compiled init in the initramfs, everything mounted fine. The input devices now do not work, but I suspect it’s just a difference in paths and that an upgrade to 1.5 userland will fix all of that.

Batman Eddy

Batman kiteI made my first kite in over a year this afternoon (yes, I am quite rusty). I plan to make a stack of these kites for my nephews with various super hero designs. This is the first and easiest one, which took about 4 hours of work today from start to finish. It isn’t perfect, the sides were a little uneven when I cut the sail which can be seen in the final product. Also I think appliqué really looks much better with the black outlines that I’ve used on my previous kites, but I really don’t have the time/patience to add another layer of ripstop to these just for that effect.

Still, these will be much better kites than you can find in your local store. At least I hope so; I haven’t made this type before — who knows if they will fly. However, I should find out soon since this one just needs a bridle and sticks and it’s good to go.

Closer

I was in fact wrong that my self-compiled android kernels weren’t booting — they were. But they do fail somewhere in init:. Unfortunately, when you boot the phone, you don’t have any idea why it fails because there’s no console by default. It would’ve been a lot easier to see this if I had a serial cable, but I did finally remember that I could use fbcon with the smallest font and CONFIG_PRINTK_DELAY to see the messages scroll by. And so now I see the problem:

A N D R O I D
init: Unable to open persistent property directory /data/property errno: 2
init: cannot find '/system/bin/sh', disabling 'console'
init: cannot find '/system/bin/servicemanager', disabling 'servicemanager'
...

Obviously, the init script can’t mount the mtd partitions, despite the partition tables being successfully probed at start and my having yaffs2 built-in. Oh well, at least now I have a direction to start debugging.

The 2.6.25 branch of the msm tree, incidentally, works fine with the stock initrd and userland, but who wants such an old kernel? Oh, and I changed my bootup logo to a shiny Tux instead of the default robot. “Android isn’t Linux” indeed.

Manual git-svn clone

I finally decided to do something about the five independent git trees I had on my hard drive at work. The problem is they are all really branches of the same subversion repository, and moving patches back and forth between them meant I had added them all as git remotes to each other. The meta problem is that we didn’t always branch off of the same trunk directory, from back when we were drinking the “just snapshots of directories” subversion kool-aid, so git svn clone doesn’t do the right thing for our branches.

The ideal setup is one where I have a git branch for each subversion branch all in one tree, and git svn dcommit will go to the right place. As it turns out, this isn’t too hard to achieve, but requires a lot of waiting around when building the repository. You just manually add different svn-remote sections to your .git/config, then run git svn fetch for each one:

$ cat .git/config
[...]
[svn-remote "svn"]
url = svn+ssh://server/svn/trunk/
fetch = :refs/remotes/git-svn
[svn-remote "svn-bar"]
url = svn+ssh://server/svn/branches/foo/bar
fetch = :refs/remotes/git-svn-bar
[...]
$ git svn fetch
$ git svn fetch svn-bar
$ git checkout -b bar svn-bar

Now ‘bar’ is a branch tracking the directory in branches/foo/bar, master is your normal trunk line of development, and git svn dcommit just works. Having 8 years of history in a 400 meg local tree is pretty nice.

Emulator

The Android source code includes at least two ARM sub-architectures in their kernel tree. The one actually used on the G1 hardware is derived from the Qualcomm MSM machine type, at least part of which is in the mainline. Then there is “goldfish,” which appears to be just a pseudo machine used only for the emulator. While I haven’t had a lot of success with the MSM stuff booting on the phone so far, building the emulator kernel is not too hard once you know where to look:

# get the MSM specific tree.
# You don't really need it but might as
# well grab both up front into the same git repo.
$ git clone git://android.git.kernel.org/kernel/msm.git msm
$ cd msm

# also grab the common one for emulator target and check it out
$ git remote add common git://android.git.kernel.org/kernel/common.git
$ git fetch common
$ git checkout -b goldfish common/android-goldfish-2.6.27

$ cat <<_EOM >make-arm.sh
#! /bin/bash

# I use the codesourcery toolchain
XGCC=/opt/xgcc
PATH="$XGCC/arm-2008q3/bin/:$PATH" make ARCH=arm CROSS_COMPILE=arm-none-eabi- "$@"
_EOM

$ chmod 755 make-arm.sh
$ ./make-arm.sh goldfish_defconfig
$ ./make-arm.sh

Now the emulator can be run with something like:

$ export ANDROID_PRODUCT_OUT=`/bin/pwd`/out/target/product/dream
$ emulator -verbose -show-kernel -kernel msm/arch/arm/boot/zImage