Booting and flashing embedded systems

Two and a half years of working for Imagination has taught me many things, truly opening my eyes to a brave new world of in-your-hand computing technologies, not least being high-performance accelerated 3D. In the pursuit of understanding those technologies, trying to get smartphones, devkits, week-old silicon on hand-built wake-up boards and more to talk to a host system in a sensible way is easily the most infuriating and downright inefficient thing that happens to me day-to-day.

On the PC you have a reasonably simple BIOS (including UEFI) and standard interfaces for storage that effectively let you say, “start booting here, wake some hardware up, then hand over control to the OS here”, without much fuss or bother, and you can watch it all happening easily too.

Embedded devices on the other hand, in large part by virtue of their form factor, are a minefield of inconsistency, disparate cabling and means to monitor and interact with the process.

While there is the same concept of, “start booting here, wake some hardware up, then hand over control to the OS here”, you interact with it in a non-standard fashion from device to device. Commonly you can’t see it boot on the screen or easily interrupt it, and swapping out the on-disk representation of the OS is a road paved with shitty tooling and bad documentation.

Block device names change from kernel to kernel; some devices can’t boot from internal flash, only SD cards; if that’s swapped around, erasing, repartitioning the flash and rewriting it is under the control of fragile code and protocols (u-boot and fastboot I look at you); sometimes a device can boot from both, but then that toggle is usually controlled by that horrid, hard to manipulate arcānus: DIP switches. If I’m really lucky it’ll be controlled by undocumented jumper pins.

Sometimes a vendor will ship a tool that does it all nicely from Windows. Sometimes you’ll get a tool that does it all nicely from Linux. OS X never gets a look in. I’ve lost count of the number of times I’ve painfully rewritten flash from Linux but watched it all on a serial console connected to a Windows box, because, well, seemingly fuck you, Rys, that’s why. USB device connection and identification under Linux is just awful.

All of the inconsistency, the myriad ways to sign (or not) the bootloader, the hardware fuses you don’t get told about, the jumper pin blocks that fall off in transit and the spaghetti mess of USB cables and hubs required to work with these systems in a usable fashion; all of that needs to go away as fast as possible.

The industry needs to wake up and stop wasting my time, and the time of thousands of engineers like me, by figuring out one secure way of rewriting device flash and booting from it, connected to the host system with one data cable. One data cable that I can reuse on all systems. Ideally one AC adaptor plug at the device side, but that’d really be getting my hopes up.

I had a situation earlier today where I had to do a full device flash rewrite using a completely different OS to the one I was interested in first, just because it came bundled with a u-boot I needed, because somehow that u-boot can’t come bundled with the other OS. And I had to flash it with a different USB cable. Two hours of my day just fucked out of the window because there’s no sane way to place a u-boot environment on an embedded device.

Embedded systems industry: wake up and stop wasting everyone’s time. You can have a secure, flexible, standard boot and make it easy for me to interact with the system.