Virtualization and Pixelation

Ed uses digital picture frames to show how virtualization works in practice.


April 03, 2007
URL:http://www.drdobbs.com/embedded-systems/virtualization-and-pixelation/198702208

Ed is an EE and author in Poughkeepssie, NY. Contact him at [email protected] with "Dr Dobb's" in the subject to avoid spam filters.


Back in the days when photons hammered latent images into silver bromide grains, the craft of photography produced pieces of paper you passed around or hung on the wall. Photons now boost valence electrons to create latent images on hard drives, but paper images still require tedious fiddling that we usually avoid.

You can, of course, admire images on your monitor and e-mail them to your friends and relations for their monitors. Ordinary folks dislike huddling around a PC and won't deal with the usual hassles just to see the grandkids, so those images return to latency fairly quickly.

All this has created a market for "digital picture frames" that display image files from flash memory on an LCD panel. A hundred bucks gets you a small LCD in a tacky plastic frame with a low-res slide show of a few dozen pictures. Half a kilobuck produces an image large enough to see across the room and maybe a wood frame. The quality and usability leave a bit to be desired, to judge from the reviews.

Seen from a different angle, though, a do-it-yourself picture frame provides an excellent platform for learning embedded systems programming. It's difficult enough to be interesting, easy enough to be approachable, educational enough to be worthwhile, and cheap enough to breeze through the Spouse Approval process. Best of all, anyone can appreciate the end product, even if they don't appreciate the underlying tech.

Here's a guide to the DIY DPF process, with an emphasis on tools and techniques that you'll find useful in other contexts. Indeed, this DPF is a thinly veiled excuse to show how virtualization works out in practice, so keep reading even if you abhor DPFs.

This month, I cover the overall issues and get into the preparations. Next month, I'll show how it all works.

Rules of Engagement

At the software level, a DPF should be a classic deeply embedded system: Nobody cares about the computer inside. That rules out user education, detailed instructions, tedious care and feeding, and, in particular, Screens of Death. Basically, you don't want yet another PC administration headache.

I decided my users should transfer pictures using ordinary USB memory sticks, as they can simply drag-and-drop images from one folder to another. Remembering to unmount the stick in Windows may pose a problem, though, as it does for everyone. They then simply pop the stick in the DPF, wait for a reboot, yank out the stick, and that's all it takes.

I've seen Windows-based DPFs, but that OS doesn't make sense for this application even if you ignore the ever-present EULA issues. It's simply too easy to blow away a FAT or NTFS filesystem with an inadvertent powercord tug. WinCE may have its points, but friends don't let friends embed consumer-grade Windows, okay?

So we'll build a Linux-based DPF with some attention to hardening the filesystem. You could use any UNIX OS, but Linux wins hands down for being cheap, readily available, and well supported. I used Slackware for this project because it can have a small footprint and offers straightforward configuration; complex system management scripts just aren't appropriate for this task.

On the hardware side, any x86 laptop built in the current millennium should suffice. I started with an IBM Thinkpad 560Z from eBay (24 bucks, delivered, with no hard drive). It was built in 1998, has some limitations that make for a good story, and is about as ancient as you should get. You don't want a new, big, fast, hot laptop hanging on the wall, so fish in the ultracompact end of the pool. Remember: Power costs two bucks per watt per year, so a 20-W laptop burns $40 every year.

DPFs must not have noisy motors, so I added a 2-GB Compact Flash card ($13 after rebate), a CF-to-IDE adapter ($5, eBay), and a 64-MB DRAM card ($22, eBay). Total cost, delivered, under 70 bucks, but your mileage may vary.

You will, however, need a Linux desktop box for the software development tools. If you don't have one, you should, for all the usual reasons in addition to what you'll see in this column. You can boot a live CD version of a Linux distro to avoid installing it or, worst case, buy the cheap laptop and a small hard drive, install Linux, get the DPF code running, then convert the laptop into the DPF.

Off the Ground?

Because x86 laptops can run desktop Linux distributions, most DIY DPF instructions start by booting a distro's CD-ROM, then continue the installation at the laptop's keyboard. Alas, the 560Z lacks a CD-ROM, a floppy drive, and a network jack; it can't even boot from a USB memory stick. This is a classic chicken-and-egg problem familiar to embedded systems developers: How do you get code in there without removable, bootable media?

Most current laptops can boot into a kernel fetched from TFTP/PXE servers and, indeed, an Advanced Port Replicator with Advanced Thinkjet ($21, eBay) adds that trick to the 560Z. Unfortunately, the Replicator's broken PXE code requires tedious server-side workarounds that I was unwilling to implement.

The typical fallback requires popping the laptop's boot device (hard drive or CF+IDE adapter) into another laptop that can boot from a CD, installing on that laptop, then swapping back to the DPF laptop. That's certainly feasible, but it seemed like a lot of work, far too much typing on an uncomfortable keyboard, and, besides, my token Windows laptop was tied up doing something else.

Assuming you get past that, most laptops use low-level configuration programs requiring DOS or, yick, Windows. The 560Z's DOS-based config program comes wrapped in an EXE file that insists on writing its contents to an actual floppy drive: You can't redirect it to a disk file. Indeed, I booted DOS from a floppy (on my only box with a floppy drive!), whereupon the config program grumped about the DOS version.

I faced a cascading series of problems even before starting the DPF part of the project and, if the 560Z wasn't a nearly ideal DPF, I'd pick a different laptop. That, too, is a typical embedded-systems trade-off: low power and a small form factor versus easy development. Trying to use the same box for development and deployment generally doesn't work, particularly for deeply embedded systems lacking the usual user-interface amenities.

The canonical embedded-system solution involves cross-development: Creating and compiling code on one box (the host, my desktop PC) that will run on another (the target, the 560Z), with remote debugging through a serial or network interface. In the general case, the host and target have different CPUs, system architectures, memory layouts, and peripherals, all of which require specific configuration tweaks. Linux can handle such cross-development projects with aplomb, albeit with careful attention to matching the compilers, libraries, headers, and assorted utilities to the target.

In my case the host is a 64-bit, dual-core Pentium D and the target is a Pentium II, so they really are different CPUs. Keeping disparate x86 tools and libraries apart on a single x86-oid box poses a challenge, as using the wrong piece in any step tends to generate code that almost works, with little indication of what went wrong. Worse, you can mung your host by installing a target tool in what it insists is the right spot.

Sorting all that out seemed rather tedious, so I opted for a lower-effort approach: Develop the target code in a virtual machine with an adequate assortment of virtual hardware. This introduces a third system into the process, a "development box" that's distinct from the target, but it also eliminates the entire cross-development headache by making the development and target systems nearly identical.

When the code's done, I can transfer a disk image to the CF card, pop it in the laptop, and fire it up. Some configurations require the laptop's physical hardware, but most of the heavy lifting happens in the VM.

Sound interesting? Here's how to get it going.

Going Virtual

Linux provides several hammers for the virtualization nail, particularly to run x86 target code on an x86 host, and the differences highlight the subtle distinction between virtualization and emulation. Unfortunately, common usage ignores those distinctions, to the point where you can't tell what a program does just by its blurb.

Nowadays, virtualization generally means creating a virtual target (guest) machine that looks just like the host, except code running in the VM can't clobber the actual hardware. Nuances involve ersatz hardware for the code inside the VM, kernel hooks to speed up the VM, and so forth. As a rule of thumb, the target code inside the VM could execute on the bare host hardware, but you wouldn't want that.

In contrast, emulation generally means creating a virtual guest machine that need not resemble the host and, indeed, need not have the same CPU or architecture. In this case, the emulator must execute a subroutine for each target CPU instruction, making the guest run at a minute fraction of the host CPU's speed.

Just to show how the terminology has mutated, Java VMs emulate a bytecode-executing architecture and the DOSEMU package runs DOS programs using the x86 CPU's hardware Virtual-8086 mode. Got that?

For this project I used the QEMU package, which runs on x86 hosts (with others in beta) and emulates x86, ARM, MIPS, and a few other targets. The target machine architectures include more-or-less generic peripherals and even mimic some embedded development boards. The matrix of host and target CPUs and operating systems far exceeds my needs.

Although there are many other emulator/VM choices, I picked QEMU because it's easy to install and includes a kernel virtualization module that boosts the x86 emulator's performance to perhaps half of "native" speed. You won't notice this for most console interactions with the target, but compute-bound processes like kernel compiles perk right up.

QEMU emulates disk drives by reading and writing ordinary disk files. Its native QCOW (QEMU Copy-On-Write) format can grow as the target writes more data, but I used fixed-size raw binary files that can be mounted as loopback devices and copied directly to floppies, CF cards, and hard drives.

You can load CD ISO images through QEMU's emulated CD-ROM drive and change them on the fly, which means multi-CD OS installations work the way you'd expect. The target system can boot from any of the emulated drives, so images of those old boot floppies may still be useful.

QEMU's VGA emulation is good enough for my purposes, although it's limited to 16-bit color. If you're installing Windows or running X applications, the lack of hardware video acceleration may be painfully evident.

QEMU can also emulate network cards, mice, USB devices, and a gaggle of other widgets I don't need for this application, but your requirements and mileage will certainly vary.

The Big Picture

Because QEMU emulates disk drives using disk files, the end result of all this fiddling will be images that we can copy directly to the DPF's IDE drive or Compact Flash card. The starting point will be zero-filled files into which we'll install all the software.

The FreeDOS and Slackware installation programs run exactly as they do on real hardware, while their virtual (or emulated, as you wish) environment provides much better control over what goes on. That turns out to be crucial due to the hardware's lack of creature comforts.

It turns out that much of what we'll do consists of installing a few programs, tweaking the system's startup scripts, and writing a few bash routines. We'll compile a new kernel to see what that's like and get some idea of what virtualization does to compute-bound performance. We'll also get a detailed view of how Linux progresses from a power-on reset to running a user program, which is less mysterious than you might imagine.

And, I suspect, we'll all learn something new!

Last Tab

Remember that you can go a long way in this project with no hardware at all, which is the whole point of virtualization. In fact, you might want to wait until everybody else stops bidding up 560Zs on eBay, then pick up the cheap leftovers.

You can trick out a laptop-based DPF with an infinitude of configuration options, plug in some wireless networking, do administration with a web browser, and so forth and so on. Remember your user community, though: A USB stick may be the simplest and easiest interface of all.

Chris Buccella presented his 560Z-based DPF at the MHVLUG last year, which prompted me to get off the dime. His blow-by-blow description appears at the virtig01.net URL in the "Resources." I hammered out this project without his code, so all the blunders are my very own.

Resources

Old-school photography: en.wikipedia.org/wiki/Silver_halide.

BSOD Primer: en.wikipedia.org/wiki/Blue_Screen_of_Death.

Techbargains for new tech goodies: techbargains.com.

eBay for old tech goodies: www.ebay.com.

Syslinux and PXELinux booting: syslinux.zytor.com/index.php.

Linux net install: marc.herbert.free.fr/linux/win2linstall.html.

Getting cross-development right: www.kegel.com/crosstool.

Virtual Machine comparison: en.wikipedia.org/wiki/Comparison_of_virtual_machines.

QEMU home: www.qemu.com.

Linux on Laptops info: www.linux-laptop.net.

ThinkPad info: www.thinkwiki.org.

ThinkPad tpctl Linux tools: tpctl.sourceforge.net.

ThinkPad DOS configuration: www-307.ibm.com/pc/support/site.wss/RMIE-3AXE3E.html.

FreeDOS project: www.freedos.org.

Slackware Linux Project: www.slackware.com.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.