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.