boot-cd_easy.txt Update

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


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

Thanks for commiting it to CVS.

-------------- next part --------------
TITLE:          Easy Boot CD of your LFS
AUTHOR:		Thomas Foecking <thomas at>
		Christian Hesse <mail at>

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

Version 0.2d


    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)

		isoinfo: (optional to detect the LFS CD without mounting it)

	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


	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

sed "s/\/usr\/local\//\/usr\//g" Makefile >
mv Makefile

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 /boot/

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


	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

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"


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

case "$1" in
                echo -n "Creating ext2fs on $dev_ram ...              "
                /sbin/mke2fs -m 0 -i 1024 -q $dev_ram > /dev/null 2>&1
                sleep 1
                echo -n "Mounting ramdisk on $dir_ramdisk ...         "
                mount -n $dev_ram $dir_ramdisk
                sleep 1
                echo -n "Copying files to ramdisk ...                 "
                cp -dpR $dir_needwrite/* $dir_ramdisk > /dev/null 2>&1
                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

	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

	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/{,,,} 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"

#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

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

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


#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

if [ -e "/bin/isoinfo" ]; then

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

mount -n proc /proc -t proc

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


#do we have devfs? (then its very easy)
if [ -d "/dev/cdroms/" ]; then
  for cdrom_device in /dev/cdroms/cdrom[0-99]
    if [ -e "$cdrom_device" ]; then
      CDROM_LIST="$CDROM_LIST $cdrom_device"
else #we search in proc tree for ide cdrom devices
  for ide_channel in /proc/ide/ide[0-9]
    if [ ! -d "$ide_channel" ]; then
    for ide_device in hda hdb hdc hdd hde hdf hdg hdh hdi hdj hdk hdl hdm hdn
      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"
  for scsi_cdrom in /dev/scd[0-99]
    if [ -e "$scsi_cdrom" ]; then
      CDROM_LIST="$CDROM_LIST $scsi_cdrom"

#2. now we try to find the LFS boot CD (we use ID as identification)

echo "Using $CHECK_TYPE"
for cdrom_device in $CDROM_LIST
  echo -n "Checking $cdrom_device ... "

  if [ "$CHECK_TYPE" = "try_mount" ]; then
    mount -n -t iso9660 $cdrom_device $TMP_MOUNT > /dev/null 2>&1
  if [ "$CHECK_TYPE" = "isoinfo" ]; then
    isoinfo -d -i $cdrom_device > /dev/null 2>&1
    if [ $media_found -ne 0 ]; then
      isoinfo -V $cdrom_device > /dev/null 2>&1

  if [ $media_found -eq 0 ]; then

    echo -n "media found"
    if [ "$CHECK_TYPE" = "try_mount" ]; then
      [ -e "$TMP_MOUNT/$ID" ]
    if [ "$CHECK_TYPE" = "isoinfo" ]; then
      isoinfo -d -i $cdrom_device | grep -i "Volume id:" | grep "$ID" \
      > /dev/null 2>&1
      if [ $media_lfs -ne 0 ]; then
        isoinfo -V $cdrom_device | grep "$ID" > /dev/null 2>&1

    if [ "$CHECK_TYPE" = "try_mount" ]; then
      umount -n $cdrom_device > /dev/null 2>&1

    if [ $media_lfs -eq 0 ]; then
      echo ", LFS boot CD found. Ready!"
      echo ", not LFS boot CD."

    echo "no media "

#3. mount LFS CD as / (root fs)
if [ "$LFS_CDROM_DEVICE" = "" ]; then

  echo "No LFS boot CD found!!!"
  exit 1


  echo "Booting from $LFS_CDROM_DEVICE ...                  "

  mount -n -o ro -t iso9660 $LFS_CDROM_DEVICE $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 /sbin/init 3'\
  <dev/console >dev/console 2>&1



	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

	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/ \
-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>
 Christian Hesse <mail at>
 Special thanks for bug reports and help to:
 David Maus <oneyed at>

More information about the hints mailing list