CDProject

This is a project designed to document the creation of bootable (El Torito) CD's, particularly multi-boot CD's. I am not an expert, however I have put together a number of bootable CD's. A lot of people have asked about how to do this, so this project is intended as a write-up of the steps necessary to build one.


My Environment

This documentation has been written based on my system (RedHat Linux 9), but the concepts and programs are pretty general, and should work in most cases. Here are the packages (and versions) that I'm working with:

   mkbootdisk (1.5.1-1) - Creates a boot floppy disk for booting a system.
   syslinux (2.00-4) - A simple kernel loader which boots from a FAT filesystem.
   mkisofs (2.0-11.9.1) - Creates an image of an ISO9660 filesystem.
   dd (4.5.3)


Just a Boot CD

If all that you're trying to do is to create a bootable CD (rather than a boot floppy) that can boot your system, you only need to use the --iso option to mkbootdisk, like this:

   mkbootdisk --device /tmp/cdproject.iso --iso <kernel_version>

If you've already got the floppy disk or disk image, you can use the -b option to mkisofs to tell it to use your image as the "El Torito" boot image:

   $ mkdir /tmp/cdproject
   $ dd if=/dev/fd0 of=/tmp/cdproject/boot.img
   $ mkisofs -o /tmp/cdproject.iso -b boot.img /tmp/cdproject

Note: For simplicity, you can use `uname -r' to insert the current kernel version.


Multi-boot CD's

To boot multiple images from a CD, I use isolinux. It's a boot loader that runs off bootable CD's, and it's part of the syslinux package in most distributions.

isolinux requires that several files be installed onto the CD, including a configuration file. This will be demonstrated in the next several sections.


A Simple Example

We'll start by first building a small disk with just memtest86 and the contents of a system boot floppy.

  1. Create a directory to serve as the root directory of your file tree on the CD:
         $ mkdir /tmp/cdproject
  2. Create a subdirectory called isolinux:
         $ mkdir /tmp/cdproject/isolinux
  3. Copy isolinux.bin and memdisk into the isolinux directory (under RedHat 9, these files are in /usr/lib/syslinux/):
         $ cp <path_to>/isolinux.bin /tmp/cdproject/isolinux
         $ cp <path_to>/memisk /tmp/cdproject/isolinux
  4. Copy in the files and images that you'll want to boot and use:
         # Build the system boot image
         $ mkbootdisk --device /tmp/cdproject/isolinux/linux.img <kernel_version>
         # or
         $ dd if=/dev/fd0 of=/tmp/cdproject/isolinux/linux.img
    
         # Get a working image of memtest86
         $ cd /tmp
         $ wget http://www.memtest86.com/memt30.zip
         $ unzip memt30.zip
         $ mv memt86/memtest.bin /tmp/cdproject/isolinux/memtest
         $ rm -r memt86 memt30.zip
  5. Create a config file in isolinux:
         $ <favorite_flamewar_inspiring_editor> /tmp/cdproject/isolinux/isolinux.cfg
    
         default 0
         display bootmsg.txt
         prompt 1
         label 0
           localboot 0x80
         label memtest
           kernel memtest
         label linux
           kernel memdisk
           append initrd=linux.img
  6. Create a boot message file:
         $ <favorite_flamewar_inspiring_editor> /tmp/cdproject/isolinux/bootmsg.txt
    
         0) Boot from first harddisk (0x80)
         memtest) Start memtest86
         linux) Linux Bootdisk
  7. Create the iso image from everything:
         $ mkisofs -o /tmp/cdproject.iso -b isolinux/isolinux.bin \
           -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
           -boot-info-table /tmp/cdproject

You should now have an ISO image in /tmp/cdproject.iso


Booting with various methods

isolinux will boot a number of different types of systems. Here is an example of the file command on one CD I've created (the "x86 boot sector" entries are bootable):

      $ file *
      bootmsg.txt:      data
      dban040.img:      x86 boot sector, system SYSLINUX, FAT (12 bit)
      delldiag.img:     x86 boot sector
      isolinux.bin:     data
      isolinux.cfg:     ASCII text
      master.img:       x86 boot sector
      memdisk:          x86 boot sector, extended partition table
      memtest:          x86 boot sector
      ntpasswd.img:     x86 boot sector, system SYSLINUX, FAT (12 bit)
      pqmagic8.img:     x86 boot sector
      slave.img:        x86 boot sector
      splash.lss:       data
      tomsrtbt.img:     x86 boot sector

Floppy Images

To create a disk image of a floppy (1.44M or 2.88M floppy image, for example), just do a dd of the entire image, and include the image file in the isolinux.cfg file:

     label <bootlabel>
       kernel memdisk
       append initrd=image.img

As an example, here is how we would add tomsrtbt to our CD:

      # Download tomsrtbt ElTorito image
      $ cd /tmp/cdproject/isolinux
      $ wget http://www.tux.org/pub/distributions/tinylinux/tomsrtbt/tomsrtbt-2.0.103.ElTorito.288.img.bz2
      $ bunzip2 tomsrtbt-2.0.103.ElTorito.288.img.bz2

      # syslinux/isolinux only supports "plain" ISO 9660 filenames (8.3 format, and not RockRidge or Joliet)
      $ mv tomsrtbt-2.0.103.ElTorito.288.img tomsrtbt.img

      # add to isolinux.cfg file
      label tomsrtbt
         kernel memdisk
         append initrd=tomsrtbt.img
Hard Disk Images

isolinux can also be used to boot from a "hard disk image". While more complex, this certainly opens up a lot of other options. In the above example, the "delldiag.img" image is actually a 10 MB disk image. Here is an example of how a disk image like this could be created:

     $ dd if=/dev/zero of=disk.img bs=1M seek=10 count=0

     # Make a filesystem (we'll just make a DOS boot system as an example)
     $ mkdosfs /tmp/disk.img

     # Insert a boot sector into the disk image (copy the 446 byte
     # boot code from a booting system--floppy, for example)
     # For further information on its location, see this link.
     $ dd if=bootsect.img of=disk.img bs=1 count=446 seek=62 skip=62 conv=notrunc

     # Mount the disk image and copy in all the necessary data
     $ mount -oloop /tmp/disk.img /mnt/tmp
     # Copy in the data and unmount
     $ umount /mnt/tmp
Now, this disk image can be included in the isolinux.cfg file like this:
     label <disk_label>
       kernel memdisk
       append initrd=disk.img floppy c=10 h=64 s=32

Linux kernel, initrd, and rootfs

To create a Linux boot disk that contains a root filesystem, you first create a kernel that can load the initrd (initial ramdisk). Then, you create the initrd and a root filesystem. This process is a lot more complicated than most of the other boot systems. For more information, visit Paul's Boot CD.

Etherboot/PXE???

CD ISO images

As far as I know, there exist no emulators that will allow booting from an ISO image (as a file on the disc). There are actually quite a few reasons that this isn't very practical. First, the boot code would need to understand the ISO 9660 filesystem and where to find the El Torito boot code. Next it would somehow need to tell the boot code that its boundaries are really the boundaries of the ISO image located on the CD. This is where problems are likely to occur. Most ISO images are designed to be burned directly to a CD, not as a file on a CD. As a result, it is likely that the programs contained on the CD will not notice the difference, will not mount the ISO image loopback, and will not be able to find the files it is expecting to find.

It's not impossible to do, though. A carefully crafted initrd could be designed to detect the environment it is in, and work around the problem. This would involve mounting the CD as a filesystem and checking to see if it contains the expected files. If they are found, continue on as normal. If instead, it finds an ISO image file that it believes to be itself, this file is then loopback mounted somewhere else on the filesystem. This method is probably much more complex than most people will find practical.

Booting other Devices

To have isolinux boot a local hard drive or other device, use the following targets:

Device isolinux target
Next boot device localboot -1
First floppy drive localboot 0x00
Primary hard drive localboot 0x80

Other Options

There are a lot of extra options that can be used with isolinux, including color, multiple pages of instructions (as in RedHat's CD's when they boot--try hitting F7 some time, and see what they've put in), and pictures. Most of these options are detailed in the


Rescue CD's

There are a number of projects that have built rescue or toolkit CD's. Here is a list of some of them.


Other Resources

TuxRocks.com © Copyright Frank Sorenson.
All trademarks and copyrights on this page are owned by their respective owners.
Legal documents here are matters of public record.
Contact me via email at frank AT tuxrocks DOT com.