Progress report on my PIC-based hack to make specially-formatted programs executable from the picture viewer: IT WORKS!!! Well, on a 2MB Juicebox anyway - I still don't have enough information to do it on an 8MB unit, and supporting both sizes would imply that the programs contain self-relocating code. I've mainly tested this with a modified version of the lcd_2 demo program from the wiki.
It's even possible for the programs to cleanly exit back to the picture viewer, if they take care not to stomp on any used memory. Fortunately, there is an easily accessible pointer to a 56K buffer, into which the picture was loaded from the SD card before being memmove()d to the screen. The easiest thing to do is to relocate the screen to that buffer, keeping the executing program and its working RAM in the original screen area. However, there is currently a problem with the use of the buttons - they're still being buffered by the system, so when you exit, all of your program's button presses suddenly get performed in the picture viewer, resulting in some rather bizarre behavior (especially if they result in reselecting the .jbp file containing the program, thus re-executing it!).
System calls appear to be fully functional. I've tried printf() (output goes to serial port 0), exec'ing another program, vfork() & exec (so that the program keeps running even after returning to the picture viewer), etc.
There is a /bin/sh in the romdisk, so the obvious next step is to run it. Unfortunately, when they say "serial input disabled for production", they really mean it - that kernel option completely omits the actual receive code in the serial port driver, it's not something that can be turned back on with an ioctl or something. So, what I did was write a little program called 'serin', that just reads characters from the serial port hardware and copies them to stdout. I then have my picture-program do a system("serin | sh -i"), and... I'VE GOT A WORKING SHELL!!! It's a horribly inconvenient shell at the moment - there's no echo or editing of typed characters, but that's fixable.
Note that 'serin' is a normal uClinux executable, in bFLT format - no assembly startup code, custom linker files, etc. were involved in producing it. ANY uClinux-arm program could be run from the SD card with basically the same technique.
The shell environment's root directory is the 1.15 MB romdisk, with about 35 standard Unix commands available in /bin (most of which are links to busybox).
There is a /proc filesystem, with all the possibilities for low-level tinkering that implies.
There is an empty ramdisk mounted at /ram, also linked from /tmp. I'm not sure how big it is ('df', for some reason, is unable to determine its free space), but I think it's close to a megabyte.
The SD card is mounted at /mnt, read-only. I'm not sure if that's an inherent limitation of the driver - I can't try to remount it RW in my current setup, since my 'serin' program is running off of it. Interestingly, the picture viewer appears to also try to mount a nand device or a second romdisk (neither of which is actually possible with the standard hardware), if the SD card isn't mountable.
The PIC that's making all this possible, via the JTAG port, is an 18LF1220 - it's not really the appropriate part, it's just what I had handy. The PIC program is only 634 bytes long, with absolutely no attempt at optimization - it could easily be squeezed into the tiniest (and cheapest) of microcontrollers. My goal here is the PIC12F508/SN - it costs about 61 cents (qty=25), and its SOIC-8 package has a pin spacing such that it could be plopped down right on the JTAG pads and soldered in place. Only two actual wires would be needed, to bring power to the PIC. I've got some of these chips on order, I should have more to report once they've arrived and I've ported my code to them.
I don't know if any of this will actually be useful to anyone, as there are some major limitations - it's completely incompatible with JTAG debugging, and it cannot automatically start a program when the Juicebox is turned on. But I'm feeling pretty darn proud of myself for having gotten this far!