--- /dev/null
+Multiboot USB Stick with Persistence from the Command Line
+==========================================================
+
+:date: 2019-07-10 13:48
+:category: System Administration
+:tags: command line, system administration, boot, grub2, efi
+:authors: Maximilian Friedersdorff
+:summary: Creating a USB stick for booting live Linux distributions with persistence
+:status: published
+
+There exist numerous graphical tools for creating bootable USB drives. Some
+support creating USB drives that can boot into any number of Linux distributions,
+chosen at boot time. Most of them support creating a persistence file or
+partition to allow you to save files or install additional applications.
+
+Every time I need one, I find that a different one is recommended. Invariably it
+is not packaged for my current distribution.
+
+This is a set of instructions for creating a multiboot USB stick with optional
+persistence for one of the installed distributions.
+
+.. contents::
+
+Get ISOs
+--------
+
+Download whatever Live disk images you want to install. Good ones are the
+Ubuntu install images, ArchLinux, Debian etc. Software updates will consume a
+large amount of space and Kernel upgrades are likely impossible: Choose recently
+updated images.
+
+Partition USB stick
+-------------------
+Use your favourite partitioning tool to create a `FAT32` partition at the
+beginning of the drive. It needs to be large enough to contain all the disk
+images (ISOs) that you want to boot from, plus some space for the grub boot
+loader.
+
+Using fdisk:
+
+.. code-block:: console
+
+ # fdisk /dev/sdX
+
+ Welcome to fdisk (util-linux 2.34).
+ Changes will remain in memory only, until you decide to write them.
+ Be careful before using the write command.
+
+ Command (m for help): o
+ Created a new DOS disklabel with disk identifier 0xf0e82e51.
+
+ Command (m for help): n
+ Partition type
+ p primary (0 primary, 0 extended, 4 free)
+ e extended (container for logical partitions)
+ Select (default p): p
+ Partition number (1-4, default 1):
+ First sector (2048-15633407, default 2048):
+ Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-15633407, default 15633407): +2G
+
+ Created a new partition 1 of type 'Linux' and of size 2 GiB.
+ Partition #1 contains a vfat signature.
+
+ Do you want to remove the signature? [Y]es/[N]o: y
+
+ The signature will be removed by a write command.
+
+ Command (m for help): t
+ Selected partition 1
+ Hex code (type L to list all codes): b
+ Changed type of partition 'Linux' to 'W95 FAT32'.
+
+ Command (m for help): w
+ The partition table has been altered.
+ Syncing disks.
+
+The above creates a 2G partition of the `FAT32` type. My drive previously
+contained a `FAT32` file system, hence the warning.
+
+Create file system
+------------------
+Create a `FAT32` file system in the newly created partition:
+
+.. code-block:: console
+
+ # mkfs.fat -F 32 /dev/sdX1
+
+Install Grub
+------------
+
+Mount your `FAT32` partition and create a `grub` directory:
+
+.. code-block:: console
+
+ # mount /dev/sdX1 /mnt/multiboot
+ # mkdir /mnt/multiboot/grub
+
+and install grub:
+
+.. code-block:: console
+
+ # grub-install /dev/sdX \
+ --target=x86_64-efi \
+ --efi-directory=/mnt/multiboot/ \
+ --boot-directory=/mnt/multiboot/boot \
+ --removable
+
+Copy ISOs
+---------
+
+Copy all ISOs that you want to be able to boot to some location on the `FAT32`
+partition:
+
+.. code-block:: console
+
+ # mkdir /mnt/multiboot/iso_boot
+ # cp /tmp/all_my_isos/*.iso /mnt/multiboot/iso_boot/
+
+Configure Grub
+--------------
+Create a grub configuration file at `/mnt/multiboot/boot/grub/grub.cfg` and create
+one or more entries for every image that you want to boot. A grub configuration
+for booting just `Xubuntu 18.04` without persistence looks like this:
+
+.. code-block:: cfg
+
+ set timeout=10
+ set default=0
+ insmod loopback
+ insmod all_video
+
+ menuentry "Run Xubuntu 18.04 64 bit" {
+ loopback loop /iso_boot/xubuntu-18.04.2-desktop-amd64.iso
+ set gfxpayload=keep
+ linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=/iso_boot/xubuntu-18.04.2-desktop-amd64.iso quiet splash ---
+ initrd (loop)/casper/initrd
+ }
+
+
+The paths `/casper/vmlinuz` and `/casper/initrd` correspond to the locations
+of the kernel and initramfs inside the ISO respectively, which may be different
+between different distributions.
+
+You can list the content of the ISO as follows:
+
+.. code-block:: console
+
+ # modprobe loop
+ # losetup /dev/loop0 /tmp/os_image.iso
+ # partprobe /dev/loop0
+ sh: dmidecode: command not found
+ Warning: The driver descriptor says the physical block size is 2048 bytes, but Linux says it is 512 bytes.
+ # mount /dev/loop0 /mnt/tmp
+ mount: /mnt/tmp: WARNING: device write-protected, mounted read-only.
+
+You can now list the contents of the ISO with standard tools. Look for files
+which contain `vmlinuz` and `initrd` or `initramfs` in the name.
+
+The kernel options will likely also be different for different distributions.
+Ideally look at the grub configuration for the ISO that you want to install and
+copy the relevant kernel options from there.
+
+Unmount the ISO and destroy the loop device when you are done:
+
+.. code-block:: console
+
+ # umount /mnt/tmp
+ # losetup -d /dev/loop0
+
+Enable Persistence (Optional)
+-----------------------------
+
+On Ubuntu, almost certainly on Ubuntu based distributions, probably on Debian
+and friends and maybe on other distributions, you can make use of a separate
+partition on the USB stick for persistence. Setup is surprisingly trivial, but
+it will only be possible to enable this for a single installed image.
+
+Create another partition on the USB stick and format it with the file system of
+your choice:
+
+.. code-block:: console
+
+ # fdisk /dev/sdX
+
+ Welcome to fdisk (util-linux 2.34).
+ Changes will remain in memory only, until you decide to write them.
+ Be careful before using the write command.
+
+
+ Command (m for help): n
+ Partition type
+ p primary (1 primary, 0 extended, 3 free)
+ e extended (container for logical partitions)
+ Select (default p): p
+ Partition number (2-4, default 2):
+ First sector (4196352-15633407, default 4196352):
+ Last sector, +/-sectors or +/-size{K,M,G,T,P} (4196352-15633407, default 15633407): +4G
+
+ Created a new partition 2 of type 'Linux' and of size 4 GiB.
+
+ Command (m for help): w
+ The partition table has been altered.
+ Calling ioctl() to re-read partition table.
+ Syncing disks.
+
+ # mkfs.ext4 -L casper-rw /dev/sdX2
+ mke2fs 1.45.2 (27-May-2019)
+ Creating file system with 1048576 4k blocks and 262144 inodes
+ Filesystem UUID: f86ba47b-9049-4970-9050-07e95d7d0743
+ Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736
+
+ Allocating group tables: done
+ Writing inode tables: done
+ Creating journal (16384 blocks): done
+ Writing superblocks and file system accounting information: done
+
+Make sure the file system has the label `casper-rw`. The size of the partition
+needs to be large enough to hold all the changes you make. If you intend to
+update software on the USB stick you will need a few Gigabytes at least.
+
+Finally edit the grub configuration file on the USB drive to add the option
+to boot with persistence enabled:
+
+.. code-block:: cfg
+
+ menuentry "Run Xubuntu 18.04 64 bit - Persistent, in RAM" {
+ loopback loop /iso_boot/xubuntu-18.04.2-desktop-amd64.iso
+ set gfxpayload=keep
+ linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=/iso_boot/xubuntu-18.04.2-desktop-amd64.iso quiet splash persistent toram ---
+ initrd (loop)/casper/initrd
+ }
+
+
+The `persistent` option enables the persistence. The kernel (or the initramfs)
+will look for a partition labeled `casper-rw` on boot to use for the
+persistence. A bonus: the `toram` option on Ubuntu will load the contents of
+the USB stick into RAM on boot, enabling relatively snappy behaviour after the
+boot process completes.
+
+I'm not sure what the limits are on the choice of file system for the persistence
+partition. `ext4` definitely works but `f2fs`, which is otherwise a desirable
+choice, did not work out of the box. I haven't investigate further.