Skip to content

repack-freebsd-iso

Adds custom files to a FreeBSD installer ISO by appending a second ISO9660 session, without rebuilding the image from scratch.

Shell · GitHub

Why

Rebuilding a multi-gigabyte FreeBSD release ISO from scratch just to add an unattended-install config or a custom package set means re-reading and re-writing every file on the disc. ISO9660 was designed for write-once/append-only optical media, though, and has a native concept of sessions -- a disc can hold several independent volume descriptors and directory trees, with the last one written being the one any reader (kernel loopback driver, mount, an installer) follows.

repack.sh exploits that instead of editing the image: it appends a second session containing only the new or changed files, and publishes a merged directory tree that points everything else back at the unmodified data already on the original image. See the multisession mechanism writeup for the full explanation, including how far the same trick carries to other OS installers (Debian preseed, RHEL kickstart, Windows Setup).

Features

  • No full rebuild -- reuses every unchanged file's on-disk extent instead of re-reading and re-writing it; only new or replaced files are written into the appended session.
  • Download and verify -- can fetch a FreeBSD release ISO directly and check its SHA-512 checksum before repacking, or repack a local .iso / .iso.xz file.
  • Unattended installer config -- grafts /etc/installerconfig, which bsdinstall reads at boot to drive a scripted install.
  • Custom distribution set -- packages files listed in a custom.mtree manifest into custom.txz and grafts it into /usr/freebsd-dist, bsdinstall's default distribution directory, so it installs alongside base.txz and kernel.txz.

Quick start

git clone https://github.com/hackagadget/repack-freebsd-iso.git
cd repack-freebsd-iso

# download FreeBSD 15.1 amd64 dvd1, verify its checksum, and repack it
./repack.sh -d

Or repack a local image instead of downloading one:

./repack.sh FreeBSD-15.1-RELEASE-amd64-dvd1.iso.xz

Both produce new.iso in the current directory, leaving the input image untouched.

Usage

repack.sh (-d [-r RELEASE] [-m MACHINE] [-a MACHINE_ARCH] [-t VARIANT]
              | <xz-compressed or plain ISO image>)
Flag Description Default
-d Download a release image instead of repacking a local one
-r RELEASE FreeBSD release to download 15.1
-m MACHINE Target machine: amd64, arm64, powerpc, riscv amd64
-a MACHINE_ARCH Machine architecture, e.g. aarch64 for arm64
-t VARIANT Image variant: bootonly, disc1, dvd1 (availability varies by machine) dvd1

What gets grafted depends on which inputs sit next to the script when it runs:

Input Grafted to Condition
installerconfig.txt /etc/installerconfig file exists and is non-empty
files/custom.mtree /usr/freebsd-dist/custom.txz file exists and is non-empty

If neither is present, the script exits with ERROR: Nothing to graft.

Prerequisites

sh, realpath, file, xz, tar, awk, fetch, sha512sum, isoinfo, and growisofs -- the last two typically come from cdrtools/dvd+rw-tools or the equivalent package on your system.