# Debian Live

Debian booting from CD/DVD/USB without installing.

# 1 Persistence

Debian Live supports persistence, allowing to modify files and have them preserved between reboots (by default all changes made in the live system are lost on reboot).

To set it up, create a partition with filesystem label persistence and a file in its root called persistence.conf containing the text / union.

To enable it, the kernel must be booted with the persistence option. The official Debian Live ISOs don’t have this set, so you have to press the tab key to edit the boot command line and append the option persistence, then press return to boot. If you forget, then any changes you make are lost on reboot!

# 1.1 By Default

To make the persistence option the default, one can patch the ISO’s bootloader configuration. There are two different bootloaders, grub and isolinux, depending on system you might need to change both?

This is a horrible hack and not really advisable: a more principled way would be to repack with xorriso or even rebuild the whole ISO from source using the live-build tools (this allows much more extensive customisation).

# 1.1.1 grub

First extract the relevant file from the ISO:

mkdir tmp
sudo mount debian-live-13.2.0-amd64-xfce.iso tmp/
cp tmp/boot/grub/grub.cfg grub.cfg
sudo umount tmp
chmod 644 grub.cfg
ls -l grub.cfg

In this case the file is 1709 bytes long.

Then modify it. The changed version must be the same size exactly!

I added the persistence option to the default entry, and set the timeout to 5 seconds for non-interactive boot. I duplicated another entry without persistence, just in case it’s useful.

--- old/grub.cfg	2025-11-18 08:30:35.739174799 +0100
+++ new/grub.cfg	2025-11-18 08:54:30.258106482 +0100
@@ -1,7 +1,15 @@
 source /boot/grub/config.cfg
 
+set timeout_style=menu  
+set timeout=5
+
+#======================================================================
 # Live boot
 menuentry "Live system (amd64)" --hotkey=l {
+	linux	/live/vmlinuz-6.12.57+deb13-amd64 boot=live components quiet splash findiso=${iso_path} persistence
+	initrd	/live/initrd.img-6.12.57+deb13-amd64
+}
+menuentry "Live system (amd64 without persistence)" {
 	linux	/live/vmlinuz-6.12.57+deb13-amd64 boot=live components quiet splash findiso=${iso_path}
 	initrd	/live/initrd.img-6.12.57+deb13-amd64
 }

Then make sure the file size matches by deleting and/or adding comments. Luckily there is a big block of comments in the original file.

# 1.1.2 Patching grub

The next step is to patch the ISO in-place (make a backup first in case it goes horribly wrong).

Get the location of the file in the ISO with xorriso:

xorriso -indev "debian-live-13.2.0-amd64-xfce.iso" -find "/boot/grub/grub.cfg" -exec report_lba --
...
Report layout: xt , Startlba ,   Blocks , Filesize , ISO image path
File data lba:  0 ,     3675 ,        1 ,     1709 , '/boot/grub/grub.cfg'

So this file starts at 3675. ISOs have block size 2048. And note that the file size matches the earlier figure.

Now we can patch the ISO:

dd if=grub.cfg of="debian-live-13.2.0-amd64-xfce.iso" conv=notrunc bs=2048 seek=3675 count=1

And check that it worked:

mkdir tmp
sudo mount debian-live-13.2.0-amd64-xfce.iso tmp/
diff -su tmp/boot/grub/grub.cfg grub.cfg
sudo umount tmp

# 1.1.3 isolinux

Two files need to be patched here:

sudo mount debian-live-13.2.0-amd64-xfce.iso tmp/
cp tmp/isolinux/live.cfg tmp/isolinux/isolinux.cfg .
sudo umount tmp
chmod 644 live.cfg isolinux.cfg

To set a timeout for automatic boot, need to delete the existing timeout 0 from isolinux.cfg

--- old/isolinux.cfg	2025-11-18 10:27:36.238755473 +0100
+++ new/isolinux.cfg	2025-11-18 10:28:03.871006890 +0100
@@ -1,4 +1,4 @@
 include menu.cfg
 default vesamenu.c32
 prompt 0
-timeout 0
+         

(where the last line has the same length in spaces) and add it to the live.cfg, because the isolinux.cfg is too compact to add the single character required.

The live.cfg file is smaller (357 bytes) without comments, so change the labels to make space for the timeout 50 and persistence options:

--- old/live.cfg	2025-11-18 10:12:14.450780053 +0100
+++ new/live.cfg	2025-11-18 10:25:41.937701185 +0100
@@ -1,12 +1,14 @@
+timeout 50
+
 label live-amd64
-	menu label ^Live system (amd64)
+	menu label ^Live system
 	menu default
 	linux /live/vmlinuz
 	initrd /live/initrd.img
-	append boot=live components quiet splash
+	append boot=live components quiet splash persistence
 
 label live-amd64-failsafe
-	menu label Live system (amd64 fail-safe mode)
+	menu label Live system (safe)
 	linux /live/vmlinuz
 	initrd /live/initrd.img
 	append boot=live components memtest noapic noapm nodma nomce nosmp nosplash vga=788

Make sure the new files are the same sizes as the old files.

# 1.1.4 Patching isolinux

See the (patching grub)(#Patching-grub) section for more details:

xorriso -indev "debian-live-13.2.0-amd64-xfce.iso" -find "/isolinux/isolinux.cfg" -exec report_lba --
...
Report layout: xt , Startlba ,   Blocks , Filesize , ISO image path
File data lba:  0 ,    65035 ,        1 ,       57 , '/isolinux/isolinux.cfg'
dd if=isolinux.cfg of="debian-live-13.2.0-amd64-xfce.iso" conv=notrunc bs=2048 seek=65035 count=1
xorriso -indev "debian-live-13.2.0-amd64-xfce.iso" -find "/isolinux/live.cfg" -exec report_lba --
...
Report layout: xt , Startlba ,   Blocks , Filesize , ISO image path
File data lba:  0 ,    65234 ,        1 ,      357 , '/isolinux/live.cfg'
dd if=live.cfg of="debian-live-13.2.0-amd64-xfce.iso" conv=notrunc bs=2048 seek=65234 count=1

# 1.2 USB Creation

WARNING using the wrong device can irreplacably wipe out your data

Plug in a USB key, it will be completely erased by the following process.

If desktop environment did auto mounting of partitions, unmount them.

as root:

dmesg

to see the details of the newly plugged in device. For example:

[ 5878.522750] usb 2-4.1.4: new SuperSpeed USB device number 8 using xhci_hcd
[ 5878.545500] usb 2-4.1.4: New USB device found, idVendor=0951, idProduct=1666, bcdDevice= 1.10
[ 5878.545512] usb 2-4.1.4: New USB device strings: Mfr=2, Product=3, SerialNumber=4
[ 5878.545518] usb 2-4.1.4: Product: DataTraveler 3.0
[ 5878.545522] usb 2-4.1.4: Manufacturer: Kingston
[ 5878.545527] usb 2-4.1.4: SerialNumber: E0D55EA523481910C8AC009E
[ 5878.567573] usb-storage 2-4.1.4:1.0: USB Mass Storage device detected
[ 5878.567820] scsi host11: usb-storage 2-4.1.4:1.0
[ 5879.573708] scsi 11:0:0:0: Direct-Access     Kingston DataTraveler 3.0 0000 PQ: 0 ANSI: 6
[ 5879.574066] sd 11:0:0:0: Attached scsi generic sg4 type 0
[ 5879.576751] sd 11:0:0:0: [sde] 484311040 512-byte logical blocks: (248 GB/231 GiB)
[ 5879.577160] sd 11:0:0:0: [sde] Write Protect is off
[ 5879.577169] sd 11:0:0:0: [sde] Mode Sense: 23 00 00 00
[ 5879.577331] sd 11:0:0:0: [sde] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 5879.619628]  sde: sde1 sde2 sde3 sde4
[ 5879.620144] sd 11:0:0:0: [sde] Attached SCSI removable disk

This means that my USB key is /dev/sde. WARNING your device may differ; check on your own system

Now copy the patched ISO to the USB key:

WARNING using the wrong device can irreplacably wipe out your data

WARNING all data on the USB key will be lost

As root REPLACING /dev/sde with the actual USB device on your own system:

cat debian-live-13.2.0-amd64-xfce.iso > /dev/sde

WARNING using the wrong device can irreplacably wipe out your data

WARNING all data on the USB key will be lost

This can take a while, about 5mins on my system.

If desktop environment mounts any partitions, unmount them.

Then we need to add the persistence partition in ext4 format, and for convenience another partition in exFAT format that can be accessed more easily on other operating systems.

As root REPLACING /dev/sde with the actual USB device on your own system:

WARNING using the wrong device can wipe out your data

fdisk --wipe=never -t dos /dev/sde

Welcome to fdisk (util-linux 2.41).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

The device contains 'iso9660' signature and it may remain on the device. It is recommended to wipe the device with wipefs(8) or fdisk --wipe, in order to avoid possible collisions.

Command (m for help): n
Partition type
   p   primary (2 primary, 0 extended, 2 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (3,4, default 3): 
First sector (7456512-484311039, default 7456768): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (7456768-484311039, default 484311039): +128G

Created a new partition 3 of type 'Linux' and of size 128 GiB.

Command (m for help): n
Partition type
   p   primary (3 primary, 0 extended, 1 free)
   e   extended (container for logical partitions)
Select (default e): p

Selected partition 4
First sector (7456512-484311039, default 275892224): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (275892224-484311039, default 484311039): 

Created a new partition 4 of type 'Linux' and of size 99.4 GiB.

Command (m for help): t
Partition number (1-4, default 4): 
Hex code or alias (type L to list all): 7

Changed type of partition 'Linux' to 'HPFS/NTFS/exFAT'.

Command (m for help): p
Disk /dev/sde: 230.94 GiB, 247967252480 bytes, 484311040 sectors
Disk model: DataTraveler 3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xd0b28f77

Device     Boot     Start       End   Sectors  Size Id Type
/dev/sde1  *           64   7456511   7456448  3.6G  0 Empty
/dev/sde2            8068     14595      6528  3.2M ef EFI (FAT-12/16/32)
/dev/sde3         7456768 275892223 268435456  128G 83 Linux
/dev/sde4       275892224 484311039 208418816 99.4G  7 HPFS/NTFS/exFAT

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Create the filesystems on the partitions. You can choose anything you like for the exfat label, but it can’t be too long or contain special characters. It might be shown by desktop environments and other operating systems.

As root, REPLACING /dev/sde with the USB device on your own system

mkfs.ext4 -L persistence /dev/sde3
mkfs.exfat -L label /dev/sde4

Then configure the persistence partition:

mkdir tmp
mount /dev/sde3 tmp
echo "/ union" > tmp/persistence.conf
umount tmp
sync

If any partitions of the USB key mounted, unmount them. Then unplug the USB key. It should be ready to use!

# 2 References

Thanks to Thomas Schmitt for explaining the ISO patching steps:

Thanks to Vojtech Trefny for explaining the partitioning steps: