r881 - trunk

tushar at linuxfromscratch.org tushar at linuxfromscratch.org
Tue Aug 10 17:16:55 PDT 2004


Author: tushar
Date: 2004-08-10 18:16:53 -0600 (Tue, 10 Aug 2004)
New Revision: 881

Added:
   trunk/lfs-live-cd.txt
Log:
Added Hint: lfs-live-cd

Added: trunk/lfs-live-cd.txt
===================================================================
--- trunk/lfs-live-cd.txt	2004-07-27 04:24:55 UTC (rev 880)
+++ trunk/lfs-live-cd.txt	2004-08-11 00:16:53 UTC (rev 881)
@@ -0,0 +1,643 @@
+AUTHOR: Mike Hernandez <mike at culmination dot org>
+
+DATE: 2004-07-24
+
+LICENSE: GNU Free Documentation License Version 1.2
+
+SYNOPSIS: How to create a live cd with udev, NPTL, and the 2.6 kernel
+          
+
+DESCRIPTION:
+This hint describes, in detail, the process by which I created a live cd
+from a system built with the BE-LFS book (As of 2004-04-27). The reader
+should be able to follow the hint to create a live cd of their own.
+It was adapted from the "Easy" hint to work with what is currently
+the "unstable" book.
+
+PREREQUISITES:
+1. A working LFS System (and cdrtools)
+2. An LFS system built for the purpose of creating a live cd (see below)
+3. CD Writer + Media (but you knew that, I bet)
+4. Syslinux
+
+HINT:
+
+First of all you might be wondering why you need two systems to create a live 
+cd. The reason is actually quite simple. If you are like me, you optimized your
+lfs system to suit your pc (or in my case, laptop). I have a pentium 4 system,
+so all of the programs which can handle optimization have been built with:
+
+        CFLAGS='-march=pentium4' 
+
+So what's the issue? It's that I want my live cd to run on just about anything
+that can boot a cd! The programs on my current system won't run on any machine 
+that isn't a pentium 4. I actually use many more optimizations when I build,
+but here I mention the architecture because it illustrates my first point:
+
+**Remember that the system running your live cd may not be the same as your 
+working system.**
+
+It really all depends on what you want your live cd to do. You may want to
+consider optimizing everything in your live cd system for size? That's up to
+you. 
+
+Another reason you want to have a separate system is because in order to
+create the cd we make some directories and move very important files
+around. In the event that something goes wrong, having at least your
+initial working system (if not a backup of the livecd system) is essential.
+
+Ok with that out of the way, let's get to creating the cd!
+
+If you want to copy and paste commands, you should set the LIVECD
+variable set to point to the mount point of the system you are
+building:
+
+        export LIVECD=/mnt/livecd 
+
+For the purpose of the next command you might want to set LIVECDDEV as well:
+
+        export LIVECDDEV=/dev/your-drive+partition
+
+Set the ISODIR to the location where you would like to keep the image:
+
+        export ISODIR=/where/you/have/space
+
+STEP ONE: chrooting into the livecd system 
+1.  Mount your live cd system:
+
+        mkdir -p $LIVECD
+        mount $LIVECDDEV $LIVECD
+
+2.  As per the directions of the BE-LFS book which is current at
+	the time this is written, mount the virtual file systems prior 
+	to entering the chroot environment:
+		
+        mount -t proc proc $LIVECD/proc
+        mount -t sysfs sysfs $LIVECD/sys
+
+    and perform the fake mounts:
+
+        mount -f -t ramfs ramfs $LIVECD/dev
+        mount -f -t tmpfs tmpfs $LIVECD/dev/shm
+        mount -f -t devpts -o gid=4,mode=620 devpts $LIVECD/dev/pts
+
+3.  chroot into the live cd system with the command given at the end of
+    chapter 6. (NOT THE CHROOT COMMAND AT THE BEGINNING!!!):
+
+        chroot $LIVECD /usr/bin/env -i \
+        HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
+        PATH=/bin:/usr/bin:/sbin:/usr/sbin \
+        /bin/bash --login
+
+4.  mount ramfs and populate /dev
+
+        mount -n -t ramfs none /dev
+        /sbin/udevstart
+
+5.  Create essential symlinks and directories not created by udev:
+
+        ln -s /proc/self/fd /dev/fd
+        ln -s /proc/self/fd/0 /dev/stdin
+        ln -s /proc/self/fd/1 /dev/stdout
+        ln -s /proc/self/fd/2 /dev/stderr
+        ln -s /proc/kcore /dev/core
+        mkdir /dev/pts
+        mkdir /dev/shm
+
+6.  Perform the mounting of the proper virtual (kernel) file systems:
+
+        mount -t devpts -o gid=4,mode=620 none /dev/pts
+        mount -t tmpfs none /dev/shm
+
+STEP TWO: Building the kernel for your live cd
+
+Building the kernel for your live cd is not something to be taken lightly
+by even a veteran! There are options which need to be built in and others
+which can be built as modules. I assume that if you're using what is, at
+the moment, either the testing or unstable branch of the book,
+that you know how to build and configure the 2.6 kernel, just be careful! =) 
+ 
+STEP THREE: Installing cdrtools (for using isoinfo)
+  Note: The original "easy" hint allowed for the use of isoinfo.
+        The options for isoinfo have changed, however.
+        I do not use isoinfo but have left the section in tact
+        so that the directions for using it could be added later.
+        (point: you really dont need to install cdrtools)
+
+(Follow blfs instructions)
+If you are using cdrtools-2.00.3 then you may have to
+insert:
+ 
+        typedef unsigned char u8; 
+
+"ifdef linux" section of scsihack.c in order for it to compile properly.
+(see http://linuxfromscratch.org/pipermail/blfs-support/2003-July/043100.html)                                                                                
+STEP FOUR: Moving /dev /etc /home /root /tmp /var  to /fake/needwrite
+
+# What is /fake/needwrite?
+# The /fake/needwrite directory is used to hold files that must be
+# writable while the livecd is running.
+# Obviously, these files can not remain on the cd-rom, and so are moved
+# To a location from which they will be copied into a ramdisk
+
+	First we have to create this directory and the mountpoint for the ramdisk:
+
+        mkdir -p $LIVECD/fake/{needwrite,ramdisk}
+
+	Then we can move it there:
+
+        cd $LIVECD/
+        mv dev/ etc/ home/ root/ tmp/ var/ fake/needwrite/
+
+ Create symlinks /... -> /fake/needwrite/...
+
+	We have moved dev/ etc/ home/ root/ tmp/ and var/ to /fake/needwrite.
+	Now we have to create symlinks so that everything seems to be
+	as before.
+
+        cd $LIVECD/
+        ln -s fake/needwrite/dev dev
+        ln -s fake/needwrite/var var
+        ln -s fake/needwrite/tmp tmp
+        ln -s fake/needwrite/root root
+        ln -s fake/needwrite/home home
+        ln -s fake/needwrite/etc etc
+
+    now "ls -l" says:
+    dev  -> fake/needwrite/dev
+    etc  -> fake/needwrite/etc
+    home -> fake/needwrite/home
+    root -> fake/needwrite/root
+    tmp  -> fake/needwrite/tmp
+    var  -> fake/needwrite/var
+
+
+STEP FIVE: Create boot script which mounts the ramdisk
+   --------------------------------------------
+
+	Ok, we have /etc /dev /var /tmp /root /home linked to
+	/fake/needwrite which is read-only (because it's on the cd).
+	To be able to login (and to run services on runlevel x
+	which need write access to /dev /var /tmp /root /home or /etc)
+	we must call a script from our /etc/rc.d/init.d/ directory which
+	mounts a ramdisk on /fake/needwrite with write access.
+
+  The following script creates 2 ram disks, a temporary one and one
+  that will house the directories which need write permission.
+  It copies the files from the cd to the temporary ram disk,
+  and then from there to the final ram disk.
+
+  The original hint used 1 ram disk, but this caused a serious
+  problem for me. First of all, the initrd which is loaded at
+  boot time uses the first ramdisk (/dev/ram0). Therefore it
+  trying to mount /dev/ram0 somewhere else leads to "device
+  already mounted" errors. Secondly, umounting a ram disk causes
+  all of the files to be lost. The original hint unmounted the
+  ram disk and remounted it, assuming the files would still be
+  there. That did not work for me, which is why I made sure
+  that /dev/ram{0,1,2} are all present, and suggest you do the
+  same. 
+
+cat > $LIVECD/etc/rc.d/init.d/create_ramdisk << "EOF"
+#!/bin/sh
+
+# SET UP SOME VARIABLES FOR DEVICES AND DIRECTORIES
+
+dev_ram=/dev/ram1
+dev_ram2=/dev/ram2
+dir_ramdisk=/fake/ramdisk
+dir_needwrite=/fake/needwrite
+
+# SOURCE THE FUNCTIONS FILE
+
+source /etc/rc.d/init.d/functions
+
+case "$1" in
+        start)
+          
+					# CREATE THE RAM DISK
+          
+					echo "Creating ext2fs on $dev_ram ...              "
+          /sbin/mke2fs -m 0 -i 1024 -q $dev_ram > /dev/null 2>&1
+          evaluate_retval
+          sleep 1
+
+          # MOUNT THE RAM DISK
+
+          echo "Mounting ramdisk on $dir_ramdisk ...         "
+          mount -n $dev_ram $dir_ramdisk -t ext2
+          evaluate_retval
+          sleep 1
+
+          # COPY FILES TO THE RAM DISK
+
+          echo "Copying files to ramdisk ...                 "
+          cp -a $dir_needwrite/* $dir_ramdisk > /dev/null 2>&1
+          evaluate_retval
+          sleep 1
+
+          # CREATE SECOND RAMDISK
+          echo "Creating second ramdisk"
+          /sbin/mke2fs -m 0 -i 1024 -q $dev_ram2 > /dev/null 2>&1
+          evaluate_retval
+          sleep 1
+          
+          # MOUNT SECOND RAMDISK
+
+          echo "mounting second ram disk"
+          mount -n $dev_ram2 $dir_needwrite -t ext2
+          evaluate_retval
+          sleep 1
+          
+          # COPY FILES TO THE SECOND RAMDISK
+          
+          echo "copying files to the second ram disk"
+          cp -a $dir_ramdisk/* $dir_needwrite
+          evaluate_retval
+          sleep 1
+          
+          # UNMOUNT THE FIRST RAMDISK
+
+          echo "unmounting and clearing ram disks"
+          umount -n $dir_ramdisk > /dev/null 2>&1
+          blockdev --flushbufs /dev/ram1
+          evaluate_retval
+          sleep 1
+          ;;
+        *)
+          echo "Usage: $0 {start}"
+          exit 1
+          ;;
+esac
+
+EOF
+
+	Make it executable:
+
+        chmod 0755 $LIVECD/etc/rc.d/init.d/create_ramdisk
+
+	create_ramdisk should be the first script excecuted by init,
+	so we set this link:
+	/etc/rc.d/rcsysinit.d/S00create_ramdisk -> ../init.d/create_ramdisk
+
+        cd $LIVECD/etc/rc.d/rcsysinit.d
+        ln -s ../init.d/create_ramdisk S00create_ramdisk
+
+**Note: If you have another script set to run first (at S00) you should
+  move that script to start after. (Maybe to S05?)
+
+
+
+STEP SIX: Install the bootloader isolinux
+   -------------------------------
+
+	We also need a bootloader on the CD to boot the kernel and ramdisk.
+	lilo and grub are all nice but isolinux is made to boot iso images!
+	(it comes with syslinux). I assume the tarball syslinux-2.09.tar.bz2 is
+	already placed in $LIVECD/usr/src.
+
+cd $LIVECD/usr/src
+
+tar xzf syslinux-2.09.tar.gz
+mkdir $LIVECD/isolinux
+cp syslinux-2.09/isolinux.bin $LIVECD/isolinux
+
+mv $LIVECD/boot/* $LIVECD/isolinux
+cd $LIVECD/
+rmdir boot
+ln -s isolinux boot
+
+cat > $LIVECD/isolinux/isolinux.cfg << "EOF"
+default bootcd
+
+label bootcd
+  kernel lfskernel
+  append initrd=initrd.gz root=/dev/ram0 init=/linuxrc ramdisk_size=16384
+EOF
+
+STEP SEVEN: Create initial ramdisk
+   ----------------------
+
+	!!! But first we have to change /etc/fstab of the live cd system !!!
+	Delete all entries you don't need. (e.g. all /dev/hd*)
+	You only need proc (and maybe devfs, devpts)
+
+vi $LIVECD/etc/fstab
+
+	Don't worry about mounting root filesystem "/".
+	This will be mounted by linuxrc from initrd fs.
+
+	You may find it helpful to remove the following links:
+
+rm $LIVECD/etc/rc.d/rc3.d/S20network
+rm $LIVECD/etc/rc.d/rc0.d/K80network
+rm $LIVECD/etc/rc.d/rc6.d/K80network
+rm $LIVECD/etc/rc.d/rcsysinit.d/S40mountfs
+rm $LIVECD/etc/rc.d/rcsysinit.d/S30checkfs
+
+	Now we create the initrd image file and filesystem.
+
+    dd if=/dev/zero of=$LIVECD/boot/initrd bs=1024 count=6144
+    mke2fs -m 0 -i 1024 -F $LIVECD/boot/initrd
+
+    mount -o loop $LIVECD/boot/initrd $LIVECD/mnt
+    cd $LIVECD/mnt
+    mkdir bin lib dev proc mnt sys etc
+    cp $LIVECD/bin/{bash,mount,grep,umount,echo,ln,mkdir} bin/
+    cp $LIVECD/sbin/udev* bin/
+    cp $(find $LIVECD -name "test" -type f) bin/
+    cp $(find $LIVECD -name "chroot" -type f) bin/
+    cp $(find $LIVECD -name "pivot_root" -type f) bin/
+    cp $LIVECD/lib/{libncurses.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/
+
+You need the console, null, ram0, ram1 and ram2 devices!
+console and null should already be present
+but we have to create /dev/ram0, /dev/ram1 and /dev/ram2
+
+    cp -dR $LIVECD/dev/{console,null} dev/
+
+You need /etc/udev, /etc/hotplug and /etc/dev.d
+
+    cp -R $LIVECD/etc/{udev,dev.d,hotplug.d} etc/
+
+    ln -s bash bin/sh
+    ln -s test bin/[
+
+If you wish to use isoinfo instead of mount to detect the live cd you
+must also copy isoinfo into the initial ramdisk.
+
+    cp $(find $LIVECD -name "isoinfo" -type f) bin/
+
+The first program executed by the kernel is /linuxrc. As it does not
+exist we create it. Our script will find the CD in the correct
+	CD-ROM drive and then mount it as rootfs / and run /sbin/init 3.
+
+
+----------- copy & paste -------------
+
+cat > $LIVECD/mnt/linuxrc << "EOF"
+#!/bin/sh
+                                                                                
+#ID is the volume id / label of the LFS boot CD if you use /bin/isoinfo
+#or ID is a file in root of the LFS boot CD
+ID="livecd"
+TMP_MOUNT="/mnt"
+                                                                                
+PATH="/bin:/sbin:/usr/bin:/usr/sbin"
+                                                                                
+#isoinfo currently does not work
+#if [ -e "/bin/isoinfo" ]; then
+#  CHECK_TYPE="isoinfo"
+#else
+  CHECK_TYPE="try_mount"
+#fi
+                                                                                
+#***********************************MOUNT KERNEL FILESYSTEMS
+
+# Create the proc directory if it does not exist
+
+if [ ! -d "/proc/" ]; then
+  mkdir /proc
+fi
+
+# Mount the proc filesystem
+
+mount -n proc /proc -t proc
+
+# If sysfs is listed as a valid filesystem type in /proc
+# then mount it (if it doesnt then udev wont work
+# and you wont have the devices you need)
+                                                                              
+if grep -q '[[:space:]]sysfs' /proc/filesystems; then
+    if [ ! -d /sys/block ]; then
+    mount -n sysfs /sys -t sysfs
+    fi
+fi
+                                                                                
+# Create some things that sysfs does not, and should not export for us.  Feel
+# free to add devices to this list.
+
+make_extra_nodes() {
+        ln -s /proc/self/fd /dev/fd
+        ln -s /proc/self/fd/0 /dev/stdin
+        ln -s /proc/self/fd/1 /dev/stdout
+        ln -s /proc/self/fd/2 /dev/stderr
+        ln -s /proc/kcore /dev/core
+        mkdir /dev/pts
+        mkdir /dev/shm
+}
+                                                                                
+                                                                                
+if [ ! -x /sbin/hotplug ]; then
+    echo /sbin/udev > /proc/sys/kernel/hotplug
+fi
+                                                                                
+# Mount a temporary file system over /dev, so that any devices
+# made or removed during this boot don't affect the next one.
+# The reason we don't write to mtab is because we don't ever
+# want /dev to be unavailable (such as by `umount -a').
+                                                                                
+mount -n ramfs /dev -t ramfs
+                                                                                
+/sbin/udevstart
+                                                                                
+make_extra_nodes
+                                                                               
+
+# Detecting the livecd is pretty complicated, 
+# but is a very logical process
+                                                                                
+#1. Search for cdrom devices and add them to CDROM_LIST
+                                                                                
+CDROM_LIST=""
+                                                                                
+# Search in proc tree for ide cdrom devices
+# There used to be a section for devfs, but this was
+# edited for udev. Actually we should probably not
+# use /proc anymore, but use sysfs instead...
+# Perhaps in the future;)
+    
+  # Check for ide channels.
+ 
+  for ide_channel in /proc/ide/ide[0-9]
+  do
+
+    # If there are no ide channels found, then skip this
+
+    if [ ! -d "$ide_channel" ]; then
+     break
+    fi
+
+		# Try each ide device to see if we can find the cd-rom drive
+
+    for ide_device in hda hdb hdc hdd hde hdf hdg hdh hdi hdj hdk hdl hdm hdn
+    do
+      device_media_file="$ide_channel/$ide_device/media"
+      if [ -e "$device_media_file" ]; then
+        grep -i "cdrom" $device_media_file > /dev/null 2>&1
+        if [ $? -eq 0 ]; then
+            CDROM_LIST="$CDROM_LIST /dev/$ide_device"
+        fi
+      fi
+    done
+  done
+
+  # Check for scsi cds
+
+  for scsi_cdrom in /dev/scd[0-99]
+  do
+    if [ -e "$scsi_cdrom" ]; then
+      CDROM_LIST="$CDROM_LIST $scsi_cdrom"
+    fi
+  done
+fi
+                                                                                
+#2. now we try to find the LFS boot CD (we use ID as identification)
+                                                                                
+LFS_CDROM_DEVICE=""
+
+for cdrom_device in $CDROM_LIST
+do
+  if [ "$CHECK_TYPE" = "try_mount" ]; then
+    mount -n -t iso9660 ${cdrom_device} $TMP_MOUNT
+    # > /dev/null 2>&1
+    media_found=$?
+  fi
+
+	# Again, the isoinfo check here doesnt work
+	# I plan on figuring this out when I'm not lazy
+	# The livecd will work just fine without isoinfo
+	# I'm leaving this here to create less work later =)
+
+  if [ "$CHECK_TYPE" = "isoinfo" ]; then
+    isoinfo -d -i $cdrom_device > /dev/null 2>&1
+    media_found=$?
+    if [ $media_found -ne 0 ]; then
+      isoinfo -V $cdrom_device > /dev/null 2>&1
+      media_found=$?
+    fi
+  fi
+                                                                                
+  if [ $media_found -eq 0 ]; then
+                                                                                
+    echo -n "media found"
+    if [ "$CHECK_TYPE" = "try_mount" ]; then
+      [ -e "$TMP_MOUNT/$ID" ]
+      media_lfs=$?
+    fi
+    if [ "$CHECK_TYPE" = "isoinfo" ]; then
+     isoinfo -d -i $cdrom_device | grep -i "Volume id:" | grep "$ID" \
+      > /dev/null 2>&1
+      media_lfs=$?
+      if [ $media_lfs -ne 0 ]; then
+        isoinfo -V $cdrom_device | grep "$ID" > /dev/null 2>&1
+        media_lfs=$?
+      fi
+    fi
+                                                                                
+    if [ "$CHECK_TYPE" = "try_mount" ]; then
+      umount -n $cdrom_device > /dev/null 2>&1
+    fi
+                                                                                
+    if [ $media_lfs -eq 0 ]; then
+      echo ", LFS boot CD found. Ready!"
+      LFS_CDROM_DEVICE="$cdrom_device"
+      break;
+    else
+      echo ", not LFS boot CD."
+    fi
+                                                                                
+  else
+    echo "no media "
+  fi
+done
+                                                                                
+                                                                                
+#3. mount LFS CD as / (root fs)
+if [ "$LFS_CDROM_DEVICE" = "" ]; then
+                                                                                
+  echo "No LFS boot CD found!!!"
+  exit 1
+                                                                                
+else
+                                                                                
+  echo "Booting from $LFS_CDROM_DEVICE ...                  "
+                                                    
+
+	# This is the magical part that makes a livecd live!
+	# The cd is mounted and pivot_root+chroot commands
+	# are used to start the system.
+	# If you really want to know what is going on here,
+	# You should read the chroot and pivot_root man pages                            
+  mount -n -o ro -t iso9660 $LFS_CDROM_DEVICE $TMP_MOUNT
+  cd $TMP_MOUNT
+  pivot_root . mnt
+  umount -n /mnt/proc >/dev/null 2>&1
+  exec chroot . sh -c 'umount -n /mnt >/dev/null 2>&1; exec -a init.new /sbin/init 3' <dev/console >dev/console 2>&1
+                                                                                
+EOF
+
+--------------------------------------
+
+
+	To make this script executable run
+
+chmod 0755 $LIVECD/mnt/linuxrc
+
+	Ok, that's it. Unmount the image and compress it.
+
+cd $LIVECD/
+umount $LIVECD/mnt
+gzip $LIVECD/boot/initrd
+
+
+8. Burn the Boot CD
+   ----------------
+
+	If you have a CD-RW you should take this for testing. When
+	your system boots quite good from CD-RW you can burn it on a CD-R.
+	(I give you this advice, because I got the clue after burning
+	about 10 CD-Rs that didn't work ;-)
+
+	Before you start burning, check the size of your LFS tree:
+
+du -ch $LIVECD/ | grep total
+
+	Delete all the stuff you don't need on a Boot CD. (e.g. /usr/src/*)
+
+	Because linuxrc must be able to identify the CD you have to create a
+	file called "livecd". (unless you use isoinfo)
+
+touch $LIVECD/livecd
+
+	Now burn the LFS system on CD
+
+	Note!
+	dev=/dev/hdc is the device number of your CD-Writer
+	Check your SCSI devices with "cdrecord -scanbus"
+	( as of this writing scsi-emulation is no longer required)
+	speed=4 should be changed to (max) speed of your CD-Writer.
+	If you are not using a CD-RW remove blank=fast from the cdrecord-command!
+
+cd $LIVECD/
+mkisofs -R -l -L -D -b isolinux/isolinux.bin -o $ISODIR/livecd_image.iso -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -V "livecd" $LIVECD && 
+cdrecord -v -eject dev=/dev/hdc blank=fast $ISODIR/livecd_image.iso
+
+
+
+ACKNOWLEDGEMENTS:
+
+Thanks to:
+Thomas Foecking <thomas at foecking.de> and Christian Hesse <mail at earthworm.de>
+For writing the "Easy Boot CD of your LFS" hint which confused me so much
+when I tried it with udev that I decided to write this one =o)
+
+Feel free to email me comments, point out typos, etc. 
+
+CHANGELOG:
+[2004-07-24]
+  * Finally found the time to proofread and submit the hint;)
+[2004-05-19]
+  * Added environment variables for more flexibility
+[2004-05-17]
+  * Initial hint completed.




More information about the hints mailing list