The attached file is a new hint which describes how to turn your LFS build
into your own Live CD.
AUTHOR: jimmy anderson ([email protected])

DATE: 2013-01-20

LICENSE: 

Portions of the instructions in this hint were derived from scripts
in the LFScript project.  These scripts are covered by the following 
license:

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

This hint is also provided under the above license terms.


SYNOPSIS: How to create a Live CD from your LFS build.

DESCRIPTION:

   This hint describes how to create a live CD from your LFS build.  The
resulting live CD can be used as an LFS/CLFS build host or for whatever 
purpose you desire.  

   Briefly, you will build your LFS system and a "squashed" version 
of it will be created.   A busybox based ramdisk will be created 
which sets up a union mount (either aufs or unionfs) of the squashed 
LFS system with a ram based file system and then the system will be 
started with the union filesystem as root. 

   unionfs and aufs are not part of the standard kernel code.   To build
a live cd you must patch your kernel to add support for one or the other.
This hint will still work without aufs or unionfs support but the result 
will not be a live CD but instead be a bootable CD (useful but
with lesser ability than a live cd).   

   This hint was verified with LFS 7.2 x86 (32 and 64 bit).  It may
(likely will) work with other LFS versions also but it only was
specifically tested with 7.2 and you are on your own to work out how 
to make it work with other LFS versions. 

   A description of each step and cut and paste for that
step is provided.  Cut and pasting should make it easier to build a live cd
but it is important that you understand what the purpose of each step
is.  Blindly cutting and pasting from this hint will probably not 
result in success.  

   Following this hint, like doing pretty much anything in LFS, has the 
potential of clobbering your system.   Before you begin, make sure 
you've saved a copy of any data that is important to you.  It's also suggested
to follow this procedure on a system that is used only by you so that any 
errors will not affect others.


ATTACHMENTS:
None

PREREQUISITES:

This hint assumes the reader is familiar with LFS.  

Much of this hint assumes that the LFS variable is properly set. So, 
when following this hint, at all times make sure LFS is set properly:

export LFS=/mnt/lfs   (or as needed for your setup)


HINT:

Step 1) Download additional needed packages.

   This step is done on the HOST (not in LFS chroot).

   You will need some additional packages.   Download the squashfs tools,
busybox and syslinux.   The squashfs tools will be needed on the host.   
The remainder of the files and patches are needed within the LFS 
system. 

#------------ Cut and Paste start
cd $LFS/sources
wget 
http://sourceforge.net/projects/squashfs/files/squashfs/squashfs4.2/squashfs4.2.tar.gz/download
wget http://www.busybox.net/downloads/busybox-1.20.2.tar.bz2
wget 
http://www.busybox.net/downloads/fixes-1.20.2/busybox-1.20.2-sys-resource.patch
wget http://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-4.06.tar.xz
#------------ Cut and Paste end

   Additionally, the addendum of this hint contains a script that is 
required for the live cd.   Save the addendum of this hint as:

$LFS/sources/init.sh

   Neither aufs nor unionfs is part of the standard kernel source so
you will need a kernel patch for either unionfs or aufs.  

   To obtain the aufs kernel patches, do the following:
   
#------------ Cut and Paste start
cd $LFS/sources
git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git \
        aufs3-standalone.git
cd aufs3-standalone.git
git checkout origin/aufs3.5
cp aufs3-*.patch ..
rm -f include/linux/Kbuild
tar cvfz $LFS/sources/aufs3.tar.gz Documentation fs include
cd ..
rm -fr aufs3-standalone.git
#------------ Cut and Paste end

   At the time of this writing, unionfs kernel patches for 
recent kernels are hard to obtain.  The most recent version from the
unionfs web site is 3.3.0-rc3.   It will not work on later kernels 
without doing some additional changes.

#------------ Cut and Paste start
cd $LFS/sources
wget 
ftp://ftp.filesystems.org/pub/unionfs/unionfs-2.x-latest/unionfs-2.5.11_for_3.3.0-rc3.diff.gz
#------------ Cut and Paste end

   This version will not work with the 3.5.2 kernel of LFS 7.2.  If you
want to use unionfs, you will need to do some additional fixing beyond 
just downloading the above patch.

   Note: You can skip the aufs/unionfs kernel patch altogether if a 
more simple bootable CD is adequate for your needs.


Step 2) Add squashfs tools to your host.   (Do this on your HOST)

   If you are running a host distribution which provides prepackaged
squashfs tools, you may be able to use them.   However they must be
at least version 4.1 to work properly with this hint.

   It is recommended however, that you build squashfs tools 4.2 from 
the source   This hint was tested with squashfs tools 4.2 and better
(xz) compression is obtained with 4.2 (compared with 4.1).  To build the
squashfs tools do:

#------------ Cut and Paste start
cd $HOME
tar xvfz $LFS/sources/squashfs4.2.tar.gz
cd squashfs4.2/squashfs-tools
sed 's@#XZ_SUPPORT@XZ_SUPPORT@g' -i Makefile
sed 's@COMP_DEFAULT = gzip@COMP_DEFAULT = xz@g' -i Makefile
make
make INSTALL_DIR=$HOME/bin install
mksquashfs -version
#------------ Cut and Paste end

The version string displayed should be 4.2.   If not, you may need to 
adjust your PATH so that $HOME/bin appears first in it.

If you are on a single user system, or if no other version of 
squashfs tools exists, squashfs tools could be installed in /usr/bin
or /usr/local/bin rather than HOME/bin.

If the lzma libraries are not installed, the build of squashfs-tools 
will fail.   To resolve it, either install the lzma libraries or 
rebuild squashfs without xz support (do that by removing the sed lines 
from the above cut and paste).   squashfs (and this hint) can operate 
properly without xz support but without xz support, the resulting 
liveCD iso size will be somewhat larger.


Step 3) Build your LFS system and kernel.

   Follow the instructions in the LFS/BLFS book and build your LFS system
as you normally would except that during the kernel build, after unpacking
the source and cd'ing into the linux directory, you apply either 
the unionfs or the aufs patches.  


To apply aufs patches:
#------------ Cut and Paste start
cat ../aufs3-kbuild.patch  |patch -Np1
cat ../aufs3-base.patch |patch -Np1
cat ../aufs3-proc_map.patch |patch -Np1
tar xvf ../aufs3.tar.gz
#------------ Cut and Paste end


OR instead apply unionfs patches:
#------------ Cut and Paste start
unionfs support is an exercise left for the reader.
#------------ Cut and Paste end

When you configure the kernel, make sure the following are enabled 
as builtins (not as modules):

   SQUASHFS support (and support for SQUASHFS XZ compressed file systems).
   UNIONFS or AUFS support.
   CDROM support (ISO9660).
   DEVTMPFS support.

   Then build and install as normal:
#------------ Cut and Paste start
make
make modules_install
cp arch/x86/boot/bzImage /boot/vmlinuz-3.5.2-lfs-7.2
#------------ Cut and Paste end


   Additionally, /etc/fstab needs some tweaks for a livecd.   
Edit /etc/fstab and comment out all hard drive mounts.
But leave the virtual filesystem mounts (/proc and such) in it:
#------------ Cut and Paste start
vi /etc/fstab
>> comment out any hard drive mounts <<
#------------ Cut and Paste end

   Build and configure the remainder of your LFS system as normal.  


Step 4) Build busybox in your LFS.

   While inside the chroot environment add busybox to your
   LFS system:  

#------------ Cut and Paste start
cd /sources
tar xvf busybox-1.20.2.tar.bz2
cd busybox-1.20.2
cat ../busybox-1.20.2-sys-resource.patch |patch -Np1
make defconfig
sed 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' -i .config

sed 's/CONFIG_FEATURE_HAVE_RPC=y/# CONFIG_FEATURE_HAVE_RPC is not set/' \
        -i .config
sed 's/CONFIG_FEATURE_MOUNT_NFS=y/# CONFIG_FEATURE_MOUNT_NFS is not set/' \
        -i .config
sed 's/CONFIG_FEATURE_INETD_RPC=y/# CONFIG_FEATURE_INETD_RPC is not set/' \
        -i .config
make
cp -v busybox /bin
#------------ Cut and Paste end


Step 5) Create ramdisk.

Do this step from inside the LFS chroot environment.   This step
creates a busybox based ramdisk.   The ramdisk does the work of
creating and mounting the union filesystem and switching to it
for the root file system.

#------------ Cut and Paste start
cd /sources
echo "LFS Live CD" >id_label
mkdir -pv mnt_init/{bin,boot}
cp -v id_label mnt_init/boot
cp -v /bin/busybox mnt_init/bin
cp init.sh mnt_init/init
sed -i "s/<ARCH>/$(uname -m)/g" mnt_init/init
chmod +x mnt_init/init

pushd mnt_init
find . | ./bin/busybox cpio -o -H newc -F ../initramfs.cpio
popd
gzip -9 initramfs.cpio
rm -rf mnt_init
mv initramfs.cpio.gz /boot/initram.fs
mv id_label /boot
#------------ Cut and Paste end


Step 6) Make a squashed version of your LFS.

   This step should be done on the HOST (not inside chroot).

   Do any needed cleanup and final tweaking of your LFS system prior to 
continuing.  Strip any binaries you want stripped, remove any build cruft, 
remove $LFS/tools, etc.   Add any additional data that you would like
to be present on the liveCD, etc.  A base LFS system (wo src) turns into only
a 120 megabyte (or thereabouts.) size iso, so there should be plenty of 
space available for extras.

   Exit the chroot and unmount any filesystems that are associated with
the $LFS directory.   At this point, it is a good idea to do a system 
shutdown and restart to ensure that the LFS directory is unused and
in a quiescent state.   Make sure LFS is set again after the reboot.


#------------ Cut and Paste start
# Set LFS value as needed...
export LFS=/mnt/lfs
cd $HOME
echo $LFS
rm -f root.sfs
sudo mksquashfs $LFS root.sfs -comp xz
#------------ Cut and Paste end

(omit the -comp xz if your squashfs tools don't support xz compression).



Step 7) Add syslinux and create CD image.

This step should be done on the HOST (not inside chroot).

Setup the isolinux configuration file:
#------------ Cut and Paste start
cd $HOME

cat > isolinux.cfg << EOF
DEFAULT menu.c32
PROMPT 0
MENU TITLE Select an option...
TIMEOUT 300

LABEL live
    MENU LABEL ^Boot the live system ($(uname -m))
    MENU DEFAULT
    KERNEL /boot/$(uname -m)/vmlinuz
    APPEND initrd=/boot/$(uname -m)/initram.fs quiet

LABEL busybox
    MENU LABEL ^Boot busybox ($(uname -m))
    KERNEL /boot/$(uname -m)/vmlinuz
    APPEND initrd=/boot/$(uname -m)/initram.fs quiet busybox

LABEL harddisk
    MENU LABEL Boot from first ^Hard disk
    LOCALBOOT 0x80

EOF
#------------ Cut and Paste end

Package the isolinux bootloader, squashed rootfs and ramdisk 
into a subdirectory:

#------------ Cut and Paste start
sudo tar xf $LFS/sources/syslinux-4.06.tar.xz
rm -fr live
mkdir -p live/boot/{isolinux,$(uname -m)}
cp -v syslinux-4.06/core/isolinux.bin live/boot/isolinux
cp -v syslinux-4.06/com32/menu/menu.c32 live/boot/isolinux
mv -v isolinux.cfg                 live/boot/isolinux

cp -v root.sfs live/boot/$(uname -m)
cp -v $LFS/boot/vmlinuz-3.5.2-lfs-7.2   live/boot/$(uname -m)/vmlinuz
cp -v $LFS/boot/id_label live/boot/$(uname -m)
cp -v $LFS/boot/initram.fs live/boot/$(uname -m)/initram.fs

#------------ Cut and Paste end

Create the live CD iso image using whatever iso creation tool you
have.   In this example, it is 'genisoimage':

#------------ Cut and Paste start
genisoimage -o system-$(uname -m).iso     \
        -b boot/isolinux/isolinux.bin \
        -c boot.cat                   \
        -no-emul-boot                 \
        -boot-load-size 4             \
        -boot-info-table              \
        -joliet -l -R                 \
        live
rm -rf live
#------------ Cut and Paste end

Step 8) Burn and boot.

Burn the iso using whatever cd writing tools you prefer.  Reboot the 
system with the CD inserted and the should boot into your live CD.

Step 9) Usage

The CD boot menu allows you to boot busybox or the livecd.   Busybox
may be useful if debugging or experimenting is needed.

You can use the livecd to inject your LFS image onto the target (
rather than rebuilding from scratch..)   First, mount
/dev/cdrom somewhere.   In the boot subdirectory in the cd image, you will
find the root.sfs file.   root.sfs is your LFS system in a squashed format.
To install it into the target, either use the unsquashfs tools to 
uncompress it onto the target system or loop mount the root.sfs 
file and then use tar or some other directory copy tool to inject
it into the target.

    

ACKNOWLEDGEMENTS:
  * The LFS from script project (http://lfscript.org/wiki/index.php/Main_Page)
  * The LFS project (http://www.linuxfromscratch.org/lfs/)

CHANGELOG:
[2013-01-20]
  * Initial hint.

ADDENDUM: v Cut and save the remainder of this file as $LFS/sources/init.sh v
#!/bin/busybox sh
#
# This file is a modified version of:
#
# Initramfs boot script 1.3.1 (2012-02-09)
# Copyright (c) 2010-2012   Marcel van den Boer
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

# FS layout at the start of this script:
# - /boot/id_label
# - /bin/busybox
# - /dev/console (created by kernel)
# - /init (this file)

set -e

ARCH="<ARCH>"

###########################################
copyBindMount() { # COPY/BIND LIVECD MODE #
###########################################

# This function bind-mounts directories which are designed to be capable of
# read-only access and copies the remaining directories to a tmpfs.
#
# The downside of this method is that the resulting root filesystem is not
# fully writable. So, for example, installation of new programs will not be
# possible.
#
# However, this function can be used without any modification to the kernel and
# is therefore perfect for use as a fallback if other options are not available.

# Mount a tmpfs where the new rootfs will be.
mount -t tmpfs tmpfs ${ROOT} # Allows remounting root in the bootscripts

# Bind mount read-only filesystems, copy the rest
cd /mnt/system
for dir in $(ls -1); do
    case ${dir} in
        lost+found)
            ;;
        bin | boot | lib | opt | sbin | usr)
            mkdir ${ROOT}/${dir}
            mount --bind ${dir} ${ROOT}/${dir}
            ;;
        *)
            cp -R ${dir} ${ROOT}
            ;;
    esac
done
cd /

##############################################
}; unionMount() { # UNIONFS/AUFS LIVECD MODE #
##############################################

# A union mount takes one or more directories and combines them transparantly
# in a third. This function creates a writable directory in memory (tmpfs) and
# uses it to overlay the read-only system image, resulting in a fully writable
# root file system.
#
# The only downside to this method is that it requires a union type filesystem
# in the kernel, which can only be accomplished by patching the kernel as there
# is no such feature in a vanilla kernel.

mkdir -p /mnt/writable
mount -t tmpfs -o rw tmpfs /mnt/writable

UNIONFSOPT="/mnt/writable=rw:/mnt/system=ro"
AUFSOPT="/mnt/writable=rw:/mnt/system=ro"
mount -t unionfs -o dirs=${UNIONFSOPT} unionfs ${ROOT} 2> /dev/null || \
mount -t aufs -o br=${AUFSOPT} none ${ROOT} 2> /dev/null || \
{
    # If UnionFS fails, fall back to copy/bind mounting
    copyBindMount
}

######################
} # END OF FUNCTIONS #
######################

# Make required applets easier to access
for applet in cat chmod cp cut grep ls mkdir mknod mount umount switch_root \
    rm mv vi cpio tar mke2fs sync fdisk dd ; do
    /bin/busybox ln /bin/busybox /bin/${applet}
done

# Clear the screen
#clear # Don't! This will clear the Linux boot logo when using a framebuffer.
       # If you want to clear the screen on boot add the "clear" command to
       # '/usr/share/live/sec_init.sh' in the system image.

# Create device nodes required to run this script
# Note: /dev/console will already be available in the ramfs
mknod /dev/null c  1  3

mknod /dev/scd0 b 11  0  # +--------
mknod /dev/scd1 b 11  1  # |
mknod /dev/scd2 b 11  2  # |
mknod /dev/scd3 b 11  3  # |
                         # |
mknod /dev/hdc  b 22  0  # |
                         # |
mknod /dev/sda  b  8  0  # |
mknod /dev/sda1 b  8  1  # |
mknod /dev/sda2 b  8  2  # |
mknod /dev/sda3 b  8  3  # |
mknod /dev/sda4 b  8  4  # |
                         # |
mknod /dev/sdb  b  8 16  # |    <----
mknod /dev/sdb1 b  8 17  # |        Devices which could be or contain the
mknod /dev/sdb2 b  8 18  # |        boot medium...
mknod /dev/sdb3 b  8 19  # |
mknod /dev/sdb4 b  8 20  # |
                         # |
mknod /dev/sdc  b  8 32  # |
mknod /dev/sdc1 b  8 33  # |
mknod /dev/sdc2 b  8 34  # |
mknod /dev/sdc3 b  8 35  # |
mknod /dev/sdc4 b  8 36  # |
                         # |
mknod /dev/sdd  b  8 48  # |
mknod /dev/sdd1 b  8 49  # |
mknod /dev/sdd2 b  8 50  # |
mknod /dev/sdd3 b  8 51  # |
mknod /dev/sdd4 b  8 52  # +--------

# Create mount points for filesystems
mkdir -p /mnt/medium
mkdir -p /mnt/system
mkdir -p /mnt/rootfs

# Mount the /proc filesystem (enables filesystem detection for 'mount')
mkdir /proc
mount -t proc proc /proc

# Invoke busybox if requested via the kernel command line.
if [ `grep -c "busybox" /proc/cmdline` -ne "0" ]; then 
    echo "Busybox requested"; 
    busybox sh
fi

# Search for, and mount the boot medium
LABEL="$(cat /boot/id_label)"
for device in $(ls /dev); do
    [ "${device}" == "console" ] && continue
    [ "${device}" == "null"    ] && continue

    mount -o ro /dev/${device} /mnt/medium 2> /dev/null && \
    if [ "$(cat /mnt/medium/boot/${ARCH}/id_label)" != "${LABEL}" ]; then
        umount /mnt/medium
    else
        DEVICE="${device}"
        break
    fi
done

if [ "${DEVICE}" == "" ]; then
    echo "FATAL: Boot medium not found."
    /bin/busybox sh
fi

# Mount the system image
mount -t squashfs -o ro,loop /mnt/medium/boot/${ARCH}/root.sfs /mnt/system || {
    echo "FATAL: Boot medium found, but system image is missing."
    /bin/busybox sh
}

# Define where the new root filesystem will be
ROOT="/mnt/rootfs" # Also needed for /usr/share/live/sec_init.sh

# Run in bootable cd mode if requested via the kernel command line.
if [ `grep -c "bootcd" /proc/cmdline` -ne "0" ]; then 
    echo "Bootcd mode (bind mount) requested"; 
    copyBindMount
else
    # Select LiveCD mode
    unionMount # Might fall back to copyBindMount
fi

# Tell LFS to skip fsck during startup:
> $ROOT/fastboot

# Get rid of / manipulations in mountfs script:
grep -v ' \/ ' $ROOT/etc/rc.d/init.d/mountfs > $ROOT/tmp/mountfs
rm -f $ROOT/etc/rc.d/init.d/mountfs
mv $ROOT/tmp/mountfs $ROOT/etc/rc.d/init.d/mountfs
chmod +x $ROOT/etc/rc.d/init.d/mountfs

# Move current mounts to directories accessible in the new root
cd /mnt
for dir in $(ls -1); do
    if [ "${dir}" != "rootfs" ]; then
        mkdir -p ${ROOT}/mnt/.boot/${dir}
        mount --move /mnt/${dir} ${ROOT}/mnt/.boot/${dir}
    fi
done
cd /

# Run secondary initialization (if the system provides it)
if [ -x ${ROOT}/usr/share/live/sec_init.sh ]; then
    . ${ROOT}/usr/share/live/sec_init.sh
fi

# Clean up
umount /proc

# Switch to the new root and launch INIT!
exec switch_root -c /dev/console ${ROOT} /sbin/init

-- 
http://linuxfromscratch.org/mailman/listinfo/hints
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to