NAME

Sys::Export::ISO9660Hybrid - Write ISO9660 filesystem overlaid on MBR+GPT partition EFI filesystem

SYNOPSIS

my $dst= Sys::Export::ISO9660Hybrid->new(
  output => $filename_or_handle,
);   
$dst->add(...); # add directory entries, cached in memory
$dst->finish;   # builds ISO9660 & VFAT filesystem, and GPT partitions

DESCRIPTION

This module helps you generate a "isohybrid" image which is both an iso9660 image and a GPT-labeled disk image (with both 4K and 512b GPT tables) with one VFAT EFI partition. Unlike with the xorriso tool, your files are visible in both filesystems simultaneously, and the files point to the same disk extents.

This image is also capable of booting in four different modes (assuming you provide appropriate boot loaders):

Legacy BIOS, Disk

Legacy i386 BIOS executes the first 440 bytes of the first sector as i386 instructions. Those instructions are free to do whatever they want. GRUB 2 uses them to read a GPT partition label and locate a partition where "stage 1.5" of the boot loader is found. The rest of the grub boot loader then locates the EFI partition, and finds the main boot loader files in boot/grub of that volume.

Legacy BIOS, CDROM

Legacy i386 BIOS looks through the CDROM Volume Descriptor entries looking for an entry that describes an extent which is a virtual floppy disk image. It then loads that extent as if it were a floppy disk, which means it essentially just starts executing it. This image is large enough that it doesn't require GRUB to be split into two parts. GRUB then loads stage 2 from the ISO filesystem, which are the same files described by the ESP VFAT filesystem.

UEFI, Disk

UEFI expects a GPT-labeled disk with a special EFI System Partition which is formatted as VFAT and which contains a file \EFI\BOOT\BOOTX64.EFI. It executes this file as an EFI application.

UEFI, CDROM

UEFI looks through the CDROM Volume Descriptors for an entry that lists an extent of sectors containing a EFI VFAT filesystem. This extent is essentially the same as a partition. It then loads \EFI\BOOT\BOOTX64.EFI the same as if it were a disk.

All the specifications above can co-exist in the same image. CDROM images leave the first 16 sectors empty, which is enough for a GPT partition data structure, and GPT leaves the first sector empty which is enough for the 440 bytes of legacy boot code. The GPT label can list partitions that exist anywhere in the image, and the CDROM Volume Descriptors can refer to extents anywhere in the image, so the EFI partition can be referenced by each of them. Additionally, the CDROM's filesystem can refer to extents anywhere on the image, so it can refer to the bodies of VFAT files as long as they are aligned to 2KiB boundaries and not fragmented. This module takes care of all of that alignment.

CONSTRUCTORS

new

$fat= Sys::Export::ISO9660Hybrid->new($filename_or_handle);
$fat= Sys::Export::ISO9660Hybrid->new(%attrs);
$fat= Sys::Export::ISO9660Hybrid->new(\%attrs);

This takes a list of attributes as a hashref or key/value list. If there is exactly one argument, it is treated as the filename or filehandle attribute.

ATTRIBUTES

filename

Name of file (or device) to write. If the file exists it will be truncated before writing. If you want to write the filesystem amid existing data (like a partition table), pass a file handle as filehandle.

filehandle

Output filehandle to write. The file will be enlarged with truncate if needed.

iso

An instance of Sys::Export::ISO9660.

esp

An instance of Sys::Export::VFAT for the EFI System Partition (ESP).

gpt

An instance of Sys::Export::GPT aligned for 4K block sizes. A GPT for 512b block size matching the 4K one is generated during "finish". It must have one partition defined as { type => GPT_TYPE_ESP }, but you may add any number of others.

If you define other partitions, you must assign the size and leave the start_lba undefined, so that this module can choose the placement. (After "finish" you can come back to inspect the location of your partition and make other changes to the disk image.)

volume_label

Returns ISO volume_label. If written, sets both iso and esp volume label attributes to the new value. Note that while ESP is usually given a volume label like "ESP", for a removable read-only image you probably want to give it a distinct name to avoid being confused with the ESP of your installed OS on your main drive.

mbr_boot_code

File data (scalar-ref or LazyFileData|Sys::Export::LazyFileData) which will be written to the first 440 bytes of sector 0. The data can be any length; only the first 440 bytes will be used.

partitions

Shortcut for ->gpt->partitions.

METHODS

add

$dst->add(\%fileinfo);

Adds a file or directory to both VFAT and ISO filesystems. Returns the VFAT file/directroy object.

finish

$dst->finish;

Calculates the size of the ISO filesystem directories, then calculates the size of the VFAT filesystem, then updates the ISO filesystem to refer to extents within VFAT, then writes GPT and MBR partition tables.

VERSION

version 0.004

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.