How to boot into a root filesystem stored as partition image file on a bootable DVD?
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 usingsquashfs
.
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, ...)?
Related videos on Youtube
Carsten Scholtes
Updated on September 18, 2022Comments
-
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 imagerootfs.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 atroot/
. (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?) - copying the files of the USB stick's boot partition (containing vmlinuz and initrd.img) into a folder
-
Zain Patel almost 11 years+1 Great, detailed answer, and properly formatted. Good job. :D