El-Torito is a standard for creating bootable optical media like CD-ROMs, DVD, or BD. It is an add-on to the ISO 9660 filesystem.
El-Torito describes different ways of booting from an optical medium. The starting point can either be an emulated floppy drive, an emulated hard disk, or a plain block address in the ISO filesystem.
The intention of this document is to explain what you need to know from the El-Torito standard to create a bootable CD with your own boot image. Details about the options for ISO 9660 image production can be found on the Mkisofs page.
El Torito Structure
El Torito booting begins by the Boot Record of the ISO 9660 filesystem at block address 0x11. See also article ISO 9660. This Boot Record points to a Boot Catalog which is stored in one or more blocks inside the ISO 9660 filesystem.
The content of Boot Record and Boot Catalog is created during filesystem production by the ISO 9660 producing software.
The Boot Catalog lists the available boot images which may be prepared for multiple system architectures, called "platforms". These images are marked either as emulated floppies, or as emulated hard disks, or as no-emulation images. In any case they are the first stage in the boot process where custom code from the ISO filesystem can be executed.
While the emulated boot images are to be interpreted by the firmware as is supposed for floppies and hard disks, the no-emulation boot images are on their own:
PC-BIOS reads from the Boot Catalog the number of blocks to load, loads them (usually to segment 07c0) and then executes them as code. As with a normal floppy or hard disk, the DL register contains the BIOS drive number.
EFI interprets the boot image as FAT filesystem and looks up a standardized file path for further processing. The file name depends on the processor type. E.g. /EFI/BOOT/BOOTIA32.EFI for 32 bit x86 and /EFI/BOOT/BOOTX64.EFI for 64 bit x86.
The original El Torito specification mentions platforms "80x86", "PowerPC", and "Mac". Boot setups based on GRUB2 and ISOLINUX use 0x00 = "80x86" for PC-BIOS, and platform id 0xef for EFI which is defined by the UEFI specification.
Creating the Structure in the ISO filesystem
The following text assumes that the ISO 9660 producing software is compatible to Mkisofs. E.g. mkisofs, genisoimage, or xorrisofs.
Mkisofs expects that the boot images are submitted as data files like any other file in the emerging ISO 9660 filesystem. Normally they are part of the directory trees which get copied into the filesystem.
In most cases the Boot Catalog is represented in the filesystem as data file, too. Its content is nevertheless composed by Mkisofs.
The boot images of ISOLINUX and GRUB2 expect to contain some information about the ISO filesystem and their own location and length. This information is called Boot Info Table and gets inserted by Mkisofs, if desired. Boot Info Table is not specified by El Torito, but is rather a convention introduced by boot loader developers.
Example of ISO Filesystem Production Run for BIOS
Put all necessary directories and files underneath directory ./prepared_for_iso . It will be copied as root directory of the ISO filesystem. Especially make the boot image for PC-BIOS available at path ./prepared_for_iso/boot/loader.sys , so that it will appear in the ISO filesystem as /boot/loader.sys .
Choose an ISO 9660 producing program and eventually its mkisofs emulation command:
prog="xorriso -as mkisofs"
Produce ISO 9660 filesystem image ./bootable.iso :
$prog -R -J -c boot/bootcat \ -b boot/loader.sys -no-emul-boot -boot-load-size 4 \ -o ./bootable.iso ./prepared_for_iso
-c boot/bootcat - Makes the Boot Catalog accessible as data file.
-b boot/loader.sys -no-emul-boot - Causes /boot/loader.sys to be listed in the emerging Boot Catalog as no-emulation boot image for PC-BIOS.
-boot-load-size 4 - Specifies the number of 512-bytes sectors to load. Four 512-byte sectors (2048 bytes) is one CD sector and is the number supported by most BIOS.
If your boot image needs updating of a Boot Info Table, then add option -boot-info-table after -boot-load-size 4.
After this production run, the emerged data file ./bootable.iso can be burned onto optical media.
Hybrid Setup for BIOS and EFI from CD/DVD and USB stick
But El Torito is interpreted by the firmware only if presented on an optical medium: CD, DVD, BD. For booting PC-BIOS and EFI from USB stick or other hard-disk-like devices, there is need for an MBR and, if desired, for a GPT.
The machine code of the MBR of SYSLINUX can be adjusted to jump with its execution onto the BIOS El Torito boot image of ISOLINUX. This is known as "isohybrid". The MBR and BIOS El Torito boot image written by grub-mkrescue have the same capability. The MBR partition table does not matter for the first stage of BIOS booting.
UEFI regulates the relation of MBR partition table and GPT. So for booting via EFI firmware, the partition tables do matter. The MBR machine code is to be ignored by EFI, unless in Legacy BIOS mode.
The most modern UEFI layout prescribes an MBR with a single partition which starts at Logical Block Address 1 and covers the whole image size. It shall have MBR partition type 0xee. In this case there is a GUID Partition Table (GPT) which in one of its partitions marks the EFI System Partition with the FAT filesystem. Neither MBR partition nor GPT partitions can lead to an address where the ISO filesystem can be mounted, unless the ISO offers a second set of volume descriptors and file tree at a higher block address. Script grub-mkrescue produces this layout for booting via EFI.
The UEFI legacy partition layout (not to be confused with Legacy BIOS mode) prescribes that the EFI System Partition shall be marked by an MBR partition of type 0xef. Other MBR partitions are permissible. E.g. one which starts at Logical Block Address 0 to make the ISO mountable. It is not allowed, nevertheless, to let the ISO partition enclose the EFI System Partition.
Several popular Linux distributions offer a layout that does not comply to either of the UEFI alternatives. The MBR marks the whole ISO by a partition of type 0x00. Another MBR partition of type 0xef marks a data file inside the ISO filesystem with the image of the EFI System Partition FAT filesystem. Nevertheless there is a GPT which also marks the EFI System Partition image file. This GPT is to be ignored by any UEFI compliant firmware. The nesting of the MBR partitions is made acceptable by giving the outer MBR partition the type 0x00, which UEFI specifies to be ignored.
Debian used for its installation image debian-7.1.0-amd64-netinst.iso the following options of xorriso's mkisofs emulation:
xorriso -as mkisofs \ ... \ -c isolinux/boot.cat \ -b isolinux/isolinux.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -isohybrid-mbr ./syslinux/usr/lib/syslinux/isohdpfx.bin \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot -isohybrid-gpt-basdat \ ... \ ./boot1 \ ...
Option -eltorito-alt-boot separates the settings for the BIOS boot image (-b) from those for the EFI boot image (-e).
The files isolinux/isolinux.bin and boot/grub/efi.img get into the ISO image from source directory ./boot1.
File ./syslinux/usr/lib/syslinux/isohdpfx.bin is copied directly from the SYSLINUX installation into the System Area of the ISO image. It contains the isohybrid MBR template. Option -isohybrid-gpt-basdat announces the FAT image boot/grub/efi.img as GPT partition.
See man 1 xorrisofs for details about the options which are in part not supported by mkisofs from cdrtools.
A BareBones Boot Image with Boot Information Table
A Boot Information Table may be put into a boot image. It starts at offset 8 and is 56 bytes long. If you are familiar with Bios Parameter Blocks, you can think of the Boot Information Table as doing a similar job.
[ORG 0x7C00] [BITS 16] start: jmp 0x0000:boot times 8-($-$$) db 0 ; Boot Information Table bi_PrimaryVolumeDescriptor resd 1 ; LBA of the Primary Volume Descriptor bi_BootFileLocation resd 1 ; LBA of the Boot File bi_BootFileLength resd 1 ; Length of the boot file in bytes bi_Checksum resd 1 ; 32 bit checksum bi_Reserved resb 40 ; Reserved 'for future standardization' boot: ; Boot code here - set segment registers etc... jmp $
If you are already familiar with boot sectors for other media, this should look quite familiar already. As usual, the first thing that the code does is jump to a known segment:offset location, where it will presumably set data and stack segment registers. I have used the times macro to provide padding for the table. This has two distinct advantages: firstly, if you decide to add anything else before the table, it will continue to reside at offset 8. Secondly, if you place more than 8 bytes worth of code before the table, you will get an assembler error. The Boot Information Table may need some explanation:
bi_PrimaryVolumeDescriptor contains the LBA address of the Primary Volume Descriptor, which contains information such as the address and length of the root directory. In practice, this value will normally be 0x10, because ISO 9660 reserves sectors 0x00-0x0F as a 'system area'. And yes - no more CHS calculations, for El-Torito no emulation mode on a modern PC, it's normally a safe bet that int 0x13 extensions are available!
bi_BootFileLocation is another LBA address containing the location of the boot file on the CD. The size of the boot file can be found (in bytes) in the bi_BootFileLength field.
bi_Checksum is a 32 bit checksum of all the 32-bit values in the boot file, starting at offset 64 (just after the boot information table).
There are some BIOS bugs that might prevent No Emulation booting from working properly on certain machines. A brief list of them is available here
The rest of the CD boot process relies on ISO 9660 rather than the El-Torito standards. After you have done the 'normal' boot sector jobs, such as setting segment registers to known values and saving the contents of DL (which contains the BIOS boot drive number), you can start reading the file system. This must happen by code in the 2k that you have available in your boot sector. The Boot Info Table tells the Logical Block Address (LBA, in units of 2k) and size of the file from where the first 2k came. So you can load more machine code from it without already having an ISO 9660 filesystem driver.
Generally, you will want to load such a driver, so that you can find and load more files of your next stage loader. You have an option here - you can either use the path tables to find a file, or perform a full directory walk.