Typo
[linux_from_scratch_hints.git] / OLD / bootlfscd.txt
blob6c093d03cff8539b37d138df9be7bdfbbc2ef24e
1 TITLE:          Bootable LFS CD using lilo
2 LFS VERSION:    LFS 4.0 onwards
3 AUTHOR:         Chris Lingard  chris@stockwith.co.uk
4 CREDITS         Thanks to Gerard Beekmans, Martin L. Pursche and many others`
5 LINKS:
7 My boot disk   www.stockwith.co.uk
8 The package    www.stockwith.uklinux.net Please do not use this until after
9 I have upgraded it.  Problems with ISP, since I took hosting away from them.
11 SYNOPSIS:
13 This hint involves using two LFS systems to build a third system on a CD.
14 It does not use any external packages, the boot method being LFS
16 Index
18 1.  Introduction
19 2.  How it boots
20 3.  What it boots
21 3.  The base system
22 4.  The image system
23 5.  Making the package
24 6.  Building the image
25 7.  Some uses for the boot CD
27 HINT:
29 1.  Introduction
31 This is my method of making a bootable CD
32 I started this project when I realised that I had no proper recovery system,
33 and it just grew from there.
35 I tried various other systems; the best being cd_template by Martin L. Pursche.
36 Extending this package, to boot a full Linux system, became my goal.
38 Here are the standard warnings.  You must be confident enough to build systems,
39 with various hacks and modifications.  You must be careful enough to avoid 
40 wrecking your systems;  many of the scripts will mess up your base system if
41 run wrongly.
43 2.  How it boots
45 First a few words on how to make a bootable CD, (using lilo). When you burn a
46 CD using mkisofs, you have the -b option to specify the boot image.
47 This boot image must be something that the hardware understands, therefore
48 you need to emulate a floppy.  Since we are only pretending that is a floppy,
49 we may choose any type,  so we choose the largest -- a 2.88Mb floppy.
51 We make a file using a loop device that is exactly 2.88Mb, copy files to
52 it, then run lilo on it.
54 Please note that it is the BIOS that reads this 2.88Mb image.  Once this is
55 read, then BIOS/lilo gives control to the kernel.  The kernel boots,
56 decompresses the initrd file, and mounts this as the root file system.
58 We need to run lilo on the 2.88Mb file.  Here is a lilo.conf:
60 cat > $TOPDIR/lilo.conf << EOF
61 disk=/dev/loop1
62 bios=0x00 # bios ID from drive A, we need that here because lilo
63 # need to know which boot device to use
64 sectors=36 # 2.88MB disk geometry
65 heads=2
66 cylinders=80
67 timeout=30
68 lba32
70  boot=/dev/loop1
71  message=/mnt/loop1/boot.msg
72  install=/mnt/loop1/boot.b
73  map=/mnt/loop1/map
74  prompt
76  image=/mnt/loop1/vmlinuz
77    label=linux
78    initrd=/mnt/loop1/initrd.gz
79    append = "root=/dev/ram0 init=/linuxrc rw"
80    ramdisk=$ISIZE
82 EOF
83 # run lilo
84 /sbin/lilo -C $TOPDIR/lilo.conf
87 At the start of the above, you can see us telling lies to the hardware,
88 that this is a 2.88Mb floppy.
90 We have put a kernel and boot message into this file system.
92 The initrd.gz is a compressed file system.
94 linuxrc is an executable script in the root of this file system.
96 This must all fit inside 2.88Mb.
98 The initrd file system may be 6.5Mb, before compression,
99 and still be small enough.
101 linuxrc may be a symbolic link to bash
103 3. What it boots
105 The files in the base of this file are:
106 boot-menu.b  boot.b  boot.msg  initrd.gz  map  vmlinuz
108 boot.b is a symbolic link to boot-menu.b, and these together with map
109 are copied from /boot on your base system
111 boot.msg is a text file that gives the start of boot greeting
113 vmlinux is the kernel, and initrd.gz is a compressed file system that
114 will become the root partition.
116 The file system may contain anything you like, but this is all you will
117 have after booting the CD
119 You can make this system inside a directory; it will look something like:
121 /dev  #    Use devfsd
122 /bin  ->  sbin
123 /lib  # Needed if you are using dynamic programs
124 /lib/modules  #  See next paragraph`
125 /linuxrc  #  The script
126 /sbin     #  You selection of programs
128 The directory modules should be copied from your target system.  These
129 will be the modules available during the boot.  Once the boot is complete
130 then /lib/modules will be available from your target system via the CD.
132 Once you have made this;  you calculate its size, make a file system on
133 loop device,  copy the files, then compress it into initrd.gz.
135 During the linuxrc script you would mount the cdrom, giving you access to
136 whatever you put on the CD.
138 See the mount_cdrom script below that auto-detects the cdrom, and modify it
139 to do what you want.
142 4.  The base system
144 The base system's kernel will need loop devices enabled.  I use mkisofs and
145 cdrecord from package  cdrtools. You will also need directories for
146 the loop back devices to use;  /mnt/loop1 and /mnt/loop2 are what I use.
148 5.  The image system
150 This system must be running devfsd, as this is used for hardware detection
151 You should implement the pciutils package to get the lspci program.
153 You must decide if you just want a CD that will work on your machine, (and
154 any identical); or you want a CD that will work on any PC.
156 If you want a generic CD, then you must build a generic system to act as the
157 image;  follow the cross compile hint to build a generic 486 LFS system.
159 The system used for the image can be any working combination you choose.
160 Things that use many shared libraries, such as KDE, should be avoided,
161 because they will be too slow for any effective work on a CD.
162 I use a standard LFS plus a few extras such as gpm, X and lynx.
164 If you really want a large KDE type system, then get the cloop daemon
165 from Knoppix.  This allows you to make and mount  compressed partitions.
167 The kernel of the booting system must have been built with:
168 CONFIG_BLK_DEV_RAM_SIZE=32768
170 6.  Making the package
172 You will need two LFS systems to generate a bootable CD.  One is the base
173 system that will be used for building.  The other is the system that provides
174 the image.
176 Here is how it works.
178 Let us first consider what we want.  We need a writable root partition,
179 so we will make one out of RAM.  We will want /proc and /cdrom mounted on
180 the root.
182 We also want /root and /etc writeable,  so these are unpacked from
183 tar files during the boot process. (How the image system is prepared is
184 described later).
186 The start up linuxrc will achieve this, then pass control to init. Here
187 is my linuxrc script:
189 #!/bin/sh
191 /sbin/devfsd  /dev
193 mount -t proc none /proc
194 modprobe -q  -s `cat /scsi`
196 dd if=/dev/zero  of=/dev/ram2  bs=1k  count=25000
197 mkdir  -p  ram
198 mke2fs -q /dev/ram2
199 mount  /dev/ram2  /ram
200 cd /ram
201 mkdir cdrom
202 /mount_cdrom
203 mkdir proc
204 mount  -t proc  none /ram/proc
205 cdrom/bin/ln -s  cdrom/bin  bin
206 bin/ln -s  cdrom/sbin  sbin
207 bin/ln -s  cdrom/lib  lib
208 bin/ln -s  cdrom/boot  boot
209 bin/ln -s  /cdrom/usr  usr
210 dd  if=/dev/zero  of=swapspace bs=1k  count=5000
211 sbin/mkswap  swapspace
212 bin/echo "Preparing file systems for pivot"
213 mkdir home
214 mkdir dev
215 mkdir tmp
216 mkdir mnt
217 mkdir mnt/lfs
218 mkdir var
219 cd var
220 mkdir lib lock log mail run spool tmp opt cache lib/misc local
221 cd /ram
222 bin/echo "Unpacking tar files for /etc and /root"
223 bin/tar xf /ram/cdrom/etc.tar
224 bin/tar xf /ram/cdrom/root.tar
225 mkdir initrd
226 sbin/pivot_root  .  initrd
227 # Get devices on the new root
228 /bin/killall  devfsd
229 mount  devfs  -t  devfs  /dev
230 exec /usr/sbin/chroot . /sbin/init <dev/console >dev/console 2>&1
233 The only non standard thing used here is mount_cdrom, this is it.
235 #!/bin/sh
236 for disk in 0 1 2 3 4 5 6 7; do
237          if  mount -t iso9660 -o ro -n /dev/cdroms/cdrom$disk /ram/cdrom 2> /dev/null  ; then
238            if [ -r /ram/cdrom/LFS-4.1 ]; then
239             echo "Found the CD-ROM"
240             exit
241            else
242              umount  /ram/cdrom;
243            fi;
244          fi
245 done
246 echo "No CD-ROM found"
248 The file LFS-4.1 is to make sure tha the right CD is mounted.
250 The file scsi is a list of scsi modules like:
252 3w-xxxx
253 53c7,8xx
254 AM53C974
255 BusLogic
256 .......
257 .......
259 Each is loaded in turn in case the machine has this scsi driver.  
261 From this is can be seen that the following programs are needed during the 
262 boot process:
264 bash  chroot  devfsd  insmod    ksyms  mkdir   modprobe  pivot_root  sh
265 cat   dd      echo    kallsyms  lsmod  mke2fs  mount     rmmod       umount
267 (kallsyms, ksyms, lsmod, modprobe and rmmod are symbolic links to insmod)
268 (sh is a symbolic link to bash)
270 Because shared libraries plus programs are smaller than static programs,
271 the following libraries are needed:
273 ld-2.3.1.so
274 ld-linux.so.2 -> ld-2.3.1.so
275 libc-2.3.1.so
276 libc.so.6 -> libc-2.3.1.so
277 libcom_err.so.2 -> libcom_err.so.2.0
278 libcom_err.so.2.0
279 libdl-2.3.1.so
280 libdl.so.2 -> libdl-2.3.1.so
281 libe2p.so.2 -> libe2p.so.2.3
282 libe2p.so.2.3
283 libext2fs.so.2 -> libext2fs.so.2.4
284 libext2fs.so.2.4
285 libuuid.so.1 -> libuuid.so.1.2
286 libuuid.so.1.2
288 We can therefore make a system like this in a directory called initrdtree
290 ls  initrdtree/
291 bin   dev  etc  initrd  lib linuxrc
292 mount_cdrom proc root sbin tmp usr var
294 Where bin a link to sbin, sbin contains the programs and lib the libraries.
295 linuxrc and mount_cdrom are the scripts, and dev has the devices.
297 This file system must be small enough, ( 6-7Mb ), so that its compressed size,
298 plus a kernel is less than 2.88Mb.
300 A file system can be made on a loop device, and the directory initrdtree
301 copied to it.   The file system is then compressed.
303 This put into a futher file system containing a kernel.
304 This file system must be exactly 2.88Mb, (it is a floppy to the hardware).
306 This is also mounted on a loop device and lilo is run on it.
307 This is then the boot image that mkisofs sees with the -b flag
309 The build directory looks like:
311 bootimagetree # Contains the kernel and the compressed file system
312 build.sh  # The script
313 initrdtree    # Contains the boot image system before compression
314 cdtree    #  The system providing the CD image is mounted here
316 Here is the script build.sh that builds the iso; note that the system
317 providing the CD image is mounted on cdtree/
319 #! /bin/sh 
321 if [ -z $TOPDIR ] ; then
322   echo "you must define TOPDIR"
323   exit
326 oldpwd=`pwd`
328 cd $TOPDIR
330 # we need to set aside a few loop devices. I chose (in reverse order of their appearance)
331 # -- loop1 for the boot image
332 # -- loop2 for the ram disk image
333 # since the loop1 choice is reflected in the lilo.loopfix file, 
334 # you should not change that (or you need to change the file).
335 # I had used loop0 first, but I found that this is used by the Samba daemon.
336 # Also, I assume that the mount points are /mnt/loop{1,2}.
337 # In principle we could do with one, but it comes in handy to be able to
338 # leave one mounted, so I took two different ones. 
340 # we first assume that a proper directory tree of the later ramdisk 
341 # is in the initrdtree directory. Put everything in there what you think
342 # will be needed. We assume that this is the case.
344 echo -n "Creating the Initial Ramdisk image.... "
346 # first find out how much space we need. 
347 ISIZE=`du -s -k  $TOPDIR/initrdtree/ | awk '{print $1}'`
349 # is that true? Anyway, we are smaller than that.
350 if [ $ISIZE -gt 8192 ]; then
351    echo "Initial Ramdisk max size exceeded ($ISIZE, max is 8192KB)"
352    exit 1
355 ISIZE=`expr $ISIZE + 1024`
356 ISIZE=8192
357 echo "Initial Ramdisk contents will be $ISIZE KB"
359 # delete the existing ramdisk image, if there is one
360 rm -f $TOPDIR/ramdisk
362 # create a file of $ISIZE Kb
363 dd if=/dev/zero of=$TOPDIR/ramdisk bs=1k count=$ISIZE
365 # associate it with /dev/loop2
366 losetup /dev/loop2 $TOPDIR/ramdisk
368 # make an ext2 filesystem on it. We set the amount of unused space to 0%
369 # and turn down the number of inodes to save space
370 #mkfs  -t ext2 -i 16384 -m 0 /dev/loop2
371 mke2fs  -F -m0 -b 1024 /dev/loop2
373 # we mount it...
374 mount /dev/loop2 /mnt/loop2 
376 # ... and delete the lost+found directory 
377 rm -rf /mnt/loop2/lost+found 
379 # then we copy the contents of our initrdtree to this filesystem
380 cp -dpR $TOPDIR/initrdtree/* /mnt/loop2/
382 # and unmount and divorce /dev/loop2
383 umount /mnt/loop2
384 losetup -d /dev/loop2 
386 echo "done"
388 # Now we have the image of the ramdisk in $TOPDIR/ramdisk. We
389 # compress this one and write the compressed image to the boot tree:
391 echo -n "Compressing the Ramdisk image.... "
393 # delete any existing one
394 rm -f $TOPDIR/bootimagetree/initrd.*
396 # and gzip our ramdisk image and put it in the right place.
397 gzip -9 -c $TOPDIR/ramdisk > $TOPDIR/bootimagetree/initrd.gz
399 # we are done with the uncompressed ramdisk image, delete it
400 rm  $TOPDIR/ramdisk
402 # how much is the contents of the bootimagetree?
403 ISIZE=`du -s -k  $TOPDIR/bootimagetree/ | awk '{print $1}'`
404 echo "Boot image size is $ISIZE KB"
406 echo "done"
408 # Part II. We work the boot tree (with the image of the ramdisk) now.
409 # we put that into yet another image which we put on the CD. 
410 # This image has to be 2.88 MB exactly, because we emulate a 2.88MB floppy.
412 echo -n "Creating the boot image.... "
414 # delete any leftover version
415 rm -f $TOPDIR/cdtree/Boot.img
417 # and make a file of the proper size (this time it's fixed at 2880 KB)
418 # note that the file gets created already in the right place to be the boot image.
419 dd if=/dev/zero of=$TOPDIR/cdtree/Boot.img bs=1k count=2880
421 # this one gets associated with loop1 and gets a ext2 file system
422 losetup /dev/loop1 $TOPDIR/cdtree/Boot.img
423 mke2fs -F -m0  -b 1024  /dev/loop1
425 # mount it...
426 mount /dev/loop1 /mnt/loop1
427 rm -rf /mnt/loop1/lost+found
429 # ... and copy the contents of our bootimagetree over
430 cp -dpR $TOPDIR/bootimagetree/* /mnt/loop1/ 
432 # now we calculate the ramdisk size for the lilo.conf
433 # Hard code the size we want; also see linuxrc for dd's count=
434 ISIZE=30000
435 echo "Ram disk size will be $ISIZE KB"
437 cat > $TOPDIR/lilo.conf <<EOF
438 disk=/dev/loop1
439 bios=0x00 # bios ID from drive A, we need that here because lilo
440 # need to know which boot device to use
441 sectors=36 # 2.88MB disk geometry
442 heads=2
443 cylinders=80
444 timeout=30
445 lba32
446  boot=/dev/loop1
447  message=/mnt/loop1/boot.msg
448  install=/mnt/loop1/boot.b
449  map=/mnt/loop1/map
450  prompt
451   
452  image=/mnt/loop1/vmlinuz
453    label=linux
454    initrd=/mnt/loop1/initrd.gz
455    append = "root=/dev/ram0 init=/linuxrc rw"
456    ramdisk=$ISIZE
461 # run lilo
462 chmod 600  $TOPDIR/lilo.conf
463 /sbin/lilo -v -v -v -C   $TOPDIR/lilo.conf
465 rm -f $TOPDIR/lilo.conf
467 # unmount and divorce from the loop device
468 umount /mnt/loop1
469 losetup -d /dev/loop1 
471 echo "done"
473 # note that after running lilo, we cannot mount the image back. That's why 
474 # we make it a throwaway.
476 # go to the top directory of the future CD
477 cd $TOPDIR/cdtree
479 # and create the CD image
480 # you can fill in the info below as follows if you like
481 # -p "preparer id" - that's your email, for example
482 # -P "publisher_id" - again you
483 # -A "Application_id"
485 echo -n "Creating the CD iso image, $TOPDIR/bootcd.iso... "
486 mkisofs -b Boot.img -c boot.catalog \
487                -o $TOPDIR/bootcd.iso \
488                -r \
489                -J \
490                -p "your email address" \
491                -P "your name" \
492                -A "LFS Disk" \
493                .
495 echo "done"
497 # go back where we came from
498 cd $oldpwd
500 # now we can burn this image to a cd. 
502 Preparing the image system, before creating the iso
504 /etc/mtab must be a pointer to /proc/mounts
506 cd $LFS/etc
507 ls -l mtab
508 and if it is a file
509 mv mtab mtab.bak
510 ln -s /proc/mounts mtab
512 You need to replace the $LFS/etc/fstab
513 cd $LFS/etc
514 mv fstab fstab.bak
515 cat > fstab << EOF
516 /dev/ram2               /                       ext2    defaults        0 0
517 proc                    /proc                   proc    defaults        0 0
518 /swapspace              swap                    swap    defaults        0 0
521 You need the script checkcd to replace checkfs and mountfs
523 cat > $LFS/etc/rc.d/init.d/checkcd << EOF
524 #!/bin/sh
525 # Begin /etc/rc.d/init.d/checkcd
527 # Include the functions declared in the /etc/rc.d/init.d/functions file
529 source /etc/rc.d/init.d/functions
531 # Activate all the swap partitions declared in the /etc/fstab file
533 echo -n "Activating swap..."
534 /sbin/swapon -a
535 evaluate_retval
536 echo -n "Remounting root file system in read-write mode..."
537 /bin/mount -n -o remount,rw /
538 evaluate_retval
540 echo "Making /tmp writeable"
541 chmod 1777 /tmp
543 umount  /initrd/proc
544 umount  /initrd/dev
545 echo "Goodbye to the RAMDISK"
546 umount /initrd
549 Note that the umount of /initrd releases the boot image,
550 it is no longer needed.
552 You need the Detect script
553 cat > $LFS/etc/rc.d/init.d/Detect << EOF
554 #!/bin/bash
555 # Begin $rc_base/init.d/
557 # Based on sysklogd script from LFS-3.1 and earlier.
558 # Rewritten by Gerard Beekmans  - gerard@linuxfromscratch.org
560 source /etc/sysconfig/rc
561 source $rc_functions
563 case "$1" in
564         start)
565                 echo "Starting hardare detection"
566                 /sbin/lspci -v >& /tmp/t
567                 if grep OHCI /tmp/t >& /dev/null; then
568                      modprobe -a usb-ohci;
569                      modprobe -a hid;
570                 fi
571                 rm /tmp/t
572                 loadproc /sbin/Opendirs
573                 if [ -c /dev/input/mouse0 ]; then
574                     ln  -s  /dev/input/mouse0  /dev/mouse;
575                   else
576                     if [ -c /dev/misc/psaux ]; then
577                       ln  -s  /dev/misc/psaux  /dev/mouse;
578                     fi
579                 fi
580                 evaluate_retval
581                 ;;
583         stop)
584                 echo "Stopping..."
585                 killproc
586                 ;;
588         reload)
589                 echo "Reloading..."
590                 reloadproc
591                 ;;
593         restart)
594                 $0 stop
595                 sleep 1
596                 $0 start
597                 ;;
599         status)
600                 statusproc
601                 ;;
603         *)
604                 echo "Usage: $0 {start|stop|reload|restart|status}"
605                 exit 1
606                 ;;
607 esac
609 # End $rc_base/init.d/
611 And here is the source of the Opendirs program, (please do not laugh)
613 #include <sys/types.h>
614 #include <dirent.h>
615 #include <unistd.h>
616 #include <stdlib.h>
618 int main(void)
620 char  CD[12]     =  "/dev/cdroms";
621 char  IDEHD[12]  = "/dev/discs";
622 char  FLOPPY[12] = "/dev/floppy";
623 char  SCSIHD[12] = "/dev/scsi";
624 char  USB[12]    = "/dev/usb";
626 DIR  *D;
628        printf("Detecting CDs\n");
629        D = opendir(CD);
630        closedir(D);
631        printf("Detecting IDE HDs\n");
632        D = opendir(IDEHD);
633        closedir(D);
634        printf("Detecting floppy\n");
635        D = opendir(FLOPPY);
636        closedir(D);
637        printf("Detecting SCSI HDs\n");
638        D = opendir(SCSIHD);
639        closedir(D);
640        printf("Detecting USB\n");
641        D = opendir(USB);
642        closedir(D);
643        exit(0);
647 We need to disable some of the target system's start up scripts.
649 cd $LFS/etc/rc.d/rcsysinit.d
650 mv  S10swap      ZZZS10swap
651 mv  S20mountproc ZZZS20mountproc
652 mv  S30checkfs ZZZS30checkfs
653 mv  S40mountfs ZZZS40mountfs 
655 Check that your $LFS/etc/inittab will start up at level 3
657 Inspect your level 3 start up scripts and disable any that you think
658 are inappropriate.  Add the following links:
660 ln -s ../init.d/checkcd  S35checkcd
661 ln -s ../init.d/Detect   S40Detect
663 You need to tar $LFS/root and $LFS/etc
665 cd $LFS
666 tar cf root.tar root
667 tar cf etc.tar etc
669 Finally you need to put a marker file LFS-4.1 in the root; so
670 that the boot mechanism chooses the right CD.
672 touch  $LFS/LFS-4.1
674 7.  Building the image
676 Return to the build directory and set TOPDIR
678 cd where_ever_it_is/cd_builder
679 export TOPDIR=`pwd`
681 The directory cdtree must have the LFS root directory mounted.
682 On my system it is /dev/hdb6 so:
684 mount  /dev/hdb6  cdtree
686 If you have a separate partition for usr then mount this too
688 mount  /dev/hdxx  cdtree/usr
690 If you have a partition containing source you may also mount this.
691 Mine is /dev/hdb5 so:
693 mount  /dev/hdb5  cdtree/usr/src
695 You can now build the image:
697 bash  build.sh >& Build &
699 Check the output for any warning or any "file system full". 
700 A warning from lilo about lilo.conf not having the correct permissions is normal; the latest lilo will also warn about lba32 and compact.
702 If you have both the LFS and the LFS/usr/src mounted the image in bootcd.iso
703 will be about 300Mb.
705 Write this to a CD and try the system.
708 Restoration of the LFS system
709 There are two changes to be made before the image LFS system will reboot:
711 $LFS/etc/fstab
712 $LFS/etc/rc.d/rcsysinit.d
714 The fstab
715 cd $LFS/etc
716 cp fstab  fstab.cd
717 cp fstab.bak  fstab
719 The links
720 cd $LFS/etc/rc.d/rcsysinit.d
721 mv  ZZZS10swap    S10swap
722 mv  ZZZS20mountproc S20mountproc
723 mv  ZZZS30checkfs S30checkfs
724 mv  ZZZS40mountfs S40mountfs 
725 cd ../rc3.d
726 mv  S35checkcd ZZZS35checkcd
727 mv  S40Detect  ZZZS40Detect 
729 Your LFS system should now boot; enabling you to change and tune it.
730 Then add more software before building a better CD.
732 7.  Some uses for the boot CD
734 Broken files
736 Any partition can be mounted; files edited or replaced by those on the CD.
737 Mending a broken lilo
739 Suppose that the machine just does LILILILI on boot up.
741 Boot from the CD and mount your root partition to /disk;
742 if your not sure which partition; then test the partitions listed in
743 /proc/partition until you get the right one.
745 Once you have the broken root partition mounted do:
747 chroot /disk
748 export PATH=/bin:/sbin:/usr/bin:/usr/sbin
749 cd /etc
750 vi lilo.conf and fix what is wrong
751 then
752 lilo -C lilo.conf
754 Exit (from the chroot), unmount the disk and reboot.
756 What I have is an automated build of LFS on my CD.  I build LFS
757 systems onto empty machines.