This post documents the steps I followed to create a customised version of the Xubuntu 19.10 live CD. I called the modified image “TU Dubuntu” (after my university, TU Dublin), but it’s really just Xubuntu with some additional software packages installed that aren’t included in the default image. The steps I followed are based on the “LiveCDCustomization” article on the Ubuntu Community Wiki.
https://help.ubuntu.com/community/LiveCDCustomization
That article isn’t specific to this version of Xubuntu and it includes a lot of optional customisations that I didn’t use, so I wrote this post to capture the specific sequence of steps that produced my working image. Also, I added a step at the end to turn the iso file into a “hybrid” image. That step wasn’t included in the article on the Ubuntu Community Image, but my image wouldn’t boot without it.
Preparing to Create the Custom Image
First, we install some required packages:
sudo apt-get -y install squashfs-tools genisoimage syslinux-utils
First, create a directory and download the original Xubuntu iso image into it:
cd ~ mkdir livecdtmp cd livecdtmp wget http://cdimages.ubuntu.com/xubuntu/releases/19.10/release/xubuntu-19.10-desktop-amd64.iso
Create a sub-directory “mnt” and mount the downloaded iso image as a loopback filesystem. A warning may be displayed saying that the filesystem has been mounted read only, which is not a problem.
mkdir mnt sudo mount -o loop xubuntu-19.10-desktop-amd64.iso mnt
Extract the contents of the installation CD from the downloaded iso image:
mkdir extract-cd sudo rsync --exclude=/casper/filesystem.squashfs -a mnt/ extract-cd
Extract the SquashFS filesystem into the current directory, then rename the root folder as “edit”:
sudo unsquashfs mnt/casper/filesystem.squashfs sudo mv squashfs-root edit
The “edit” folder will be the root directory of the chroot environment. Before chrooting into it, we copy some network configuration files into it and clone a couple of special directories as sub-directories of “edit”.
sudo cp /etc/resolv.conf edit/etc/ sudo mount -o bind /run/ edit/run sudo cp /etc/hosts edit/etc/ sudo mount --bind /dev/ edit/dev
Now, we chroot into the edit folder, mount some special filesystems, and set a couple of environment variables.
sudo chroot edit mount -t proc none /proc mount -t sysfs none /sys mount -t devpts none /dev/pts export HOME=/root export LC_ALL=C
I actually don’t really understand what the following commands do, but I ran than because they were in the original instructions and everything worked out ok!
dbus-uuidgen > /var/lib/dbus/machine-id dpkg-divert --local --rename --add /sbin/initctl ln -s /bin/true /sbin/initctl
Customising the Image
The following command runs the timezone configuration. I selected “Europe” and “Dublin”.
dpkg-reconfigure tzdata dpkg-reconfigure keyboard-configuration
Now install whatever packages are to be added using apt-get.
apt update apt-get -y install inkscape octave geany hexedit mplayer ffmpeg blender python-scipy python-matplotlib python-serial obs-studio php texlive texstudio audacity xdotool pv gphoto2 exfat-utils
Note: I intended to add the Arduino IDE to the chroot filesystem at this point, but I forgot so I had to add it in later. The required commands are included later in the process.
Cleaning Up
The following commands basically undo those commands above that I didn’t understand.
rm /var/lib/dbus/machine-id rm /sbin/initctl dpkg-divert --rename --remove /sbin/initctl
The following commands unmount the special filesystems and exit chroot.
umount /proc umount /sys umount /dev/pts exit sudo umount edit/dev sudo umount edit/run sudo umount mnt
Assembling the Modified Filesystem
Regenerate manifest:
sudo chmod +w extract-cd/casper/filesystem.manifest sudo su chroot edit dpkg-query -W --showformat='${Package} ${Version}\n' > extract-cd/casper/filesystem.manifest exit sudo cp extract-cd/casper/filesystem.manifest extract-cd/casper/filesystem.manifest-desktop sudo sed -i '/ubiquity/d' extract-cd/casper/filesystem.manifest-desktop sudo sed -i '/casper/d' extract-cd/casper/filesystem.manifest-desktop
When I was installing pacakges earlier in the process using apt-get, I forgot to also download the Arduino IDE and unpack it into the /opt directory of the chroot environment so I did it at this point instead:
wget https://downloads.arduino.cc/arduino-1.8.10-linux64.tar.xz tar xf arduino-1.8.10-linux64.tar.xz rm arduino-1.8.10-linux64.tar.xz sudo mv arduino-1.8.10 edit/opt/
The following command compresses the modified filesystem:
sudo mksquashfs edit extract-cd/casper/filesystem.squashfs
This recalculates the filesystem size:
sudo su printf $(du -sx --block-size=1 edit | cut -f1) > extract-cd/casper/filesystem.size exit
To change the image name to 'TUDubuntu 19.04 "Learned Lecturer" - Release amd64', we edit the first line of the file “extract-cd/README.diskdefines” using nano:
sudo nano extract-cd/README.diskdefines
The following command recalculates the md5sum:
cd extract-cd sudo rm md5sum.txt find -type f -print0 | sudo xargs -0 md5sum | grep -v isolinux/boot.cat | sudo tee md5sum.txt
Create the Bootable Image
This creates the iso image:
sudo mkisofs -D -r -V "$IMAGE_NAME" -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o ../TUDubuntu-19.10-desktop-amd64.iso .
This command runs isohybrid on the iso file to turn it into a “hybrid” image that will boot from a USB drive:
cd .. sudo isohybrid TUDubuntu-19.10-desktop-amd64.iso
Finally, the image needs to be copied onto a USB drive. In my case, when I plugged in my USB key it appeared as “/dev/sda”, but you must check the correct device before running the following command!!! The entire contents of the device you specify (hopefully your USB key) will be erased.
WARNING: RUNNING THE NEXT COMMAND WITHOUT CHECKING WHICH DEVICE FILE IS THE USB DRIVE MAY WIPE YOUR ENTIRE OPERATING SYSTEM. MINE IS /dev/sda BUT THERE IS NO GUARANTEE THAT WILL BE THE CASE ON OTHER SYSTEMS.
sudo dd if=TUDubuntu-19.10-desktop-amd64.iso of=/dev/sda
The previous command may take a few minutes to complete because it has to copy approximately 2.7 GB of data to the USB drive.
That’s it! The USB drive should now be ready to boot.