NWR04B: It's crashing!

I'm starting to make a bit of progress on the NWR04B -- almost to the point where I could comfortably say it's crashing. Yay! The problem so far has been that I wasn't getting any output on the serial port when (presumably) Linux was booting. Some judicious insertion of ARM assembly code into the kernel image showed me that it was at least running, but I had no clue what I was doing after that. I managed to follow the path of the assembly code through head.S, which is the very, very first bit of anything that gets run when you've got a compressed kernel. This is so early that it takes a while even to get around to decompressing the kernel. After that, I was able to follow it through to misc.c, where decompress_kernel gets run. There's some puts statements in there (like puts ("Uncompressing Linux...");), so how come I wasn't seeing anything? Well, because puts wasn't defined as anything. puts is defined in head.S as some assembly code to write a string to the serial port, but that wasn't referenced by misc.c; attempts to #include it failed horribly. There's an #ifdef STANDALONE_DEBUG that defines puts as printf, but attempts to build a kernel using that didn't work either. But follow the bouncing ball:

Whew! So I tried that, and hey -- I got garbage on the screen! But not very much: I was expecting something like "Uncompressing Linux..." and instead got maybe 20 characters of garbage. I took another look at the assembly version of puts, and one of the things it does is waits for 20,000 clock cycles -- which at 60MHz is a third of a second. Try adding a loop to count down 60,000 cycles (what the hell), and hey! more garbage -- though still a finite amount, and it stopped after maybe 5 seconds or so, and still nothing intelligible. What the hell's going on? I tried this:

static void cx84200_puts(const char *s)
{
        while(*s != '\0')
                cx84200_putc(*s++);
        cx84200_putc('F');
        cx84200_putc('I');
        cx84200_putc('X');
        cx84200_putc('M');
        cx84200_putc('E');
        cx84200_putc("\n");
}

and now I started to get garbage that had FIXME tossed in for good measure. A quick cat /dev/ttyS0 > logfile (have I mentioned that I love Unix?), and whaddaya know: I'm getting precisely four FIXMEs. If I threw an extra puts ("FIXME"); into misc.c, I got five, not six -- the string going to puts doesn't come out, but the extra putcs I put in do work. For the moment, this is where I'm stuck. The garbage/extra characters I'm seeing don't seem to have any relation to messages I might expect ("FOO", "Uncompressing Linux...", etc. There's places for the kernel to crap out after that, but I don't think there's any before. And why the hell am I seeing all the garbage, then a perfectly intelligible "FIXME" after that? What is happening to the strings to get them all fucked up?