Skip to content

ISO 9660

ISO 9660 is the disk format behind every ISO image a hobbyist kernel gets tested from under QEMU’s -cdrom, including the one Build Systems already describes producing with grub-mkrescue, itself a wrapper around xorriso, the tool that actually assembles an ISO 9660 volume. Where ext2 and the VFS abstractions built on top of it assume a filesystem that grows, shrinks, and gets modified in place, ISO 9660 assumes exactly the opposite: a volume written once, in full, and never touched again, an assumption that shapes nearly every structural decision the format makes.

Every ISO 9660 volume reserves its first sixteen 2,048-byte sectors (the System Area) unused by the filesystem itself, historically left free for a platform-specific boot sector to occupy, and the Primary Volume Descriptor (PVD) begins immediately after, at a fixed offset of sector 16. This fixed location is deliberate: unlike ext2’s superblock, whose exact offset still has to be looked up relative to the start of a partition, software reading an ISO image needs no partition table or filesystem-specific negotiation at all to find the PVD, since every conforming volume places it at the same sector regardless of the image’s total size. The PVD carries the volume’s identifying label, its total size in logical blocks, and, critically, the address of the root directory record, the entry point every other lookup on the volume starts from.

struct iso_pvd {
uint8_t type; // 1 for Primary Volume Descriptor
char id[5]; // "CD001"
uint8_t version;
// ... reserved ...
char volume_id[32];
// ... path table locations, root directory record, ...
} __attribute__((packed));

A volume can carry more than one volume descriptor in sequence past the PVD (a Volume Descriptor Set Terminator marks the end of the list), which is the mechanism the Joliet extension uses to add long Unicode filenames alongside the PVD’s own restrictive 8.3-style names, without altering the PVD itself or breaking software that only understands the plain ISO 9660 structure.

Where ext2 scatters a file’s data across blocks tracked by an indirect-pointer tree, and threads a directory’s entries through a comparable structure, ISO 9660 stores both file data and directory contents as a single extent: one starting logical block address and a length, describing one contiguous run of sectors with nothing scattered and no indirection to resolve. A directory record itself is a fixed-format entry (identifier, extent location, extent length, flags marking it as a directory or a plain file) packed one after another inside that directory’s own extent, so listing a directory means reading its extent start-to-finish and walking these fixed-size records in sequence, not following pointers the way a linked or tree-based structure would require.

Directory record:
[len][ext addr][ext len][date][flags][name len]["FILENAME.TXT;1"]

This works cleanly only because the volume is never modified after being written: a contiguous extent is trivial to lay out once, in one pass, when the entire volume’s contents and sizes are already known ahead of time, but expensive to maintain under the kind of in-place growth and deletion ext2’s block-pointer tree and bitmap allocator exist specifically to handle. Filenames also default to the restrictive 8.3-style convention (uppercase, a limited character set, a trailing ;1 version number) unless an extension such as Joliet or Rock Ridge is present to relax it, a further consequence of the format predating the long-filename conventions later, mutable filesystems take for granted.

None of the structure above makes a volume bootable on its own; El Torito, an extension published in 1995, is specifically what does. It adds a Boot Record Volume Descriptor among the volume descriptors following the PVD, pointing to a Boot Catalog: a small table of entries, each naming a boot image already present elsewhere on the same ISO 9660 volume (itself just an ordinary file, ordinary extent, nothing structurally special about it) along with the platform ID and load address firmware should use for it. BIOS firmware reads the catalog’s default entry and loads the referenced image exactly as it would a floppy or hard-disk boot sector; UEFI firmware instead looks for an entry marked with the UEFI platform ID, typically pointing at a small FAT-formatted image (which is why mtools, unrelated to ISO 9660 itself, ends up a grub-mkrescue dependency) containing a .efi application. A single Boot Catalog commonly carries both entries side by side, which is exactly what lets one ISO image boot correctly under either firmware type without any other change to the volume.

Reading an ISO 9660 volume from a kernel driver is considerably simpler than reading ext2 specifically because there is no allocation bookkeeping to get right: no bitmap to consult before writing, no coalescing, no partially-filled block to worry about splitting, since the format is read-only in ordinary use and every structure describes exactly where its own contents already sit. The 2,048-byte sector size, larger than the 512-byte sectors most disk drivers are built expecting, is a detail worth checking for explicitly: code that assumes a fixed 512-byte sector when computing an offset into an ISO image ends up reading the wrong data entirely rather than failing with any obvious error.

  1. ^ ECMA International, ECMA-119: Volume and File Structure of CDROM for Information Interchange: the formal specification ISO 9660 is based on.
  2. ^ El Torito Bootable CD-ROM Format Specification, Version 1.0, 1995: the boot-catalog extension covered above.
  • Build Systems: the grub-mkrescue/xorriso pipeline that produces an ISO 9660 image from a kernel binary.
  • VFS: the abstraction layer a read-only driver for this format would sit behind, alongside ext2 or FAT.
  • ext2: a mutable, block-pointer-based filesystem, a useful structural contrast to this format’s write-once extents.