boot-cd_easy.txt Update

Thomas Föcking thomas at foecking.de
Mon Dec 16 14:02:30 PST 2002


Hi,

just added the realname of the one who helped us. (David Maus)

Thanks for commiting it to CVS.

Thomas
-------------- next part --------------
TITLE:          Easy Boot CD of your LFS
LFS VERSION:    all
AUTHOR:		Thomas Foecking <thomas at foecking.de>
		Christian Hesse <mail at earthworm.de>

SYNOPSIS:
	How to create an easy Boot CD of your working LFS system.

HINT:
Version 0.2d
19/11/2002

Contents
--------

    1. What do you need and what is the idea?
    2. Configure & compile Kernel
    3. Move /dev /var /tmp /root /home to /fake/needwrite
    4. Create symlinks /... -> /fake/needwrite/...
    5. Create boot script which mounts the ramdisk
    6. Install the bootloader isolinux
    7. Create initial ramdisk
    8. Burn the Boot CD
    9. Reboot and enjoy


1. What do you need and what is the idea?
   --------------------------------------

	What do you need?
	- LFS system which you want to burn on CD
	- another linux/unix system to create some stuff and burn the CD
	- CD-R(W) drive to burn your LFS system and boot image on CD
	- 1 CD-R + 1 CD-RW is very recommended for saving money
	- additional software:
		syslinux: (contains isolinux to boot the LFS kernel on CD)
http://freshmeat.net/redir/syslinux/10177/url_bz2/syslinux-1.67.tar.bz2

		isoinfo: (optional to detect the LFS CD without mounting it)
http://www-tet.ee.tu-berlin.de/solyga/linux/isoinfo-0.03.01.tar.gz


	First of all you need a running LFS system, which you want to burn
	on CD. You may want to have a LFS CD for creating new LFS systems
	on other computers. Whatever your ideas are, you'll first have to
	create this special system on your LFS partition.
	(e.g. I have created a LFS system with xfree86 and windowmaker;
	now I can boot from CD and create new LFS systems without missing
	xfree86 & windowmaker)

	What is the idea?
	- Create kernel with ramdisk and initrd support
	- Move /dev /var /tmp /root /home to /fake/needwrite
	- Set symlinks
		/dev  -> /fake/needwrite/dev
		/var  -> /fake/needwrite/var
		/...   -> /fake/needwrite/...
	- Mount /dev/ram0 to /fake/ramdisk
	- Copy /fake/needwrite/* to /fake/ramdisk/
	- Remount /dev/ram0 to /fake/needwrite

	We'll have read-write access on /dev /var /tmp /root /home
	because they point to /fake/needwrite which is then a ramdisk

	You are able to do the most things from the other linux/unix
	system by setting LFS to your LFS mountpoint. LFS=/path/to/lfs
	e.g.:

LFS=/mnt/lfs

	Don't forget to set LFS again when you do a reboot!


2. Configure & compile Kernel
   --------------------------

	Boot your LFS system or chroot to it.

--- optional ---

	As we're just here we first install isoinfo which we use later. I
	assume the tarball isoinfo-0.03.01.tar.gz is placed in /usr/src.

	Skip this step if you have already installed cdrtools! These cdrtools
	also contain a program named isoinfo which we'll use then.

cd /usr/src
zcat isoinfo-0.03.01.tar.gz | tar x
cd isoinfo

./configure
sed "s/\/usr\/local\//\/usr\//g" Makefile > Makefile.new
mv Makefile.new Makefile
make

make install

--- end of optional ---


	Ok, now let's configure your kernel:

cd /usr/src/linux
make mrproper && make menuconfig

	You need ramdisk support!
		"Block devices  --->" 
			"<*> RAM disk support"
			"(4096)   Default RAM disk size"
			"[*]   Initial RAM disk (initrd) support"

	You need ISO 9660 CDROM file system support!
		"File systems  --->"
			"<*> ISO 9660 CDROM file system support"

	You should also think about building some other drivers into
	your kernel or as modules which is much better.

	If you want to be able to boot the CD on a lot of PCs with
	different CPUs (e.g. 486, Pentium, PII, PIII, Athlon) you have to
	compile the kernel for 486 (then it runs on >= 486).
		"Processor type and features  --->"
			"(486) Processor Family"

	Save config and compile your kernel:

make dep && make bzImage && make modules && make modules_install

	Then you should copy the new built kernel to /boot:

cp arch/i386/boot/bzImage /boot/lfskernel && cp System.map /boot/

	Run Lilo (or update the bootloader you're using):

/sbin/lilo

	Try to boot the new kernel in order to test ramdisk support:
	If you're using devfs you must change: dev_ram=/dev/rd/0


dev_ram=/dev/ram0
mke2fs -m 0 $dev_ram

	If this fails like
	> The device apparently does not exist;
	> did you specify it correctly?
	you have no ramdisk support in your kernel.
	You should read this chapter again ;-)

	Otherwise you have done your work very well!

	You can check the size of your ramdisk by mounting it to
	/mnt and doing an "df -h"

mount $dev_ram /mnt
df -h

	Now you can boot your other linux/unix system ...


3. Move /dev /var /tmp /root /home to /fake/needwrite
   --------------------------------------------------

	We move all stuff needing write access to /fake/needwrite.

	First we have to create this directory
	and the mountpoint for the ramdisk:

mkdir -p $LFS/fake/{needwrite,ramdisk}

	Then we can move it there:

cd $LFS/
mv dev/ var/ tmp/ root/ home/ fake/needwrite/


4. Create symlinks /... -> /fake/needwrite/...
   -------------------------------------------

	We have moved /dev /var /tmp /root /home to /fake/needwrite.
	Now we must set symlinks so that everything seems to be
	as before.

cd $LFS/
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

	"ls -l" says:
	 dev  -> fake/needwrite/dev
	 home -> fake/needwrite/home
	 root -> fake/needwrite/root
	 tmp  -> fake/needwrite/tmp
	 var  -> fake/needwrite/var

	If you also want to be able to change files in /etc on your Boot CD
	you must repeat the same procedure with /etc.

cd $LFS/
mv etc/ fake/needwrite/
ln -s fake/needwrite/etc etc


5. Create boot script which mounts the ramdisk
   --------------------------------------------

	Ok, we have /dev /var /tmp /root /home linked to
	/fake/needwrite which is first read-only.
	To be able to login (and to run services on runlevel x
	which need write access to /dev /var /tmp /root or /home)
	we must call a script from our /etc/rc.d/init.d/ directory which
	creates a ramdisk to /fake/needwrite with write access.

	The following script creates a ramdisk to /fake/ramdisk and
	will copy everything of /fake/needwrite to /fake/ramdisk.
	Then it remounts the ramdisk to /fake/needwrite.

cat > $LFS/etc/rc.d/init.d/create_ramdisk << "EOF"
#!/bin/sh

dev_ram=/dev/ram0
dir_ramdisk=/fake/ramdisk
dir_needwrite=/fake/needwrite

source /etc/rc.d/init.d/functions

case "$1" in
        start)
                echo -n "Creating ext2fs on $dev_ram ...              "
                /sbin/mke2fs -m 0 -i 1024 -q $dev_ram > /dev/null 2>&1
                evaluate_retval
                sleep 1
                echo -n "Mounting ramdisk on $dir_ramdisk ...         "
                mount -n $dev_ram $dir_ramdisk
                evaluate_retval
                sleep 1
                echo -n "Copying files to ramdisk ...                 "
                cp -dpR $dir_needwrite/* $dir_ramdisk > /dev/null 2>&1
                evaluate_retval
                sleep 1
                echo -n "Remount ramdisk to $dir_needwrite ...        "
                umount -n $dir_ramdisk > /dev/null 2>&1
                sleep 1
                mount -n $dev_ram $dir_needwrite
                sleep 1
                ;;
        *)
                echo "Usage: $0 {start}"
                exit 1
                ;;
esac
EOF

	Make it executable:

chmod 0755 $LFS/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 $LFS/etc/rc.d/rcsysinit.d
ln -s ../init.d/create_ramdisk S00create_ramdisk


6. 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 perfect for a CD is isolinux (it comes
	with syslinux). I assume the tarball syslinux-1.67.tar.bz2 is
	already placed in $LFS/usr/src.

cd $LFS/usr/src
bzcat syslinux-1.72.tar.bz2 | tar x

mkdir $LFS/isolinux
cp syslinux-1.72/isolinux.bin $LFS/isolinux/

	If all files associated with the boot process should be in one
	directory we have to move kernel and the Rest of /boot to /isolinux.

mv $LFS/boot/* $LFS/isolinux

	Now we create a symlink from boot to isolinux.

cd $LFS/
rmdir boot
ln -s isolinux boot

	Kernel & co can now be found in /boot again.
	But isolinux still needs a config-file, so we create it now:

cat > $LFS/isolinux/isolinux.cfg << "EOF"
default bootcd

label bootcd
  kernel lfskernel
  append initrd=initrd.gz root=/dev/ram0 init=/linuxrc ramdisk_size=16384
EOF

	isolinux is now installed completely.


7. Create initial ramdisk
   ----------------------

	!!! But first we have to change /etc/fstab of LFS !!!
	Delete all entries you don't need. (e.g. all /dev/hd*)
	You only need proc (and maybe devfs, devpts)

vi $LFS/etc/fstab

	Don't worry about mounting root filesystem "/".
	This will be mounted by linuxrc from initrd fs.

	The best is to remove also the following links:

rm $LFS/etc/rc.d/rc3.d/S20network
rm $LFS/etc/rc.d/rc0.d/K80network
rm $LFS/etc/rc.d/rc6.d/K80network
rm $LFS/etc/rc.d/rcsysinit.d/S40mountfs
rm $LFS/etc/rc.d/rcsysinit.d/S30checkfs

	Now we create the initrd image file and filesystem.

dd if=/dev/zero of=$LFS/boot/initrd bs=1024 count=6144
mke2fs -m 0 -i 1024 -F $LFS/boot/initrd

mount -o loop $LFS/boot/initrd $LFS/mnt
cd $LFS/mnt
mkdir bin lib dev proc mnt
cp $LFS/bin/{bash,mount,grep,umount,echo} bin/
cp $(find $LFS -name "test" -type f) bin/
cp $(find $LFS -name "chroot" -type f) bin/
cp $(find $LFS -name "pivot_root" -type f) bin/
cp $LFS/lib/{libncurses.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/
cp -dR $LFS/dev/{console,hd?,scd*,null,ram*} dev/
ln -s bash bin/sh
ln -s test bin/[

	If you wish to use isoinfo instead of mount to detect the LFS CD you
	must also copy isoinfo into the initial ramdisk.

cp $(find $LFS -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 > $LFS/mnt/linuxrc << "EOF"
#!/bin/sh

#if you want use devfs and don't have /dev/hd?, /dev/scd* then
#you must mount your devfs here:


#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
EOF

echo "ID=\"LFS_$(date +%Y%m%d)\"" >> $LFS/mnt/linuxrc

cat >> $LFS/mnt/linuxrc << "EOF"
TMP_MOUNT="/mnt"

PATH="/bin:/sbin:/usr/bin:/usr/sbin"

#this script searches for cdrom devices and then tries to find
#the LFS boot CD in order to mount it as / (rootfs)
#it detects: IDE devices hda - hdn and SCSI devices scd0 - scd99
#or when using devfs: IDE/SCSI devices cdrom0 - cdrom99

#you need following programs:
#- /bin/isoinfo (optional)
#- /bin/sh (e.g. bash)
#- echo
#- [ (which is linked to test)
#- mount
#- umount
#- grep
#- pivot_root
#- chroot

#you need following devices:
#- /dev/hd* or /dev/scd* or /dev/cdroms/cdrom*
#- /dev/null

#you need following directories:
#- /proc
#- $TMP_MOUNT

if [ -e "/bin/isoinfo" ]; then
  CHECK_TYPE="isoinfo"
else
  CHECK_TYPE="try_mount"
fi

if [ ! -d "/proc/" ]; then
  mkdir /proc
fi

mount -n proc /proc -t proc

#1. search for cdrom devices and add them to CDROM_LIST

CDROM_LIST=""

#do we have devfs? (then its very easy)
if [ -d "/dev/cdroms/" ]; then
  for cdrom_device in /dev/cdroms/cdrom[0-99]
  do
    if [ -e "$cdrom_device" ]; then
      CDROM_LIST="$CDROM_LIST $cdrom_device"
    fi
  done
else #we search in proc tree for ide cdrom devices
  for ide_channel in /proc/ide/ide[0-9]
  do
    if [ ! -d "$ide_channel" ]; then
     break
    fi
    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
          if [ -e "/dev/$ide_device" ]; then
            CDROM_LIST="$CDROM_LIST /dev/$ide_device"
          fi
        fi
      fi
    done
  done
  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=""
echo "Using $CHECK_TYPE"
for cdrom_device in $CDROM_LIST
do
  echo -n "Checking $cdrom_device ... "

  if [ "$CHECK_TYPE" = "try_mount" ]; then
    mount -n -t iso9660 $cdrom_device $TMP_MOUNT > /dev/null 2>&1
    media_found=$?
  fi
  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 ...                  "

  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 $LFS/mnt/linuxrc

	Ok, that's it. Unmount the image and compress it.

cd $LFS/
umount $LFS/mnt
gzip $LFS/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 -h $LFS/

	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 "LFS_YYYYMMDD". (But only if you don't use isoinfo)

touch $LFS/LFS_$(date +%Y%m%d)

	Now burn the LFS system on CD

	Note!
	dev=0,0,0 is the device number of your CD-Writer
	Check your SCSI devices with "cdrecord -scanbus"
	speed=4 should be changed to (max) speed of your CD-Writer.
	If you are using a CD-RW add blank=fast to the cdrecord-command!

cd $LFS/
mkisofs -R -l -L -D -b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table -V "LFS_$(date +%Y%m%d)" \
$LFS | \
cdrecord -v -eject dev=0,0,0 speed=4 -


9. Reboot and enjoy
   ----------------

	Reboot and let your Bios boot from CD.
	Enjoy the kernel messages and login prompt ;-)

------------------------------------------------------------------
 If you have any ideas, suggestions or found a bug you can send a
 mail to:
 Thomas Foecking <thomas at foecking.de>
 Christian Hesse <mail at earthworm.de>
------------------------------------------------------------------
 Special thanks for bug reports and help to:
 David Maus <oneyed at gmx.de>
------------------------------------------------------------------



More information about the hints mailing list