# Custom Debian ISO Boot Chain — Technical Reference
Expert reference for building and debugging custom bootable Debian-based ISOs.
Covers hybrid MBR/GPT, live-boot, debootstrap, GRUB, ISOLINUX, Plymouth, and xorriso.
---
## 1. Hybrid MBR/GPT for USB Boot
### What is isohdpfx.bin?
The first 432 bytes of a hybrid-bootable ISO. Contains the Master Boot Record code that BIOS firmware executes when booting from USB. Different sources produce different MBR code:
| Source | First bytes | Compatibility |
|--------|-------------|---------------|
| Debian Live ISO (`dd if=debian-live.iso bs=1 count=432`) | `45 52` | Best — works on all tested hardware |
| `/usr/lib/ISOLINUX/isohdpfx.bin` | `33 ed` | Generic — fails on some UEFI hardware |
| Manually built with `isohybrid` | Varies | Unpredictable |
**Rule**: Always extract MBR from a known-working ISO. Never rely on the generic ISOLINUX one.
-isohybrid-gpt-basdat \ # Adds GPT partition for EFI
-partition_offset 16 \ # Space for GPT table — REQUIRED for UEFI
/path/to/iso/contents
```
**Critical flags**:
-`-isohybrid-gpt-basdat`: Without this, UEFI firmware won't see the EFI partition
-`-partition_offset 16`: Reserves 16 sectors for GPT. Without it, some UEFI firmware ignores the USB entirely
-`-isohybrid-mbr`: Without this, the ISO won't boot from USB at all (only CD-ROM)
### Balena Etcher
Writes the ISO byte-for-byte to USB — no reformatting, no special partition creation. If the ISO works with `dd`, it works with Etcher. If BIOS doesn't see the USB, the MBR code is wrong, not Etcher.
### Verifying hybrid structure
```bash
xxd -l 4 image.iso # MBR code (should be 45 52 for Debian Live)
| `toram` | No | Copies squashfs to RAM (faster, allows USB removal) |
| `persistence` | No | Enables writable overlay on a partition labeled "persistence" |
| `quiet` | No | Suppresses boot messages |
| `splash` | No | Enables Plymouth splash screen |
| `console=ttyS0,115200` | No | Serial console for QEMU debugging |
### Where live-boot mounts things
-`/run/live/medium` — The boot media (USB/CDROM) mount point
-`/run/live/rootfs/filesystem.squashfs` — The mounted squashfs
-`/run/live/overlay` — The tmpfs overlay for writes
### Verifying live-boot in initramfs
```bash
TMPDIR=$(mktemp -d)
unmkinitramfs /path/to/initrd.img $TMPDIR
# Check for live-boot scripts
file $TMPDIR/scripts/live # Should be "ASCII text"
# OR (some initramfs have main/ prefix)
file $TMPDIR/main/scripts/live
```
### Common failures
1.**live-boot not in initrd**: Installed in rootfs but initramfs not regenerated after
2.**Missing kernel params**: `boot=live` not in GRUB/ISOLINUX config
3.**Broken initramfs**: Built without /proc /sys /dev mounted in chroot
4.**Wrong verification**: `[ -d scripts/live ]` fails because it's a file
---
## 3. debootstrap for Installer Environments
### Variants
-`--variant=minbase`: Absolute minimum (~150MB). Only essential + apt. Good for installer squashfs.
- Default (no variant): Full base system (~300MB). More packages, fewer missing deps.
### --include limitations
debootstrap's minbase resolver is simplified and **cannot resolve complex dependency chains**. Packages like `live-boot` that depend on `initramfs-tools` which depends on many other packages will silently fail or be skipped.
**Fix**: Install complex packages via `chroot apt-get` after debootstrap completes:
selected_item_color = "#fb923c" # Selected item color
item_height = 36
item_spacing = 8
scrollbar = false
}
+ label {
left = 25%
top = 20%
width = 50%
text = "Some Text"
color = "#f7931a"
align = "center"
}
```
**IMPORTANT**: Do NOT specify `font = "Name Size"` in theme elements unless you know the exact internal font name. If GRUB can't find the font, the ENTIRE theme fails to load and you get the ugly default.