This is an old revision of the document!
Playing with LiveCDs
Introduction
LiveCDs are without a doubt a very useful concept. They are helpful whether you want to prepare a new system for installation, or recover an existing system from misconfiguration, or simply have a familiar system image that you can carry around. There are a few projects that produce their FreeBSD (or, perhaps, FreeBSD-based?) LiveCDs. Such projects also typically provide SDKs for building your own customized LiveCDs. I used some of them and they worked beautifully. But there is one issue - those things work automatically, auto-magically, mysteriously… I configured a few things, followed some steps, ran a script or two and, voìla, here was my ISO image. But I had zero idea what those scripts did internally, and reverse-engineering the scripts looked too hard.
Demistification
Then, one day I attended a presentation by Mykola Marzhan at KyivBSD where he explained how one could build his own FreeBSD LiveCD. Step-by-step, using command line, no ready-made scripts. That was enlightening and exactly what I needed. And it was very simple.
Here are instructions for creating the simplest LiveCD:
- Create a directory where a system image will be prepared; e.g.:
mkdir /tmp/R - Put a pristine FreeBSD tree into that directory; if you use source method, then this could be:
make buildworld
make buildkernel
Note: cd9660 filesystem support must be included with kernel, this is already the case for GENERIC
make installworld DESTDIR=/tmp/R
make installkernel DESTDIR=/tmp/R
make distribution DESTDIR=/tmp/R
- Now time for some basic configuration:
echo 'boot_cdrom="YES"' >> /tmp/R/boot/loader.conf
This will make loader pass -C option to kernel to let it know that it should mount root from CD-ROM (/dev/cd* or /dev/acd*)
- Make ISO image:
cd /tmp/Rmkisofs -R -l -ldots -allow-lowercase -allow-multidot -V 'My FreeBSD' -volset 'My FreeBSDs' -hide boot.catalog -o ../R.iso -no-emul-boot -b boot/cdboot .
And this is it! Well, almost
You have an image of the most trivial LiveCD, it has default configuration (read: no configuration), hostname is not set, network will not be configured, no users, etc.
But it will boot and you will get to single-user shell.
Actually, with an additional rather simple change you should be able to boot to multi-user. This change doesn't have to be necessary, but currently FreeBSD tries to re-mount its root filesystem as R/W and if that fails the boot process is interrupted and you are left in single-user mode. FreeBSD tries to do that even if root filesystem is cd9660. So we have to tell it that the root filesystem should stay readonly. In order to do that we should put an entry into fstab (and we have to predict device name for a CD/DVD drive):
/dev/cd0 / cd9660 ro 0 0
Alternatively you can set root_rw_mount="NO" in rc.conf or you can hack etc/rc.d/root script.
How this works
Just in case you wonder why such a simple setup works.
By using -b boot/cdboot mkisofs option we specified what should be run by BIOS (firmware) when boot from CD/DVD is chosen.
cdboot knows basics of ISO9660, it can find loader(8) and start it. loader also knows how to read ISO9660,
it can find and read/load its configuration and kernel with modules, it then executes kernel.
kernel in turn also should have ISO9660 filesystem support and it is instructed to use CD as its root, so it mounts root filesystem
and kicks off init, which then executes rc scripts that set up a system environment.
You might wonder: some system services need R/W filesystem, but CD is R/O. E.g. daemons create pid files and write to logs.
This is taken care of by two rc scripts: rc.d/var and rc.d/tmp that use mdmfs(8) to create in-memory filesystems
that are mounted over /var and /tmp if necessary, that is, if those are readonly.
What next
Of course, our simple LiveCD can be enhanced and improved.
In rc.conf you can set a hostname and provide some network options (e.g. for DHCP).
You can set up resolv.conf or your timezone via etc/localtime.
You can disable various services that are enabled by default and that are not needed on a LiveCD.
This what I usually have for example:
update_motd="NO" syslogd_enable="NO" sendmail_enable="NONE" cleanvar_enable="NO" hostid_enable="NO" ip6addrctl_enable="NO" moused_nondefault_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" cron_enable="NO" crashinfo_enable="NO" virecover_enable="NO" newsyslog_enable="NO" mixer_enable="NO"
But, of course, only sky is a limit to what you can do. You may want to install some useful thirdparty tools - it's easy. Just chroot into the image directory and do things that you want to do. You might find nullfs(5) to be a convenient way to make directories from host system to be available in the chrooted environment. For example, a directory with packages or ports directory.
Note: things might be not as easy if you are creating a LiveCD for different architecture using cross-compiled world and kernel.
Test before burning
I think I should mention this just in case: it is a good idea to test your LiveCD ISO using likes of emulators/qemu or
emulators/virtualbox before actually burning it and trying with real hardware.
This way you can discover, troubleshoot and fix potential issues in advance.
Installation
Perhaps it's not immediately obvious, but you can (re-)use the image you created for installation.
Because we didn't mangle our system image much we can transfer it to HDD and have the same system installed there. Of course, first you need to partition the disk, create filesystem(s) and only then transfer the files. With a full-blown system on LiveCD it's quite easy. You can use your favorite way of configuring disks.
You can run gpart and newfs (zpool, zfs), or you can use sade, or even start sysinstall in configuration mode. Don't forget to install necessary boot chain to HDD for your selected configuration.
Once you have filesystems prepared and mounted you can proceed to copying the system files. Here you can encounter a quite unpleasant surprise: copying files from CD is very slow. CD read speed is not very high in general, but especially so when you read many smaller files instead of one large sequential file.
There is an easy solution. Create an archive of your prepared system tree, for example a .tbz2, then add it to the tree before making an ISO image. You will see that extracting files from a compressed archive is much faster than for a plain filesystem.
Note that you can create the archive at different steps of your system tree preparation. You can create it from a pristine tree, or you can create from a final tree with all the configuration and additional software, or something in the middle. You can even replace some files or add new files to the archive, so that you can get a pre-configured system that you want after unpacking.
Try to reboot to a newly installed system - if anything goes wrong you still have your LiveCD that you can use to fix any mistakes. Once your installed system works fine you can proceed to build it up to final configuration.
Hint: when working from LiveCD you might get into a situation where you need to change some file on your (readonly) LiveCD; in this case
you can use mdmfs to create an in-memory filesystem and then use unionfs(5) to mount it over a sub-tree where you want to make changes.
That way you still have your readonly base files visible, but you can create and modify new versions of them in the in-memory filesystem.
Keep in mind that the changes are not persistent between reboots