BuildISO
This page defines one of the core features of LFScript; The ability to create a Live CD.
This page is set up in way so that it can be imported into LFScript automatically, just like the pages for the other Extra packages are. Al though you should be able to run these commands yourself, it is intended for them to be executed by LFScript.
LFScript can find this software under the name buildiso
.
Sources
Note: You obviously can not download this file, it can only be created by you.
Dependencies
Installation
isolinux.cfg
This creates a default configuration file for the isolinux boot loader. If you have created a custom configuration, this file file be ignored:
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)/initramfs.cpgz quiet LABEL harddisk MENU LABEL Boot from first ^Hard disk LOCALBOOT 0x80 EOF
Init script
This creates the core initialisation script for the Live CD. It is this script that runs immediately after the Linux kernel has been loaded by the boot loader. It is responsible for locating and mounting the CD medium, mounting the root file system image and then give control to the Operating System inside that image:
cat > init.sh << "EndOfFile" #!/bin/busybox sh # Initramfs boot script 1.3 (2012-01-19) # 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 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" mount -t unionfs -o dirs=${UNIONFSOPT} unionfs ${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 clear cat chmod cp ls mkdir mknod mount umount switch_root; 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 # | Devices which could contain the mknod /dev/hda b 3 0 # | boot medium... mknod /dev/hdb b 3 64 # | mknod /dev/hdc b 22 0 # | mknod /dev/hdd b 22 64 # +---- # Create mount points for filesystems mkdir -p /mnt/medium mkdir -p /mnt/system mkdir -p /mnt/rootfs # Search for, and mount the boot medium LABEL="$(cat /boot/id_label)" for device in scd0 scd1 scd2 scd3 hda hdb hdc hdd; do mount -t iso9660 -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." exit 1 fi # Mount the system image mount -t squashfs -o ro,loop /mnt/medium/boot/${ARCH}/root.sqfs /mnt/system || { echo "FATAL: Boot medium found, but system image is missing." exit 1 } # Define where the new root filesystem will be ROOT="/mnt/rootfs" # Also needed for /usr/share/live/sec_init.sh # Select LiveCD mode unionMount # Might fall back to copyBindMount # 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 / # Eject the medium before a shutdown cat > ${ROOT}/etc/rc.d/rc0.d/S98eject << EOF #!/bin/sh if [ -x /usr/bin/cdrecord ]; then /usr/bin/cdrecord -eject dev=/dev/${DEVICE} &> /dev/null echo -e "\033[31m" echo -en "Remove the boot medium, close the tray (if any), " echo -en "then press ENTER to power off." echo -e "\033[0m" read fi EOF chmod +x ${ROOT}/etc/rc.d/rc0.d/S98eject # Overwrite /etc/fstab # FIXME: This file is specific to LFS-SVN-20120116+, could it be made portable? cat > ${ROOT}/etc/fstab << "EOF" # Begin /etc/fstab # file system mount-point type options dump fsck # order rootfs / rootfs defaults 0 0 proc /proc proc nosuid,noexec,nodev 0 0 sysfs /sys sysfs nosuid,noexec,nodev 0 0 devpts /dev/pts devpts gid=4,mode=620 0 0 tmpfs /run tmpfs defaults 0 0 devtmpfs /dev devtmpfs mode=0755,nosuid 0 0 # End /etc/fstab EOF # 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 # Switch to the new root and launch INIT! exec switch_root -c /dev/console ${ROOT} /sbin/init EndOfFile
Mount, verify and compress the system image
In order to compress the system image, it must be mounted (read-only) first:
mkdir mnt mount -o loop,ro ../rootfs-$(uname -m).img mnt
This next block performs some verification on the system image to ensure it can be used as a root file system. If you are executing the commands on this page manually, you should skip this block:
FAIL="0" if [ ! -r mnt/usr/bin/$(uname -m)-*linux-gnu-gcc ]; then echo -n "ERROR: Unable to verify image architecture; Your system image does" echo " not contain the file '/usr/bin/$(uname -m)-*linux-gnu-gcc'" FAIL="1" fi if [ ! -d mnt/etc ]; then echo "ERROR: Your system image does not contain the directory '/etc'" FAIL="1" fi if [ ! -x mnt/sbin/init ]; then echo "ERROR: Your system image does not contain the executable '/sbin/init'" FAIL="1" fi if [ ! -e mnt/dev/console ]; then echo "ERROR: Your system image does not contain the device '/dev/console'" FAIL="1" fi if [ "${FAIL}" == "1" ]; then return 1 fi
mkdir -p live/boot/{isolinux,$(uname -m)} cp -v /usr/share/syslinux/isolinux.bin live/boot/isolinux cp -v /boot/vmlinuz-* live/boot/$(uname -m)/vmlinuz cp -v /boot/config-* live/boot/$(uname -m)/config
if [ -e "mnt/usr/share/live/medium" ]; then cp -vR mnt/usr/share/live/medium/* live fi
if [ ! -e "live/boot/isolinux/isolinux.cfg" ]; then cp -v /usr/share/syslinux/menu.c32 live/boot/isolinux cp -v isolinux.cfg live/boot/isolinux fi
dd if=/dev/random of=live/boot/$(uname -m)/id_label bs=1 count=64
mkdir -pv mnt_init/{bin,boot} cp -v live/boot/$(uname -m)/id_label mnt_init/boot cp -v /bin/busybox mnt_init/bin cat init.sh > mnt_init/init sed -i "s/<ARCH>/$(uname -m)/g" mnt_init/init chmod +x mnt_init/init
cd mnt_init find . | /bin/busybox cpio -o -H newc -F ../initramfs.cpio cd ../ gzip -9 initramfs.cpio mv -v initramfs.cpio.gz live/boot/$(uname -m)/initramfs.cpgz rm -rf mnt_init
umount ./mnt rm -rf mnt
mkisofs -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
mv -v system-$(uname -m).iso /sources/buildmgr/packages rm -rf live rm -rf ${FAKEROOT}/*