Building Your Own Live CD
A tarball containing all the scripts and files referred to here can be found at ftp.linux.org.uk/~dan/livecd. Due to space limits, here, most of the code is not reproduced in the article itself. It's mostly Makefile-driven, with some shell scripts and some simple Perl, and it should be pretty easy to follow. You may hit a few snags if you're not using Debian. If you make it work with some other host distribution, be sure to send patches.
The debootstrap program provides the Debian base system from which you start. Given a Debian release name and a package mirror URL, debootstrap downloads and installs the base system into a subdirectory of your choice. This is pretty flexible; you can chroot into it, use it as a UML root or, if the subdirectory you chose was on its own filesystem, reboot your computer and use it directly. You even can burn it onto a CD, which is what we are going to do. We have some work to do first, though.
Expect to do quite a lot of debootstrap and package installation as you test your scripts. Before going much further, save yourself some time and bandwidth by installing a proxy package archive (such as apt-proxy) on a convenient machine.
The fix_inner target in the Makefile adds packages to the base system. The first thing we do is replace start-stop-daemon with /bin/true to prevent post-installation scripts from running services in our chroot. With that done, we chroot into the system repeatedly and run such commands as apt-get and dpkg.
For testing and experimentation, we also have a Perl script, run-chroot.pl, that simulates a system boot in the chroot area. It doesn't start most of the services, because they're already running on the host and would conflict, but it does run an SSH server and the X startup script. This is a lot more convenient than writing a CD and rebooting whenever we want to test something.
There's no point in making people log in on a single-user demonstration system. You have to tell them the password anyway, and the CD is read-only so they can't change it beyond the current session. GDM has an autologin feature, but to keep the image size down we want to avoid dragging in all the GNOME dependencies. Instead, we simply use su to start X as a non-root user and run the .xsession script, which opens an xterm and Emacs and starts our application. The autologin-x script is installed as /etc/init.d.autologin-x, with appropriate symlinks to make it run at boot.
The script chooses which X server to run based on whether DISPLAY is set already; if so, it starts up Xvnc instead of XFree86. This is done to help with testing: when autologin-x is run by run-chroot.pl inside an xterm, we can connect to it with a VNC client to make sure all the usual X applications come up correctly. Of course, for X to work on the real CD-ROM, we need to know what video hardware the user has.
Hardware detection in Linux has improved a lot in the last ten years, helped by the improvements in hardware technologies. It's a lot easier to detect today's PCI and USB hardware reliably and safely than it was with the ISA devices we used to have.
Most Linux distributors have something that grovels through the PCI and USB devices in the system and loads appropriate modules. Knoppix uses Kudzu, originally written for Red Hat, but vanilla Debian uses the discover command. The two are pretty similar in coverage; as it's all open source, they can copy from each other's hardware databases. The Debian X server packages already use discover to provide defaults for X configuration questions, so we'll stick with it.
What do we do with the hardware we detect? Debian packages have human-editable configuration files, but they typically also come with post-installation scripts that create the initial versions of said files interactively. Where applicable, such as for X and network configuration, these scripts run the hardware detection tools.
The problem is we're installing the packages in a chroot on the host system, and detecting the host system's hardware is not going to help on the target. What we need to do is put the debconf database somewhere writable, so at boot time we can use debconf-communicate to unconfigure the package and run its .config script to make it think it's being configured for the first time. This is a more thorough approach than using dpkg-reconfigure, which sometimes asks questions such as, “Are you sure you want to reconfigure this package?” This can be confusing to the end user who hasn't even configured it once yet. See the debconf-communicate manual page and target/etc/init.d/configure-xserver in the tarball for details.