New GPG key

My previous key isn’t yet two years old, but given the recent kernel.org reboot, I created a new keypair today. The fingerprint is:

11FB F4D3 92A6 F32B CB4E  2E07 8411 1007 23B2 B915

The old key will be valid for a little while longer. As for korg, perhaps it’s time I used github anyway. My OMFS tree is over there now, lonely and waiting for me to feed him some patches.

Hello from Canada!

My family picked up and moved from the DC area to the surroundings of Toronto last week, and we still have all our limbs intact! My wife and son are here as citizens, while I am a lowly visitor, at least until my immigration paperwork goes through.

We are in the so-called Greater Toronto Area (GTA), which means we are in the part of Canada that is not Montreal, Vancouver, or Toronto itself. That’s Greater-with-a-capital-G: it’s about a 90 minute drive to get downtown from here.

So far my experience as a Canadian resident is much the same as that as a US resident. One must just learn the proper mental substitutions: Comcast is now Rogers, Target is Zellers, Digiorno is Delissio, Nabisco is Mr. Christie, bathroom is washroom, miles are kilometers, degrees Fahrenheit are now degrees Celsius, Throwing Away Garbage is now Composting.

Things are expensive. A whole chicken costs $12, while it would be $7 at our previous place. And the Canadian dollar is more or less at parity with USD these days so that’s still real money. Albeit money that comes in various pretty colors and shiny coins.

We live near one “Taunton Road.” I can’t shake the image of the internal organs of Hothian beasts whenever I drive on this one.

Moving our 92 boxes worth of earthly goods (among them, over 600 books) turned out to be easier than we expected, apart from the two weeks of packing time. Customs took us about two hours in all. The movers delivered our stuff within a week. It will still be some time before various wrinkles, such as managing to receive snail mail, are ironed out, but hopefully before long this house we are renting will feel like home.

To our stateside friends, look us up if you happen this way. Our email addresses survived the move but not much else in the way of contact info.

My Pal SCSI

My son Alex turned one a couple of weeks ago. (If you are reading this, Alex, happy birthday, and congratulations for learning to read at such an early age!) He picked up quite a stash of loot as a result.

Moore’s law means that the processing power of his toy box very likely exceeds that of my first computer by a large factor. As one example, he received a My Pal Scout talking stuffed animal as a gift. A toy that comes with a USB cable — this is progress! You can customize the toy to say and spell your child’s name, and pick different tunes for it to play.

My inner geek has been wondering what’s inside ever since, but of course I cannot take apart or otherwise ruin my kid’s toy in the name of science. I did, however, plug it in to my Linux box while he was napping. A quick dmesg showed the device implements USB storage, but always responds with ‘Medium Not Present’ when accessed. I guessed (incorrectly) that some extra magic might make the internal flash appear as a disk and then files are just copied to a FAT filesystem stored therein. The toy is relatively inexpensive and coming up with too much special sauce is likely to be prohibitively costly.

USB storage is a successful example of taking an existing protocol (SCSI command set) and wholesale wrapping it in a different wire protocol. Each USB storage transfer is initiated by the host sending a Command Block Wrapper (CBW) — a 31-byte USB packet starting with ‘USBC’, typically containing a SCSI command as a payload. Next, a block of data is transferred if this command represents a read or write. Finally, the device completes the transaction by sending a Command Status Wrapper (CSW), a 13-byte packet beginning with the string ‘USBS’.

One can get a feel for the flavor of the protocol by using usbmon. Much like an ethernet sniffer, usbmon provides a simple mechanism under Linux to capture USB traffic. A simple session might look like:

    # cat /sys/kernel/debug/usb/usbmon/4u > usbmon.txt

One might even potentially run usbmon on a host OS while some other OS is running as a guest in a virtual machine with USB pass-through.

The upshot of the layered approach to USB storage is that Linux creates a generic SCSI device (/dev/sgX) for any USB storage device. Using the generic device, one can directly send SCSI commands to the USB device, and the kernel will take care of wrapping it in USB commands. I believe something similar is possible in Windows land.

As it turns out, Scout is even simpler than I imagined. The internal flash has no controller or filesystem; instead it appears to be a raw NAND flash written a page at a time. It is a simple matter to read the flash using the Linux sg device. One merely opens the device file, and then issues a vendor-specific SCSI command on the file descriptor:

static int read_page(int fd, u32 addr)
{
    u8 cmdblk[] = {
        0xfd,               /* access flash */
        0x28,               /* read it (0x20 = write) */
        0, 0, 0, 0,
        0x06, 0, 0x08, 0,   /* no idea what the rest is */
        0, 0, 0, 0,
        0x47, 0x50
    };
    u8 response_buf[4096];
    u8 sense_buffer[32];

    cmdblk[2] = (addr >> 24) & 0xff;
    cmdblk[3] = (addr >> 16) & 0xff;
    cmdblk[4] = (addr >> 8) & 0xff;
    cmdblk[5] = addr & 0xff;

    sg_io_hdr_t io_hdr = {
        .interface_id = 'S',
        .cmd_len = sizeof(cmdblk),
        .mx_sb_len = sizeof(sense_buffer),
        .dxfer_direction = SG_DXFER_FROM_DEV,
        .dxfer_len = sizeof(response_buf),
        .dxferp = response_buf,
        .cmdp = cmdblk,
        .sbp = sense_buffer,
        .timeout = 20000
    };

    ioctl(fd, SG_IO, &io_hdr);
    /* do something with response_buf here */
    return 0;
}

Reading addresses 0x01000 through 0x10000, 4k at a time, seems to yield the customizable data on the device. The flash is tiny: this is just 64k, yet you can upload a digital audio file of your child’s name plus ten songs.

The data format is rather simple: there is a 30-byte header starting at address 0x1000, containing 16-bit, little-endian pointers for the customized files. Address 0x1008 holds a pointer to the spelling of your child’s name, address 0x100e holds a pointer to the audio file pronouncing your child’s name, and so on. Armed with the Leapfrog software and a packet sniffer, one can verify that these files do indeed match the individual binary files that the software downloads over HTTP when syncing the puppy.

I believe the digital audio files are some flavor of raw 8 kHz PCM, but I could not find the right combination of parameters to sox to make sense out of them. The song files are all apparently compressed with TTComp, some compression program from 1995. Running ttdecomp.exe from within dosemu did successfully decompress them. My guess is these files are some sort of sequencer format rather than sampled audio, given their tiny size.

This is, I think, as far as I wish to investigate the toy. Obvious exercises for the interested reader are to discern the individual file formats, and have the toy play Metallica. It’s pretty incredible how much technology can be cheaply packed into a child’s plaything today. But now I have my eye on dissecting that (non-electronic) toy inchworm — is there a spring in there or what?

Fast… for a modem

This question is for someone slightly more motivated: why is qemu-img so slow to convert from a raw disk image to a VMware (vmdk) image? Apparently it does some compression or null-block elimination, as the resulting file is about 30% smaller, but I was not expecting it to take an entire day to convert a 100 gig disk. To get the answer to a first approximation without actually reading the source, I did a quick run with blktrace and seekwatcher:

So we get a nice sequential read pattern, but excessive think time between the reads. Probably, reading bigger blocks would help, or something like posix_fadvise(POSIX_FADV_SEQUENTIAL). Iostat showed the disk was reading exactly 2k sectors (1MB) per second, when it should be able to do 50-100 times that.

I just decided to wait a day rather than learn and hack the source.

My drive is now solid state

I always learn something new when doing some misguided thing such as “let’s copy our OS onto a new disk using tar like they did back in the day!” The impetus was a shiny new OCZ Vertex 3 to replace the spinning rust in my ancient Macbook. As a co-worker says, it’s like putting a gold steering wheel in a 1970 Pinto. My plan was roughly to:

  • Stuff the new drive in the desktop
  • Make a tar backup of the old laptop drive across the network to the desktop
  • Partition new drive, aligning to flash block sizes
  • Mount the new partition somewhere, and untar the backup
  • Chroot in the new directory, and do a grub-install

Simple. All of that went great, I thought.

The first hurdle when swapping the new drive in was a physical one: the laptop disk bay uses Torx, smaller ones than any adapters I have. This obstacle was cleared by creative use of needle-nosed pliers, and I was on to my first boot attempt, and subsequent failure.

Among the exciting new discoveries:

  • You really, really need to remember to mark /boot as bootable. Otherwise, the dumb Mac firmware will give you the blinking question mark despite all of your previous care.
  • If your user/groups don’t match between the two systems, you probably just borked up a bunch of uid/gids. Luckily there are the -nouser and -nogroup args to find, and almost everything outside of /home is root:root.
  • Once again, Macs won’t boot a rescue USB flash drive unless it has EFI crud laying around in the root directory.
  • UUID-based fstab and grub.conf are not happy when you have an entirely new drive
  • Debian tar doesn’t understand xattrs, that’s a RedHat feature (although I caught this one in time and compiled RedHat’s tar on the Debian system).

On the whole though, it wasn’t too bad. The install took maybe twice as long as installing from media and restoring my usual backup despite the mistakes, and this way I don’t have to reinstall huge numbers of packages to get back to where I was. And so far the drive seems quite speedy, even with my sad 1.5 Mbps interface. Plus it doesn’t hurt that the installation did a giant defrag of the whole OS.

Build complete

293I found time about a month ago to finish up my facet kite, just ahead of my family’s trip to the beach. Of course, the spars are too big for our suitcases, so it got left at home. Since then we haven’t had the free weekend to get it up in the sky.

As they say, until it flies, it’s just art. But here’s a picture of the final assembly anyway. To give a sense of scale, the kite is about 1.2 meters tall.

No comment.

Despite comments requiring moderation before posting, I’ve had a flood of thousands of spam comments over the last few days in the queue and I’m tired of pressing the delete button. Thus, they are disabled for the time being until I can set up something more automated.

Sorry spammers, none of those posts ever made it to any web crawler.

Update: or not. Of course WP makes this hard. Well you can’t comment on this one post at least!

Edge binding

Edge binding by bluesterror I finished reinforcements on my facet kite about a month ago, and there my project sat as I waited for supplies to come in. Last Thursday the shipment arrived, so when I got a free hour this weekend, I did the edge binding on four of the eight panels. On all of my previous kites, I used double-folded hems, where, as the name suggests, you fold the edge of the sail over twice and then sew it flat. With edge binding, you instead fold and sew a separate piece of material along the cut edge. Edge binding seems like it would be easier, but I find that it’s a bit of a battle to keep the sail and binding material aligned. Perhaps some sticky tape would help, but that just adds to the build time. On the other hand, binding can look nicer since the border stands out.

After I finish the bindings, there’s a bit more sewing, and then it’s ready for framing and its first flight.

Updates

So the blog mysteriously committed suicide recently, so I took the opportunity to update to the latest WordPress. Everything now seems to be in order. Perhaps I should also upgrade the theme one of these days.

Also committing suicide this weekend was the two year old Ubuntu installation on my laptop. The automatic upgrade to 10.04 resulted in a non-bootable mess (it turns out this was merely foreshadowing), so I took a backup and then dropped the F15 alpha on it to see what the Gnome3 Shell hubbub is all about. It does make my computer feel like a giant cell phone, but I do actually hate it less than I thought I would. We’ll see if that faint praise holds up after I use it a bit. The actual F15 installation took four tries, all due to my Macbook’s quirky half-EFI, half-BIOS firmware. No manner of coercion would convince Fedora to make a hybrid GPT/MBR partition table that actually booted, so I eventually gave up and just created a plain MBR with fdisk and that was that. A full day of reloading the backup and updating packages later, and I am back to a functional desktop, sans all those pesky minimize buttons.

Wirth’s Law avenged

Occasionally, rewriting other people’s code can be its own reward:

88 times speedup is not too bad for a few days’ work.