Create a Custom Debian Live Environment (CD or USB)
These are steps that I used on an Ubuntu 22.04 LTS (Jammy Jellyfish) 64-bit Normal installation system to build an amd64 (64-bit) Debian 11 (Bullseye) live environment that can boot from CD or USB.
The live environment generated by this guide is bootable with legacy BIOS or modern EFI hardware.
I wrote this guide more for personal educational purposes than anything. It is not necessarily the fastest guide or the best guide for your needs. There are many other apps, tutorials, walkthroughs, and methods that better accomplish what is in this guide. [1] [2] [3] [4] [5] [6] [7] I hope this guide is helpful all the same.
Warning : I have highlighted all the places you should be in the [chroot] environment. Be careful! Running some of these commands on your local environment instead of in the chroot can damage your system.
Prerequisites
Install applications we need to build the environment.
sudo apt install \ debootstrap \ squashfs-tools \ xorriso \ isolinux \ syslinux-efi \ grub-pc-bin \ grub-efi-amd64-bin \ grub-efi-ia32-bin \ mtools \ dosfstools
Create a directory where we will store all of the files we create throughout this guide.
Bootstrap and Configure Debian
Set up the base Debian environment. I am using bullseye for my distribution and amd64 for the architecture. Consult the list of debian mirrors.
Please change the URL in this command if there is a mirror that is closer to you.
sudo debootstrap \ --arch=amd64 \ --variant=minbase \ bullseye \ $HOME/LIVE_BOOT/chroot \ http://ftp.us.debian.org/debian/
Chroot to the Debian environment we just bootstrapped.
sudo chroot $HOME/LIVE_BOOT/chroot
[chroot] Set a custom hostname for your Debian environment.
echo "debian-live" > /etc/hostname
[chroot] Install a Linux kernel of your choosing. I chose the image linux-image-amd64 . I also believe live-boot is a necessity. systemd-sys (or an equivalent) is also necessary to provide init.
apt update && \ apt install --no-install-recommends \ linux-image-amd64 \ live-boot \ systemd-sysv
[chroot] Install programs of your choosing, and then run apt clean to save some space. I use —no-install-recommends to avoid superfluous packages. You should decide what you need for your environment.
Although this article results in a relatively tiny live environment, generating an environment that is only a couple dozen MB large takes additional effort not covered in this article.
apt install --no-install-recommends \ network-manager net-tools wireless-tools wpagui \ curl openssh-client \ blackbox xserver-xorg-core xserver-xorg xinit xterm \ nano && \ apt clean
[chroot] Set the root password. root will be the only user in this live environment by default, but you may add additional users as needed.
[chroot] Exit the chroot.
Create directories that will contain files for our live environment files and scratch files.
Compress the chroot environment into a Squash filesystem.
sudo mksquashfs \ $HOME/LIVE_BOOT/chroot \ $HOME/LIVE_BOOT/staging/live/filesystem.squashfs \ -e boot
Copy the kernel and initramfs from inside the chroot to the live directory.
cp $HOME/LIVE_BOOT/chroot/boot/vmlinuz-* \ $HOME/LIVE_BOOT/staging/live/vmlinuz && \ cp $HOME/LIVE_BOOT/chroot/boot/initrd.img-* \ $HOME/LIVE_BOOT/staging/live/initrd
Prepare Boot Loader Menus
Create an ISOLINUX (Syslinux) boot menu. This boot menu is used when booting in BIOS/legacy mode.
cat $HOME/LIVE_BOOT/staging/isolinux/isolinux.cfg UI vesamenu.c32 MENU TITLE Boot Menu DEFAULT linux TIMEOUT 600 MENU RESOLUTION 640 480 MENU COLOR border 30;44 #40ffffff #a0000000 std MENU COLOR title 1;36;44 #9033ccff #a0000000 std MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all MENU COLOR unsel 37;44 #50ffffff #a0000000 std MENU COLOR help 37;40 #c0ffffff #a0000000 std MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std MENU COLOR msg07 37;40 #90ffffff #a0000000 std MENU COLOR tabmsg 31;40 #30ffffff #00000000 std LABEL linux MENU LABEL Debian Live [BIOS/ISOLINUX] MENU DEFAULT KERNEL /live/vmlinuz APPEND initrd=/live/initrd boot=live LABEL linux MENU LABEL Debian Live [BIOS/ISOLINUX] (nomodeset) MENU DEFAULT KERNEL /live/vmlinuz APPEND initrd=/live/initrd boot=live nomodeset EOF
Create a second, similar, boot menu for GRUB. This boot menu is used when booting in EFI/UEFI mode.
cat $HOME/LIVE_BOOT/staging/boot/grub/grub.cfg insmod part_gpt insmod part_msdos insmod fat insmod iso9660 insmod all_video insmod font set default="0" set timeout=30 # If X has issues finding screens, experiment with/without nomodeset. menuentry "Debian Live [EFI/GRUB]" < search --no-floppy --set=root --label DEBLIVE linux ($root)/live/vmlinuz boot=live initrd ($root)/live/initrd >menuentry "Debian Live [EFI/GRUB] (nomodeset)" < search --no-floppy --set=root --label DEBLIVE linux ($root)/live/vmlinuz boot=live nomodeset initrd ($root)/live/initrd >EOF
Copy the grub.cfg file to the EFI BOOT directory.
cp $HOME/LIVE_BOOT/staging/boot/grub/grub.cfg $HOME/LIVE_BOOT/staging/EFI/BOOT/
Create a third boot config. This config will be an early configuration file that is embedded inside GRUB in the EFI partition. This finds the root and loads the GRUB config from there.
cat $HOME/LIVE_BOOT/tmp/grub-embed.cfg if ! [ -d "$cmdpath" ]; then # On some firmware, GRUB has a wrong cmdpath when booted from an optical disc. # https://gitlab.archlinux.org/archlinux/archiso/-/issues/183 if regexp --set=1:isodevice '^(\([^)]+\))\/?[Ee][Ff][Ii]\/[Bb][Oo][Oo][Tt]\/?$' "$cmdpath"; then cmdpath="$/EFI/BOOT" fi fi configfile "$/grub.cfg" EOF
Your LIVE_BOOT directory should now roughly look like this.
LIVE_BOOT/chroot/*tons of chroot files* LIVE_BOOT/staging/live/initrd LIVE_BOOT/staging/live/vmlinuz LIVE_BOOT/staging/live/filesystem.squashfs LIVE_BOOT/staging/isolinux/isolinux.cfg LIVE_BOOT/staging/EFI/BOOT LIVE_BOOT/staging/boot/grub/grub.cfg LIVE_BOOT/staging/boot/grub/x86_64-efi
Prepare Boot Loader Files
Copy BIOS/legacy boot required files into our workspace.
cp /usr/lib/ISOLINUX/isolinux.bin "$/LIVE_BOOT/staging/isolinux/" && \ cp /usr/lib/syslinux/modules/bios/* "$/LIVE_BOOT/staging/isolinux/"
Copy EFI/modern boot required files into our workspace.
cp -r /usr/lib/grub/x86_64-efi/* "$/LIVE_BOOT/staging/boot/grub/x86_64-efi/"
Generate an EFI bootable GRUB image.
grub-mkstandalone -O i386-efi \ --modules="part_gpt part_msdos fat iso9660" \ --locales="" \ --themes="" \ --fonts="" \ --output="$HOME/LIVE_BOOT/staging/EFI/BOOT/BOOTIA32.EFI" \ "boot/grub/grub.cfg=$HOME/LIVE_BOOT/tmp/grub-embed.cfg"
grub-mkstandalone -O x86_64-efi \ --modules="part_gpt part_msdos fat iso9660" \ --locales="" \ --themes="" \ --fonts="" \ --output="$HOME/LIVE_BOOT/staging/EFI/BOOT/BOOTx64.EFI" \ "boot/grub/grub.cfg=$HOME/LIVE_BOOT/tmp/grub-embed.cfg"
Create a FAT16 UEFI boot disk image containing the EFI bootloaders.
(cd $HOME/LIVE_BOOT/staging && \ dd if=/dev/zero of=efiboot.img bs=1M count=20 && \ mkfs.vfat efiboot.img && \ mmd -i efiboot.img ::/EFI ::/EFI/BOOT && \ mcopy -vi efiboot.img \ $HOME/LIVE_BOOT/staging/EFI/BOOT/BOOTIA32.EFI \ $HOME/LIVE_BOOT/staging/EFI/BOOT/BOOTx64.EFI \ $HOME/LIVE_BOOT/staging/boot/grub/grub.cfg \ ::/EFI/BOOT/ )
Create Bootable ISO/CD
The .iso file we create can be burned to a CD-ROM (optical media) and can also be written to a USB device with dd . The process here a bit complex, but that resultant behavior is common in many modern live environments such as the Ubuntu installation .iso file.
Please note that writing an .iso file to a USB device is not the same as installing the live environment directly to a USB device.
Generate the .iso disc image file.
xorriso \ -as mkisofs \ -iso-level 3 \ -o "$/LIVE_BOOT/debian-custom.iso" \ -full-iso9660-filenames \ -volid "DEBLIVE" \ --mbr-force-bootable -partition_offset 16 \ -joliet -joliet-long -rational-rock \ -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ -eltorito-boot \ isolinux/isolinux.bin \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ --eltorito-catalog isolinux/isolinux.cat \ -eltorito-alt-boot \ -e --interval:appended_partition_2:all:: \ -no-emul-boot \ -isohybrid-gpt-basdat \ -append_partition 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B $/LIVE_BOOT/staging/efiboot.img \ "$/LIVE_BOOT/staging"
Citations
- [syslinux] Isohybrid wiki page and UEFI
- This makes me think syslinux EFI with isohybird will not work!
- See: `This is what i understand from SYSLINUX being unable to boot from ISO 9660 via UEFI.
- Note that it is not clearly expliained how we generate efiboot.img . Every major distro uses Grub and Syslinux for legacy + EFI booting.
- Decent SYSLINUX vesa menu colors.
- Some good context for grub-mkimage.