How to boot into a root filesystem stored as partition image file on a bootable DVD?

6,895

Abstract

Meanwhile, I managed to solve the problem. My key mistake was to mount the image of the root partition without write permission (as it is stored on DVD). Currently, the usual workaround for this appears to be using overlayfs and tmpfs. Additionally, it appears to be common practice to use squashfs for providing the image of the root partition.

Alternative solution

With Remastersys, there exists a package that can backup a running Debian system to a Live-DVD. While I managed to get it to build a booting DVD, I found the result not satisfying for my purposes. (Some issues: The existing system has to be modified. There was too much emphasis on reinstalling the Live-DVD and additional packages. There were too many features to be configured. On each boot of the DVD, there were two minutes of waiting for some network configuration.) Additionally, I find it hard to understand what is really going on. So I chose another way.

My solution

In the following, I give the details of what I did as root on a Ubuntu 12.04. I've stripped away any application specific elements trying to provide a concise and general example for creating a bootable DVD from a USB stick booting a Linux based on Ubuntu Core 12.04. (Because of the stripping, the code shown below is not tested. So please tell me if you find a mistake and I will fix it.)

Configuring isolinux

First the DVD filesystem structure is created within a directory CD_root (cf. Isolinux)

mkdir -p CD_root/boot/isolinux
cp /usr/lib/syslinux/isolinux.bin CD_root/boot/isolinux/

I assume that the boot partition of the bootable stick is mounted under stick_boot/ and that the kernel booted is stored there and named vmlinuz.

cp -a stick_boot/vmlinuz CD_root/boot/isolinux/
vi CD_root/boot/isolinux/isolinux.cfg

The content of isolinux.cfg is as follows:

PROMPT 1
TIMEOUT 30
DEFAULT Linux

LINUX Linux
    LINUX VMLINUZ
    APPEND root=/cdrom/rootfs.squash ro
    INITRD INITRD.IMG
  • The kernel to be loaded must be specified in uppercase letters (VMLINUZ), even if it is copied to the CD filesystem in lowercase letters.
  • The same applies to INITRD.IMG.
  • The name of the squashed image of the root filesystem of the bootable stick rootfs.squash must be specified without such changes.
  • Specifying the filename of the squashed image (instead of a device such as /dev/sda1) is enough to have it mounted using squashfs.

Building the initrd

The initrd.img used on the bootable stick must be patched. The rootfs of the bootable stick can be used to build the patched initrd. It can be protected from permanent changes by using overlayfs and tmpfs (in the same way as these will be used to provide a writable version of the squashed root filesystem stored on the DVD). I assume that the root filesystem of the bootable stick (that is to be protected from change) is mounted under stick_rootfs:

mkdir patch_tmp
mount -t tmpfs patched_files_fs patch_tmp
mkdir patch_root
mount -t overlayfs -o lowerdisk=stick_rootfs,upperdisk=patch_tmp overlayed_stick_rootfs patch_root
  • Now changes can be made safely under patch_root/.

Two modules must be added to the initrd:

cat >>patch_root/etc/initramfs-tools/modules <<!
squashfs
overlayfs
!

During the boot, the DVD must be mounted under /cdrom so that the squashed image of the root filesystem /cdrom/rootfs.squash is accessible. This is achieved with the following local-premount script:

vi patch_root/etc/initramfs-tools/scripts/local-premount/cdmount

Its content is:

#!/bin/sh

PREREQ=""

prereqs()
{
    echo "$PREREQ"
}

case $1 in
# get pre-requisites
prepreqs)
    prereqs
    exit 0
    ;;
esac

# No error checking / fallbacks for brevity, here
mkdir /cdrom
mount -t iso9660 /dev/sr0 /cdrom
exit 0

This script must be executable:

chmod +x patch_root/etc/initramfs-tools/scripts/local-premount/cdmount

The writeable view of the root filesystem is provided by a well documented script root-ro which I took with little changes from this german / english source.

cp root-ro patch_root/etc/initramfs-tools/scripts/init-bottom/root-ro
chmod +x patch_root/etc/initramfs-tools/scripts/init-bottom/root-ro

The essential changes concern the modifications applied to the fstab at the bottom of the script. I only use a single entry for the proc filesystem (I remove any entries for root / or /boot):

proc /proc proc nodev,noexec,nosuid 0 0

The patched initrd can now be built within a chroot environment on the protected root filesystem of the stick:

chroot patch_root update-initramfs -c -k 3.2.0-37-generic
  • The parameter to -k specifies the version of the booted kernel loading the initrd (the output of uname -r on the booted system on the USB stick).

Now the patched initrd can be copied to the isolinux folder:

cp patch_root/boot/initrd.img-3.2.0-37-generic CD_root/boot/isolinux/initrd.img

The changes to stick_rootfs can now be undone / forgotten:

umount patch_root
umount patch_tmp

Building the root filesystem

The squashed image of the root filesystem of the bootable stick must also be patched. Again the image of the stick is protected using overlayfs and tmpfs (reusing the directories already created):

mount -t tmpfs patched_files_fs patch_tmp
mount -t overlayfs -o lowerdisk=stick_rootfs,upperdisk=patch_tmp overlayed_stick_rootfs patch_root

Old cache files should be removed to avoid hanging / failing network configuration, when booting from DVD:

rm -f patch_root/etc/udev/rules.d/70-persistent-net.rules
rm -f patch_root/var/lib/dhcp/dhclient.eth?.leases

Optionally, the eject script from casper (as used e.g. in the DVDs produced by remastersys) could be used to eject the DVD at shutdown:

cp casper patch_root/etc/init.d/casper
chmod 755 patch_root/etc/init.d/casper
ln -s ../init.d/casper patch_root/etc/rc0.d/S89casper
ln -s ../init.d/casper patch_root/etc/rc6.d/S89casper
  • A little patch is required at the top of this script. There is a check if the system was booted by casper. If not, the script immediately exits. I 've removed this check.

The patched image can now be squashed:

mksquashfs patch_root CD_root/rootfs.squash

The changes to stick_rootfs can now again be undone / forgotten:

umount patch_root
umount patch_tmp

Creating the DVD image

Finally the iso image dvd.iso can be created:

mkisofs -iso-level 3 -quiet -r -V "STICK_DVD" -cache-inodes -J -l -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -joliet-long -o dvd.iso CD_root

That's all. The iso image is ready to be burned to a CD / DVD.

Some Warnings

  • I got to this solution mostly by trial and error. Thus, I'm not so confident, that a stable system emerges. (Still, up to now, after some tests on virtualbox and a few iMacs, this appears to be the case.)

  • The way to provide access to the content of the booting CD / DVD (cf. init script /etc/initramfs-tools/scripts/local-premount/cdmount) could certainly be improved: In the presence of multiple optical drives, probably all of them should be checked (sr?, hd?, ...). I don't know how to directly determine the device from which the CD / DVD is being booted. I feel this should be possible (maybe evaluating /sys or /proc?). Maybe, it was not even necessary to explicitly mount the booting device (another time?)? After all, its content is already being accessed when executing the init scripts.

  • The file /etc/fstab in the squashed image of the root partition could probably use an entry for the (properly mounted) CD / DVD.

  • Maybe the /boot directory on the iso image should contain the usual files and be properly mounted into the life system. This might provide more flexibility when working with the life system (such as: temporarily installing software modifying the initrd during a life session, providing better output when debugging in a life session, ...)?

Share:
6,895

Related videos on Youtube

Carsten Scholtes
Author by

Carsten Scholtes

Updated on September 18, 2022

Comments

  • Carsten Scholtes
    Carsten Scholtes over 1 year

    I have created a bootable CD from a USB stick (built from Ubuntu core 12.04 according to this example) by

    • copying the files of the USB stick's boot partition (containing vmlinuz and initrd.img) into a folder CD_root/,
    • adding isolinux to that folder (according to these instructions)
    • copying an image rootfs.part of the root partition of the USB stick into the folder and
    • using mkisofs.

    How can I boot from DVD into the image of the root partition?

    Some more details and a somewhat more precise version of the question:

    I can start booting into the init script (using virtualbox on a Ubuntu 12.04 host): With kernel parameter break=mountroot I can drop to a shell right before the image rootfs.part should be mounted and insert:

    mkdir /run/cdrom
    mount -t iso9660 /dev/sr0 /run/cdrom
    losetup /dev/loop0 /run/cdrom/rootfs.part
    mount -o ro /dev/loop0 /root
    

    How could I achieve this part (or its gist of mounting /root) automatically? Do I have to patch initrd.img (how) or are there other options such as maybe kernel parameters?

    At this point, the files inside rootfs.part are visible at root/. (They include /root/sbin/init, /root/sbin/modprobe, root/lib/modules/*, ...) I tried to continue and simulate the normal proceeding of the init script (certainly somewhat out of context):

    udevadm control --timeout=121 --exit
    mount -n -o move /dev /root/dev
    mount -n -o move /run/ /root/run
    mount -n -o move /sys /root/sys
    mount -n -o move /proc /root/proc
    exec run-init /root /sbin/init </dev/console >/dev/console 2>&1
    

    Unfortunately, this doesn't lead very far. Lots of error messages about missing modprobe and devices such as /dev/loop0 not existing appear and repeat infinitely. (Maybe the DVD should be mounted differently?)

  • Zain Patel
    Zain Patel almost 11 years
    +1 Great, detailed answer, and properly formatted. Good job. :D