Jump to content
Search

The new Ubuntu Wiki is live. Legacy content may be unavailable and page links may have changed. Read the announcement on Discourse.

Live CD customization

From Ubuntu Wiki
(Redirected from LiveCDCustomization)

Tidying

This page has been identified as needing tidying and should be reviewed for clarity, structure, and formatting.

Why customize LiveCDs

You may wish to customise the Ubuntu Desktop LiveCD to:

  • make your own Ubuntu distribution
  • show off a particular application
  • localise to a certain language
  • remove software packages
  • add software packages
  • update software packages
  • change system defaults (theme, icons, desktop background, panels, browser homepage, etc)

How to Customise the Ubuntu Desktop CD

This guide is for the Desktop LiveCD. There is another page referring to customisation of the alternative-server install CD. Also, there is a guide on how to create a LiveCD from scratch. This guide is based on customisation from an existing Ubuntu 22.04.1 LTS amd64 LiveCD.

System Requirements

  • At least 100GB GB of free disk space
  • At least 4GB RAM, much more recommended
  • xorriso, to compile a new ISO image
  • squashfs-tools, to unpack and recompile the 'live' filesystem
  • binwalk for investigating the initramfs file, if updating the boot kernel (optional)
  • casper files are required for recreating initramfs for updating the boot kernel (optional)
  • live-boot and live-boot-initramfs-tools if upgrading the boot kernel, as needed to recreate initramfs (optional)
  • QEMU/KVM, VirtualBox or VMware for testing (optional)

It is strongly recommended that you perform the customisation of a LiveCD from an installed copy of that version of Ubuntu. Some operations in this guide (noted at the relevant point) will likely fail otherwise. For example, to customise from an Ubuntu 22.04.1 LTS amd64 LiveCD, you should work on an installed copy of Ubuntu from that version. It may well be sensible to perform the update from a dedicated installation or a dedicated virtual machine as a number of operations can be disruptive to the host.

The architecture (amd64 or i386) to be stored on the LiveCD should be the same as the architecture used to perform the customization. It is not trivial to customize an amd64 LiveCD using an i386 operating system, for example. Also, the Ubuntu system you are using to create a custom image should be of the same major release version as that of the target system. Otherwise, the LiveCD may not run, and / or you may get stuck at some point during the customisation process.

Install pre-requisities

Make sure that you have installed the needed tools. This guide assumes you are going to use QEMU KVM virtualisation and complete all optional tasks.

Update the package lists:

sudo apt-get update

QEMU-KVM and Virtual Machine Manager:

sudo apt-get install apparmor apparmor-utils bridge-utils libvirt-clients libvirt-daemon-system libguestfs-tools qemu-kvm virt-manager

Strict requirements for customisation:

sudo apt-get install binwalk casper genisoimage live-boot live-boot-initramfs-tools squashfs-tools

Note that some of these packages also install dependency packages which are needed, such as xorriso. If you deviate from this guide, you may need to install some additional required packages manually.

Obtain the base system

  • Create a working folder with the image to work from.
sudo mkdir ~/custom_live_cd
sudo mv ubuntu-22.04.1-desktop-amd64.iso ~/custom_live_cd
sudo cd ~/custom_live_cd

Note: this example refers to Ubuntu 22.04.1 Desktop. Replace it with the name of your iso.

It is strongly recommended at this point that on the host / build machine you upgrade all packages at this point:

sudo apt-get dist-upgrade

Then repeat until all packages are up to date. Following this, clean and autoremove old packages:

sudo apt-get autoremove
sudo apt-get clean

Extract the physical DVD .iso contents

sudo mkdir isomount
sudo mount -o loop ubuntu-22.04.1-desktop-amd64.iso isomount

sudo mkdir extracted

We then copy the files from the mount to a working folder using the rsync command. rsync is a fast copy utility, amongst other things, and the -a switch preserves the time, date and permissions on the files. The --exclude switch excludes the compressed squash file system from the copy.

sudo rsync --exclude=/casper/filesystem.squashfs -a isomount/ extracted

Extract the SquashFS system

We now have a local copy of the DVD file system without the squashfs file, which we will want to work on separately. We extract the squashfs file to a separate local folder:

sudo unsquashfs isomount/casper/filesystem.squashfs

sudo mv squashfs-root edit

Amending the LiveCD Squash Files System

Most of the customisations in this guide rely on changing the live Ubuntu instance stored in the Squash File System. This is the basis of what will be installed on any target machine, and this also contains the packages and settings available to the user when the LiveCD is booted.

Amending this file system can be as simple as changing files, but can require package and setting changes that are best done when treating this file system as the running system. To do this, we use a tool called, chroot.

Prepare and chroot

chroot is an operation that changes the apparent root directory for the current running process and its children. In practice, for present purposes, this lets you work in a copy of a Linux file system you have in a sub-folder and update it, remove and install packages like it was the actual running system using commands like apt-get. In fact, in this guide this is almost the only reason to chroot. Other changes can just be made by amending files.

Unfortunately, significant functionality will be lost on chroot, including network functionality which is likely to be necessary for tasks such as updating and installing packages. You can avoid this issue by just binding /run instead before the chroot, which will pull your host's resolvconf info into the chroot:

sudo mount -o bind /run/ edit/run

Depending on your configuration, you may also need to copy the hosts file:

sudo cp /etc/hosts edit/etc/

The following bindings are also necessary. Before chroot:

sudo mount --bind /dev/ edit/dev

Then chroot:

sudo chroot edit

Then bind from within chroot:

mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts

The above commands will mount important directories of your host system to the edit directory. If you later decide to exit from chroot, make sure to unmount all of them before doing so (see the cleanup section below). Otherwise, your host system will become unusable until you reboot it.

Customizations

Apt

The main reason for chrooting into the edit folder is to install, update and remove apt packages, especially for updating the kernel version.

Tasks

To view installed packages by size:

dpkg-query -W --showformat='${Installed-Size}\t${Package}\n' | sort -nr | less

Installing packages:

sudo apt-get update

sudo apt-get install <package1> [<package2>]

When removing packages, use purge:

apt-get purge package-name

It is likely desirable to update all packages to the latest version, including the kernel. If it is desired to update to the latest kernel, both the build machine and the edited environment must have exactly the same kernel version to enable regeneration of the initrd file. If this is not possible, updating the kernel is not recommended. The commands are:

sudo apt-get update

sudo apt-get dist-upgrade

Note: if the kernel is updated you will need to follow the instructions for a kernel update in the separate section below, otherwise you may have obsolete files bloating the image, and boot may fail.

The number of package sources available on a LiveCD is very limited. It may therefore be necessary to temporarily edit the sources.list file in the edit file system to add sources for desired packages. This can be done before and after the chroot. It is important to remove any temporary package sources after the chroot has been done. Edit the sources file like this:

sudo gedit edit/etc/apt/sources.list

DebConf

A number of important settings, such as default user groups, are stored in the debconf database. This can be queried and edited during a chroot. debconf is not to be confused with dconf dealt with below.

To display default user groups:

echo "get passwd/user-default-groups" | debconf-communicate

To set default user groups:

echo "set passwd/user-default-groups adm cdrom dip lpadmin plugdev sambashare debian-tor lxd" | debconf-communicate

These groups are used for the creation of the LiveCD user on boot and are therefore available when running the LiveCD. Any other debconf key can be queried and edited as above.

Ending chroot and cleaning up

Before exiting chroot

Cleanup old kernel versions

Find a list of all currently installed kernel versions. An easy way to do this is to list the config files in the /boot folder:

ls -r /boot/config-*

This will provide a list. For each instance make a note of that version number. Then, list all linux packages:

dpkg --list | grep -i "linux-"

Then purge all the packages with old version numbers.

Do not purge packages with the most current kernel number:

apt-get purge <packages>

For example:

apt-get purge linux-headers-5.15.0-43 linux-headers-5.15.0-43-generic linux-image-5.15.0-43-generic linux-modules-5.15.0-43-generic linux-modules-extra-5.15.0-43-generic

If you looked into the edit/boot folder before entering chroot and updating, you will have noticed that it contained a kernel file vmlinuz and an initrd / initramfs file called initrd.img. Both are symlinks pointing at numbered versions and both were, on your working machine, broken symlinks. Before updating, there were no actual kernel or initrd files there. After updating, there are.

When you have finished cleaning up all out of date kernels per the instructions above there should be one version of an actual kernel file, and one initrd file in the edit/boot folder. These will be moved and further worked on later in these instructions.

Cleanup apt and packages

Use the following commands.

apt-get autoremove

apt clean
apt-get clean

Cleanup temporary files

rm -rf /tmp/* ~/.bash_history

rm /var/lib/dbus/machine-id
rm /sbin/initctl
dpkg-divert --rename --remove /sbin/initctl

Terminate / unmount in-chroot bindings and mounts

Unbind the in-chroot bindings set earlier:

umount /proc
umount /sys
umount /dev/pts

Exit chroot

exit

After exiting chroot

Remove further mounts and bindings set outside chroot

Execute the following commands:

sudo umount edit/run
sudo umount edit/dev

Remove any temporary package sources from sources.list

Do not forget to remove temporary package sources:

sudo gedit edit/etc/apt/sources.list

Remove bash history from Squash File System

If you performed your chroot by hand, as opposed to executing a script, then bash will have stored your keystroke history, which should be deleted.

sudo rm edit/root/.bash_history

Updating and altering the SNAP package configuration

Modern Ubuntu uses multiple package managers. As well as apt, the current version uses snap, which is a new package manager provided by Canonical with the intention of making some complex software easier to install and manage. It is desirable to update the snap packages on the LiveCD to the latest versions and it may also be desirable to add or remove packages. Updating these is complex as snapd will by default retain multiple versions of snaps even when uninstalling.

Unfortunately, snap does not yet have many deployment customisation tools or work in chroot. The best and easiest way to do this correctly at present is to use a build machine with the identical version of Ubuntu as the source LiveCD, to completely remove all snap packages and snap itself, then reinstall the desired packages. This ensures there are no old package versions and that only the desired code is installed.

The program that manages the snaps is distributed as an apt / debian package called snapd.

On the LiveCD, dummy / mount point folders exist. In addition there is a seed folder with details for an initial setup of snapd and its snaps. The snap packages are apparently duplicated - but in fact hardlinked.

Updating the snaps means firstly taking a list of all desired snap packages and dependent packages:

sudo snap list --all

Then, iterate through and disable all snaps. For each snap use the command:

sudo snap disable <snap name>

Then, iterate through all folders under /var/snap and call umount on them to unmount any folders that will cause a failure:

cd /var/snap
sudo umount <snap name>
cd /

Next, iterate through and uninstall all snaps. This may require iterating through all the snaps more than once as some snaps depend on each other and will fail until depending snaps are removed:

sudo snap remove <snap name>

Once all snaps are removed, also remove the snapd package:

sudo apt-get -y purge snapd

Check that snapd is really gone by checking that /var/snap and /var/lib/snapd no longer exist.

If it is not, redo until all snaps and snapd are gone.

Delete all the snap related files in and under /etc/systemd/system/. These should already be gone - this is just an extra step for safety and to avoid junk data in the target image. Do not delete other files. For safety, this means delete files with names that begin with the word, 'snap'.

Then, reinstall snapd:

sudo apt-get -y install snapd

Then, download each snap desired for the new image:

sudo snap download <snapname>

There will be a file with a name of the form <snapname>[_number].assert and one with a name of the form <snapname>[_number].snap. Copy the assert file to /var/lib/snapd/seed/assertions/ and then run the following command to install it:

sudo snap ack <assertion file name>

To install the snap file itself, run:

sudo snap install <snap file name>

Write an entry in /var/lib/snapd/seed/seed.yaml for each snap. The file overall begins, 'snaps:' then each entry follows as shown below, beginning with ' -'.

snaps:
  -
    name: bare
    channel: stable
    file: bare_5.snap

Once the snaps are installed, mask, stop and disable the snapd service:

sudo systemctl mask snapd.service
sudo systemctl stop snapd.service
sudo systemctl disable snapd.service

Then, rsync archive the /var/lib/snapd folder into the target image edit folder, removing the old one first. This basically copies the entire snap configuration on the build host that has just been created to the LiveCD:

sudo rm -R edit/var/lib/snapd
sudo rsync -avP /var/lib/snapd/ edit/var/lib/snapd

Hardlink all the files in the snaps folder to the seed/snaps folder. This will save space in the final squashfs image, which will respect hardlinks:

sudo ln edit/var/lib/snapd/snaps/<snapfilename> edit/var/lib/snapd/seed/snaps/<snapfilename>

Create mount points in the image - remove edit/var/snap from the image and recreate. So, edit/var/snap should contain a folder for each snap name. Each should in turn contain a folder called common, and a folder with the version number of the snap. This name can be copied from /var/snaps. Finally, create a symlink called current to the version number folder. So, there should be two folders and a symlink in the folder for each snap name.

There is an identical set of mount points under edit/snap, which should be the same but without the common folder for each entry. Also, there is a bin folder which again can be copied from /snap/bin and which contains symlinks.

Finally, the registered systemd services in the images need updating. Delete all the snap related files in and under edit/etc/systemd/system/. Copy the snap related unit files in or under /etc/systemd/system/ to edit/etc/systemd/system/, along with symlinks.

Unmask, enable and start the snapd service:

sudo systemctl unmask snapd.service
sudo systemctl enable snapd.service
sudo systemctl start snapd.service

Updating the kernel and initrd on the LiveCD proper

If you updated the kernel in the edit folder whilst in chroot you will need to update the kernel in the LiveCD proper. This will require recreation of the initrd file.

On the physical LiveCD file system, the Linux kernel is stored in the /casper subfolder. Casper is software that enables booting on diverse hardware by identifying appropriate drivers.

Copying the kernel

sudo rm extracted/casper/vmlinuz
sudo cp edit/boot/vmlinuz extracted/casper/vmlinuz
sudo chmod 644 extracted/casper/vmlinuz

This should copy the kernel currently pointed at to the /casper folder on the LiveCD. Depending on the version of the cp command used an -L switch may be necessary to make it follow the symlink:

sudo cp -L edit/boot/vmlinuz extracted/casper/vmlinuz

Extracting the current initrd file

Firstly, we need to extract the existing file to obtain required scripts using the unmkinitramfs command:

sudo mkdir initrdmount
sudo unmkinitramfs -v extracted/casper/initrd initrdmount

Copying required files to a seed folder

The following commands extract the necessary files from the existing extracted initrd file tree to enable us to create a new one which will work with the LiveCD:

sudo cp -R initrdmount/main/conf conf
sudo mv conf initrdconf
sudo cp -R initrdmount/main/scripts initrdconf/scripts

Creating a new initrd / initramfs file

With this done, the mkinitramfs command can be used to recreate the initrd file. This will draw materials from the host system, which is why the kernel versions must match precisely and why the casper, live-boot and live-boot-initramfs-tools must be installed in the host because they provide needed drivers:

sudo mkinitramfs -d initrdconf -o ninitrd
sudo rm extracted/casper/initrd
sudo mv ninitrd extracted/casper/initrd

A note on kernel versioning

This guide assumes that the reader is creating a customised LiveCD from a running installation of the same version of Ubuntu as is being customised. If the LiveCD root or the Squash File System has had the kernel updated (e.g. via chroot) then the initrd file should be created from a host running the same kernel version. Ordinarily, the host will have been updated and rebooted also. However, if for some reason the host has not been rebooted, then it is possibly to manually specify the kernel version. This will not ordinarily be necessary, however for example:

sudo mkinitramfs -d initrdconf -o ninitrd <new kernel>

Clean up the squashfs /boot folder

As set out above, there are no linux kernel nor initrd / initramfs files in the edit/boot folder until you update. There are only broken symlinks. Now we have successfully put them in the /casper folder on the physical LiveCD file system we can once again break those symlinks:

sudo rm edit/boot/initrd.img-*
sudo rm edit/boot/vmlinuz-*

Simple Customisations

These are customisations that only require file system changes without the use of chroot. Changes that require altering the initrd file or otherwise have their own sections.

Custom Wallpapers

Wallpapers are stored in /usr/share/backgrounds (so in your working environment edit/usr/share/backgrounds). New wallpapers must be copied into this folder. For example:

sudo cp Wallpaper/* edit/usr/share/backgrounds

Wallpapers are only available as choices in the settings menus if they are registered in an XML file in /usr/share/gnome-background-properties. Any suitable xml file in this folder is picked up. For example my-wallpapers.xml. Either create a new file, or add <wallpaper> elements to an existing one.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
<wallpapers>
  <wallpaper>
    <name>My Custom Stuff</name>
    <name xml:lang="en_AU">My Custom Stuff</name>
    <name xml:lang="en_GB">My Custom Stuff</name>
    <name xml:lang="en_US">My Custom Stuff</name>
    <filename>/usr/share/backgrounds/my-default.png</filename>
    <options>zoom</options>
    <pcolor>#2c001e</pcolor>
    <scolor>#2c001e</scolor>
    <shade_type>solid</shade_type>
  </wallpaper>
</wallpapers>

The default wallpaper is set in the file /usr/share/glib-2.0/schemas/10_ubuntu-settings.gschema.override (so in your working environment edit/usr/share/glib-2.0/schemas/10_ubuntu-settings.gschema.override). The default file is called, 'warty-final-ubuntu.png' and can be replaced simply with sed. The procedure for amending schema defaults is set out below under setting default GNOME desktop settings. For example -

sed -i 's/warty-final-ubuntu.png/talis-default.png/g' edit/usr/share/glib-2.0/schemas/10_ubuntu-settings.gschema.override

Changing GNOME desktop settings

Many of the desktop settings, including the default favourite applications shown on the dock and the wallpaper are stored in dconf, not to be confused with debconf used above. The dconf default settings are set up by schema files which are compiled to a dconf database by glib-2.0.

The folder /usr/share/glib-2.0/schemas (so in your working environment edit/usr/share/glib-2.0/schemas) contains the schemas as XML files, also containing default values. There are also 'override' files, which allow altering of values without changing the XML files. To change a default setting, edit the relevant XML file OR create / edit an override file. Then, recompile the default database -

glib-compile-schemas .

Performing ls on the contents of the folder will yield something like this -

00_org.gnome.shell.gschema.override
10_gnome-shell.gschema.override
10_gnome-terminal.gschema.override
10_gsettings-desktop-schemas.gschema.override
10_ubuntu-dock.gschema.override
10_ubuntu-settings.gschema.override
10_virt-manager.gschema.override
casper.gschema.override
com.canonical.unity.desktop.gschema.xml
com.canonical.Unity.Lenses.gschema.xml
com.github.libpinyin.ibus-libpinyin.gschema.xml
com.ubuntu.login-screen.gschema.xml
com.ubuntu.notifications.hub.gschema.xml
[... lots of XML files ...]

The settings come from the XML files, can be overridden by the .override files. The numbers at the start of the override filenames denote priority. Higher numbered filed override lower ones. An XML file such as org.gnome.shell.gschema.xml may look like this -

<schemalist>
  <schema id="org.gnome.shell" path="/org/gnome/shell/"
          gettext-domain="gnome-shell">
    [... lots of keys ...]
    <key name="favorite-apps" type="as">
      <default>[ 'firefox_firefox.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.gedit.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.DiskUtility.desktop', 'virt-manager.desktop' ]</default>
      <summary>List of desktop file IDs for favorite applications</summary>
      <description>
        The applications corresponding to these identifiers
        will be displayed in the favorites area.
      </description>
    </key>
    [... lots of keys ...]
  </schema>
</schemalist>

The corresponding override such as 10_ubuntu-settings.gschema.override may look something like this:


[org.gnome.shell]
favorite-apps = ['firefox_firefox.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.gedit.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.DiskUtility.desktop', 'virt-manager.desktop']

In order for desired changes to be effective, you will need to identify the setting key you want to change, find the XML file for it and any override files, and create a higher numbered override to change it. If there is no existing override, you could also change the XML, or change both anyway.

After editing the schema and / or keyfiles, delete and then recreate them using glib-compile-schemas. For example whilst in the folder -

sudo rm gschemas.compiled
sudo glib-compile-schemas .

This operation is file / folder based, meaning as long as the same version of GLIB is on the host machine, there is no need to chroot.

Setting regional defaults

Legacy Boot

Change default language of gfxboot

This customization must be done outside the chroot.

sudo apt install dpkg-dev uck
apt source gfxboot-theme-ubuntu gfxboot
cd gfxboot-theme-ubuntu*/
make DEFAULT_LANG=fi
sudo cp -af boot/* ../extract-cd/isolinux/

Change "fi" to your preferred locale. Note that this does not change which languages are available in the F2 menu. For more info about gfxboot customization, see Ubuntu Customization Kit.

  • A other way to change the default language of gfxboot without rebuild the packages is to create a file name lang in the isolinux directory containing your locale's name.
Change default keyboard

In 12.04, changing the default keyboard for a live boot is not as obvious as it used to be in 10.04 and earlier. As an example, if you want to keep the default language as English but set the default keyboard to "GB", you are going to have to edit the file /usr/lib/ubiquity/ubiquity/misc.py. If you look at the hard-coded defaults table at around line 620 it should be fairly obvious what's going on...

// In /usr/lib/ubiquity/ubiquity/misc.py line 620:
    default_keymap = {
        'ar': 'ara',
        'bs': 'ba',
        'de': 'de',
        'el': 'gr',
        'en': 'us',
etc...

You can se the default keymap for your default language by editing this table, but remember that if you update the ubiquity package on your image then any changes will be clobbered.

Also note this only works for X. To set the console keyboard:

dpkg-reconfigure keyboard-configuration

UEFI

UEFI booting uses GRUB instead of gfxboot. There's no options for changing the language or keyboard for the live session, so it's all English by default. Therefore GRUB configuration needs to be modified. In the Ubuntu Finnish Remix script this is done as follows:

sed -i '6i    loadfont /boot/grub/fonts/unicode.pf2' boot/grub/grub.cfg
sed -i '7i    set locale_dir=$prefix/locale' boot/grub/grub.cfg
sed -i '8i    set lang=fi_FI' boot/grub/grub.cfg
sed -i '9i    insmod gettext' boot/grub/grub.cfg
sed -i 's%splash%splash locale=fi_FI console-setup/layoutcode=fi%'
boot/grub/grub.cfg
sed -i 's/Try Ubuntu without installing/Kokeile Ubuntua asentamatta/'
boot/grub/grub.cfg
sed -i 's/Install Ubuntu/Asenna Ubuntu/' boot/grub/grub.cfg
sed -i 's/OEM install (for manufacturers)/OEM-asennus
(laitevalmistajille)/' boot/grub/grub.cfg
sed -i 's/Check disc for defects/Tarkista asennusmedian eheys/'
boot/grub/grub.cfg
mkdir -p boot/grub/locale/
mkdir -p boot/grub/fonts/
cp -a /boot/grub/locale/fi.mo boot/grub/locale/
cp -a /boot/grub/fonts/unicode.pf2 boot/grub/fonts/

Customization limits

After customization make sure that there are no users with an UID == 999. Otherwise your image won't boot because no initial user is available (see /usr/share/initramfs-tools/scripts/casper-bottom/25adduser, -> 'db_set passwd/user-uid 999'). This may happen, for example, after installing VirtualBox/GuestAdditions

While in chroot:

awk -F: '$3 == 999' /etc/passwd

If you get any hits, try changing the uid:

usermod -u 500 $hit

Miscellaneous Defaults

You may wish to edit the files in /etc/default to change system behavior at startup. You might also edit /etc/profile, /etc/bash.bashrc, and /etc/bash_completion to change login settings for all users on the system. You cannot directly edit defaults for the live cd user (e.g., casper, ubuntu, or user) since that account is created at boot time. You can directly edit root's default files (/root in the chroot environment).

If you wish to change the default timezone used by the live cd, run:

dpkg-reconfigure tzdata

If you have added a locale and wish to make it the default, update /etc/default/locale. You may have to compile the locale:

locale-gen new_locale
update-locale LANG=new_locale LANGUAGE=new_locale LC_ALL=new_locale

These changes must be made as root in the chroot environment.

Advanced Customizations

Removing the (Casper) Autologin

The autologin feature of the Jaunty/9.04 live CD is a bit of an on-the-fly boot-hack. After extracting the initrd.gz, you need to edit the casper-bottom/25configure_init script and then recreate the initrd.gz file, replacing the original in extract-cd/casper. The process to do so goes like this:


Now look for line 25 which has the conditional statement to test $USERNAME.

Line 25 performs a conditional evaluation and if it evaluates to true, it will execute the code within the if block. The if block contains code to modify files used in the boot process to create the live cd autologin.

To disable the autologin feature, Remove $USERNAME, but just leave the quotes. The -n modifier tests the $USERNAME string to see if it's length is non-zero. By removing the variable, and leaving two double quotes, this statement evaluates to false because the two double quotes effectively make a zero-byte string. Be sure to leave no whitespace between the quotes because whitespace will make the evaluation true and execution wil fall into the if block.

21:log_begin_msg "$DESCRIPTION"
22:
23:# Arrange for shells on virtual consoles, rather than login prompts
24:
25:if [ -n "$USERNAME" ]; then

After making the change, line 25 will look like this:

25:if [ -n "" ]; then

Save the file and quit the editor. Then, from extract-cd/casper/tempdir run the following command to re-create the initrd.gz file. There are other methods for re-creating the initrd.gz file on this page which may work also:

# cp ../initrd.gz ../initrd.gz.orig
# find . | cpio -o -H newc | gzip -9 > ../initrd.gz

This will create a new initrd.gz file with no auto login. You can then continue to remaster the CD as described on this page. Be sure to create a user and password to login with before you remaster the cd. If you do not, you will not be able to login after booting!

Also, I have read a few articles mentioning that Karmic (9.10) uses initrd.lz instead of initrd.gz. I do not know if this is true, but should mention it in case you are not getting the expected results. To unpack the initrd.lz file, you need to do this:

# cd extract-cd/casper
# mkdir lztempdir
# cd lztempdir
# lzma -dc -S .lz ../initrd.lz | cpio -imvd --no-absolute-filenames

And to re-create the initrd.lz file:

# cp ../initrd.lz ../inird.lz.orig
# find . | cpio --quiet --dereference -o -H newc | lzma -7 > ../initrd.lz

Boot init

You have to edit the files in edit/usr/share/initramfs-tools/scripts/casper-bottom/* For example you can change the hostname or the livecd user:

sudo nano edit/usr/share/initramfs-tools/scripts/casper

and edit the username or hostname:

sudo nano edit/usr/share/initramfs-tools/scripts/casper-bottom/10adduser

to edit even the livecd user's password.

If you're customizing 10.04, you need to edit variables in /etc/casper.conf for the user and host names instead of modifying the scripts

P.S. in order to obtain an encrypted password, you have to use the mkpasswd program that's shipped with whois package!

Producing the CD image

Assembling the file system

Firstly, regenerate the manifests of the SquashFS file system:

sudo chmod +w extracted/casper/filesystem.manifest
sudo chroot edit dpkg-query -W --showformat='${Package} ${Version}\n' > extracted/casper/filesystem.manifest
sudo cp extracted/casper/filesystem.manifest extracted/casper/filesystem.manifest-desktop
sudo sed -i '/ubiquity/d' extracted/casper/filesystem.manifest-desktop
sudo sed -i '/casper/d' extracted/casper/filesystem.manifest-desktop

Remove the existing SquashFS file and its signature (this will only apply if you have not followed the instructions, or have already attempted this step before):

sudo rm extracted/casper/filesystem.squashfs
sudo rm extracted/casper/filesystem.squashfs.gpg

Recreate the SquashFS file from your edited filesystem:

sudo mksquashfs edit extracted/casper/filesystem.squashfs -comp xz
sudo printf $(du -sx --block-size=1 edit | cut -f1) > extracted/casper/filesystem.size

It is desirable to sign the SquashFS file using your signing key, for example as below (replace the example signing key fingerprint with your own):

sudo gpg --local-user 2551D59A01F3022FAFB75644F440B26DF14188A2 --output extracted/casper/filesystem.squashfs.gpg --detach-sign extracted/casper/filesystem.squashfs

Update the filesystem.size file, which is needed by the installer:

sudo printf $(du -sx --block-size=1 edit | cut -f1) > extracted/casper/filesystem.size

Update the image information in extracted/README.diskdefines. An example is below:

#define DISKNAME  MyDistribution 1.1 Ubuntu Remix amd64
#define TYPE  binary
#define TYPEbinary  1
#define ARCH  amd64
#define ARCHamd64  1
#define ARCHi386  0
#define DISKNUM  1
#define DISKNUM1  1
#define TOTALNUM  0
#define TOTALNUM0  1

Remove the old md5sum.txt file and calculate new md5 sums, as follows:

cd extracted
sudo rm md5sum.txt
sudo find -type f -print0 | xargs -0 md5sum | grep -v isolinux/boot.cat | tee md5sum.txt
cd ..

Creating the ISO Image

Retrieving information about the existing image

It is necessary before building the image to extract some information and files from the source image being customised. What is needed is the boot sector image, the UEFI boot filesystem and structure information. In modern Ubuntu, the MBR boot code and the EFI image are not provided as files, but they can be extracted from the existing LiveCD image. One is simply in the boot sector of the image, the other is a partition.

Firstly, the source image can be analysed to obtain sector size and partitions using the command:

sudo fdisk -l <image name>

For example:

sudo fdisk -l ubuntu-22.04.1-desktop-amd64.iso

This will yield significant information including the offset and size of the EFI partition. For example:

ubuntu-22.04.1-desktop-amd64.iso1      64 5465119 7465056  4.1M Microsoft basic
ubuntu-22.04.1-desktop-amd64.iso2 7465120 7473615    8496  4.1M EFI System
ubuntu-22.04.1-desktop-amd64.iso3 7473616 7474215     600  4.1M Microsoft basic

Then, extract the MBR, as follows:

sudo dd bs=1 count=446 if=<image name> of=mbr.img

For example:

sudo dd bs=1 count=446 if=ubuntu-22.04.1-desktop-amd64.iso of=mbr.img

Then, extract the EFI image, as follows:

sudo dd bs=<sector size> count=<sectors in EFI partition> skip=<EFI partition offset> if=<input ISO file> of=EFI.img

For example the following, which will extract the whole EFI partition from the fdisk -l example output above into a file:

sudo dd bs=512 count=8496 skip=7465120 if=ubuntu-22.04.1-desktop-amd64.iso of=EFI.img

Now all the components are in place to create a new ISO image. The next thing to do is to create the image using the xorriso tool. In previous versions of this guide, the older mkisofs tool was used, or xorriso running in emulation mode. In this version, native xorriso is used and explained.

Firstly, xorriso can be used to analyse an existing image and output an example command that is similar to the one used to create the existing image being customised, and has all the necessary switches. The command is as follows:

sudo xorriso -indev "<image name>" -report_el_torito cmd

For example:

sudo xorriso -indev "ubuntu-22.04.1-desktop-amd64.iso" -report_el_torito cmd

Assembling the ISO file

The commands shown above will output a list of switches to be used with the xorriso command when creating the new ISO image. By default, the command will derive the MBR and EFI images necessary to create the new ISO image, from the source ISO file. As an alternative, an example command is given below with tweaks to use separate MBR and EFI image files, which has the advantage of not needing to refer to the original ISO file. All that is then necessary is to tweak slightly to use the new filesystem as the source, and to use the MBR and EFI image files extracted from the image being customised. For example:

sudo xorriso -outdev MyDistribution.iso -map extracted / -- -volid "MyDistribution 1.1 Ubuntu Remix amd64" -boot_image grub grub2_mbr=mbr.img -boot_image any partition_table=on -boot_image any partition_cyl_align=off -boot_image any partition_offset=16 -boot_image any mbr_force_bootable=on -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b EFI.img -boot_image any appended_part_as=gpt -boot_image any iso_mbr_part_type=a2a0d0ebe5b9334487c068b6b72699c7 -boot_image any cat_path='/boot.catalog' -boot_image grub bin_path='/boot/grub/i386-pc/eltorito.img' -boot_image any platform_id=0x00 -boot_image any emul_type=no_emulation -boot_image any load_size=2048 -boot_image any boot_info_table=on -boot_image grub grub2_boot_info=on -boot_image any next -boot_image any efi_path=--interval:appended_partition_2:all:: -boot_image any platform_id=0xef -boot_image any emul_type=no_emulation -boot_image any load_size=4349952

This will yield what should be a bootable ISO file. The next step, which is desirable, is to test. Then hashing and signing the image is also desirable, for example as below (replacing the public key fingerprint with your own):

sha512sum MyDistribution.iso >> MyDistribution.iso.sha512
gpg --local-user 2551D59A01F3022FAFB75644F440B26DF14188A2 --output MyDistribution.iso.sha512.gpg --detach-sign MyDistribution.iso.sha512

The ISO should boot even in secure boot because the signed Ubuntu shim is still used. However, if unsigned drivers or suchlike are added, then it may not boot in secure boot mode.

Testing the CD

Using the virtual machine environment of your choice (for example QEMU-KVM with Virtual Machine Manager) or other software such as VirtualBox, create a new bare metal virtual machine. Then mount, and boot the ISO. Test with BIOS, UEFI and UEFI with secure boot. Test an installation.

The ISO should boot even in secure boot because the signed Ubuntu shim is still used. However, if unsigned drivers or suchlike are added, then it may not boot in secure boot mode.

If it boots in all configurations, the image is ready to be burned.

Burning the image to a memory stick or other block device

Insert the memory stick and note its device id. (Note, not partition id). Then use the dd command:

sudo dd if=<input file> of=<output device>

For example:

sudo dd id=MyDistribution.iso of=/dev/sda

Ensure the device has sufficient space for the image. Also ensure that you have the correct device id before doing this as all other information on the target device will be destroyed, or at least rendered hard to retrieve without data recovery software.

Burning the image to CD

Simple! Just do:

cdrecord dev=/dev/cdrom MyDistribution.iso

Additional uses for the image

Install Ubuntu from a USB stick

Installation From Image Loaded On Hard Drive

Comments

Note
The old wiki page included an extensive comments section at the end. This has not been migrated (yet).