r882 - trunk

tushar at linuxfromscratch.org tushar at linuxfromscratch.org
Tue Aug 10 17:38:15 PDT 2004


Author: tushar
Date: 2004-08-10 18:38:13 -0600 (Tue, 10 Aug 2004)
New Revision: 882

Added:
   trunk/2.6-udev-nptl-bootcd.txt
Removed:
   trunk/lfs-live-cd.txt
Log:
Added Hint: 2.6-udev-nptl-bootcd

Added: trunk/2.6-udev-nptl-bootcd.txt
===================================================================
--- trunk/2.6-udev-nptl-bootcd.txt	2004-08-11 00:16:53 UTC (rev 881)
+++ trunk/2.6-udev-nptl-bootcd.txt	2004-08-11 00:38:13 UTC (rev 882)
@@ -0,0 +1,652 @@
+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
+
+  Gabe Munoz pointed out that this symlink can be S11, where it used
+  to be at S00. Of course feel free to number the symlink as you see
+	fit. (This is LFS after all!):
+	/etc/rc.d/rcsysinit.d/S11create_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 sbin lib dev proc mnt sys etc
+    cp -a $LIVECD/bin/{bash,mount,grep,umount,echo,ln,mkdir} bin/
+    cp -a $LIVECD/sbin/udev* sbin/
+    cp -a $(find $LIVECD -name "test" -type f) bin/
+    cp -a $(find $LIVECD -name "chroot" -type f) bin/
+    cp -a $(find $LIVECD -name "pivot_root" -type f) bin/
+    cp -H $LIVECD/lib/{libncurses.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/
+		cp -H $LIVECD/lib/{libreadline.so.5.0,libhistory.so.5.0} 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 -a $LIVECD/dev/{console,null} dev/
+
+You need /etc/udev, /etc/hotplug and /etc/dev.d
+
+    cp -a $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
+                                                                                
+#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
+
+fi                                                                               
+ 
+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)
+
+ * Gabriel Aneceto Munoz
+   For bring syntax errors and other updates to my attention
+
+Feel free to email me comments, point out typos, etc. 
+
+CHANGELOG:
+[2004-08-04]
+  * Fixed syntax errors and made other updates
+[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.

Deleted: trunk/lfs-live-cd.txt
===================================================================
--- trunk/lfs-live-cd.txt	2004-08-11 00:16:53 UTC (rev 881)
+++ trunk/lfs-live-cd.txt	2004-08-11 00:38:13 UTC (rev 882)
@@ -1,643 +0,0 @@
-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