head     1.1;
branch   1.1.1;
access   ;
symbols  LTP_20031204:1.1.1.1 LINUX_TEST_PROJECT:1.1.1;
locks    ; strict;
comment  @# @;


1.1
date     2003.12.31.09.00.32;  author mtm;  state Exp;
branches 1.1.1.1;
next     ;

1.1.1.1
date     2003.12.31.09.00.32;  author mtm;  state Exp;
branches ;
next     ;


desc
@@



1.1
log
@Initial revision
@
text
@#! /bin/sh
################################################################################
##                                                                            ##
## Copyright (c) International Business Machines  Corp., 2001                 ##
##                                                                            ##
## This program is free software;  you can redistribute it and#or modify      ##
## it under the terms of the GNU General Public License as published by       ##
## the Free Software Foundation; either version 2 of the License, or          ##
## (at your option) any later version.                                        ##
##                                                                            ##
## This program is distributed in the hope that it will be useful, but        ##
## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ##
## or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   ##
## for more details.                                                          ##
##                                                                            ##
## You should have received a copy of the GNU General Public License          ##
## along with this program;  if not, write to the Free Software		          ##
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    ##
##									                                          ##
################################################################################
# File:        mkrootfs
#
# Description: script to create rootfs that will fit on a floppy. This 
#              filesystem contains a staticly linked busybox that provides
#              basic commands and a shell.
#
# Author:      Manoj Iyer - manjo@@mail.utexas.edu
#
# History:     June 17 2003 - Created.
#


TWDIR=/tmp/mkrootfs.$$ # temporary working directory 

clean()
{    
    echo "INFO: Cleaning and exiting program"
 
    mount | grep "$TWDIR/mnt" 2>&1 >/dev/null && \
    {
        echo "INFO: unmounting $TWDIR/mnt"
        umount $TWDIR/mnt 2>&1 >/dev/null || \
        {
            echo "WARNING: failed unmounting temporary device."
            echo "WARNING: clean up temporary devices manually"
        }
     }

    rm -fr $TWDIR 2>&1 >/dev/null || \
    {
        echo "WARNING: failed to remove temporary working directory"
        echo "WARNING: clean up temporary files and directories manually"
    }

    [ -a ./busybox-0.60.5.tar.gz ] && \
    {
        rm ./busybox-0.60.5.tar.gz 2>&1 >/dev/null || \
        {
            echo "WARNING: unable to remove busybox tarball"
            echo "WARNING: clean up temporary files and directories manually"
        }
    }
}


usage()
{
    echo "Usage: `basename $0` [-b] -c -d <HDDTYPE> -f <fSTYPE> -h"
    echo " "
    echo " "
    echo " -b            location of the staticly linked busybox binary."
    echo "               (if you dont provide one, this script will build one)"
    echo " -c            creates rootfs on floppy."
    echo "               (if this option is not provided rootfs.gz will be "
    echo "                created in the current working directory.)"
    echo " -d <HDDTYPE>  options available are scsi or ide"
    echo " -f <FSTYPE>   options available are ext2, ext3, reiserfs, xfs"
    echo " -h            help"
    echo " "
    echo "Example: `basename $0` -b /tmp/busybox-dir/ -c -d ide -f ext2"
    exit 0
}


help()
{
    echo "This program will create a root file system with busybox commads."
    echo "Follow these steps to boot your machine with this file system"
    echo "1. create a boot floppy."
    echo "   - use command: dd if=<path>/bzImage of=/dev/fd0h1440 bs=1k"
    echo "2. create a root floppy "
    echo "   - using this program eg: $0 -c -d scsi -f ext2 "
    echo "3. boot machine with kernel in boot floppy"
    echo "   - provide boot options root=/dev/fd0h1440 (floppy device)"
    echo "4. insert root floppy when prompted by the kernel."
    echo "5. after you boot with this rootfs, remount '/' dir to read write"
    echo "   - use command: mount -o remount -w rootfs / "
    echo " "
    echo " "
    usage
}


main()
{
    local SYS_DIR=" "                 # names of various system directory
    local SYS_DEV=" "                 # names of various system devices
    local RC=0                        # return value from commands.
    local FORCEREI=" "                # force mkfs.reiserfs to be quite
    local CREATEFD=0                  # flag to create floppy or just image
    local FSTYPE=ext2                 # file system type default is ext2
    local HDDTYPE=ide                 # HDD type SCSI or IDE default: ide
    local BBLOC="NONE"                # location of static busybox binary.

    # parse input arguments
    while getopts b:cd:f:h arg
    do case $arg in 
        b) BBLOC=$OPTARG;;
        c) CREATEFD=1;;
        d) HDDTYPE=$OPTARG;;
        f) FSTYPE=$OPTARG;;
        h) help;;
        \?) usage;;
       esac
    done       

    # on exit clean up all temporary files and directories.
    trap "clean" 0

    # create temporary working directory 
    mkdir -p $TWDIR  2>&1 || \
    {
        echo "FAILED: creating temporary working directory"
        exit 1
    }

    # make block or character special files called ramdisk_fs
    mknod $TWDIR/ramdisk_fs b 1 0 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: creating block file $TWDIR/ramdisk_fs"
        echo "FAILED: `cat $TWDIR/crfs.out`"
        exit 1;
    }

    # create a file system of required size, zeroing is important because
    # the filesystem will be compressed before its put on a floppy, zeroing
    # achives maximum compression. Creating a block file of size 8K.

    dd if=/dev/zero of=$TWDIR/ramdisk_fs bs=1k count=8 \
        2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: unable create filesystem of 8K size"
        echo "FAILED: `cat $TWDIR/crfs.out`"
        exit 1
    }

    # create the filesystem, EXT2 file system will be default.
    if [ $FSTYPE == "ext2" ]; then
        mke2fs -v -m 0 -N 2000 $TWDIR/ramdisk_fs 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: unable to create EXT2 filesystem on block file."
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        } 
    else 
        [ "$FSTYPE" == "reiserfs" ] && \
        { 
            FORCEREI="-f -f";
        }
        mkfs.$FSTYPE $FORCEREI $TWDIR/ramdisk_fs 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: unable to create $FSTYPE filesystem on block file."
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }
    fi

    # mount this filesystem so that it can be populated with system files and
    # commands.

    # create a temporary mount directory.

    mkdir -p $TWDIR/mnt 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: creating temporary mount directory"
        exit 1
    }

    mount -o loop $TWDIR/ramdisk_fs $TWDIR/mnt 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: unable to mount block file TWDIR/ramdisk_fs on $TWDIR/mnt"
        echo "FAILED: `cat $TWDIR/crfs.out`"
        exit 1
    }

    # remove lost+found directory from the rootfs file system, this is not
    # required.

    rm -fr $TWDIR/mnt/lost+found 2>&1 >$TWDIR/crfs.out || \
    {
        echo "WARNING: unable to remove lost+found from $TWDIR/mnt/ directory"
        echo "WARNING: `cat $TWDIR/crfs.out`"
    }

    # create system directories.

    for SYS_DIR in bin boot dev etc etc/init.d etc/rc.d lib mnt opt proc \
                   root sbin tmp usr usr/bin usr/sbin usr/lib usr/share \
                   var var/lock var/log var/run var/lib/rpm
    do
        mkdir -p $TWDIR/mnt/$SYS_DIR 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating $SYS_DIR"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }
    done

    # initialize RPM database, just in case any RPMs will be installed to this
    # root filesystem.
    rpm --initdb --root=$TWDIR/mnt 2>&1 >$TWDIR/crfs.out || \
    {
        echo "WARNING: initializing RPM database."
        echo "WARNING: cat `$TWDIR/crfs.out`"
    }

    # setting up the /etc directory, the three main files that will 
    # be created are fstab, rc.sysinit and inittab.

    # create the inittab file.
    cat > $TWDIR/mnt/etc/inittab <<-EOF || RC=$?
    ::sysinit:/etc/rc.d/rc.sysinit
    ::askfirst:/bin/sh
	EOF

    [ $RC -ne 0 ] && \
    {  
        echo "FAILED: creating inittab file"
        exit 1
    }

    # changing perissions if inittab file to 644
    chmod 644 $TWDIR/mnt/etc/inittab 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: changing permissions of $TWDIR/mnt/etc/inittab"
        exit 1
    }

    # create a /etc/rc.d/rc.sysinit file.
    cat > $TWDIR/mnt/etc/rc.d/rc.sysinit <<-EOF || RC=$?
    #!/bin/sh

    mount -a -n
	EOF

    [ $RC -ne 0 ] && \
    {
        echo "FAILED: creating rc.sysinit file"
        exit 1
    }

    # changing perissions of rc.sysinit file to 755
    chmod 755 $TWDIR/mnt/etc/rc.d/rc.sysinit 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: changing permissions of $TWDIR/mnt/etc/rc.d/rc.sysinit"
        exit 1
    }


    # creating etc/fstab file.
    cat > $TWDIR/mnt/etc/fstab <<-EOF || RC=$?
    /dev/ram0 / ext2 defaults 0 0
    dev/fd0   / ext2    defaults 0 0
    /proc /proc proc defaults 0 0
    none /tmp tmpfs defaults 0 0
	EOF

    [ $RC -ne 0 ] && \
    {
        echo "FAILED: creating etc/fstab file"
        exit 1
    }

    # changing perissions of rc.sysinit file to 644
    chmod 644 $TWDIR/mnt/etc/fstab 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED: changing permissions of $TWDIR/mnt/etc/fstab"
        exit 1
    }

    # setting up /dev directory. Assuming that this script is 
    # executed on a linux system, contents of /dev directory of the 
    # host system will simply be copied to the rootfs file. Alternatively 
    # the mknod command may be used to create 
    # each device file. But the former is quick and easy.

    # set up floppy drives. /dev/null and /dev/console
    for SYS_DEV in /dev/fd[01]* /dev/null /dev/console /dev/zero
    do
        cp -dpR $SYS_DEV $TWDIR/mnt/dev 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating $SYS_DEV on $TWDIR/mnt/dev"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }
    done

    # set up scsi or ide devices.

    if [ "$HDDTYPE" == "scsi" ] || [ "$HDDTYPE" == "SCSI" ] 
    then
        # set up SCSI cdrom drives.
        cp -dpR /dev/sr0 $TWDIR/mnt/dev 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating SCSI cdrom device on $TWDIR/mnt/dev"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }

        # set up SCSI hard drives.
        cp -dpR /dev/sd* $TWDIR/mnt/dev 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating SCSI cdrom device on $TWDIR/mnt/dev"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }
    elif [ "$HDDTYPE" == "ide" ] || [ "$HDDTYPE" == "IDE" ] ; then
        # set up IDE cdrom drive.
        cp -dpR /dev/cdrom    $TWDIR/mnt/dev 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating SCSI cdrom device on $TWDIR/mnt/dev"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }

        # set up IDE hard drives.
        cp -dpR /dev/hd* $TWDIR/mnt/dev 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: creating SCSI cdrom device on $TWDIR/mnt/dev"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }
    else
        echo "FAILED: unknown hardware type:"
        usage
    fi


    # setting up busybox. 

    if [ "$BBLOC" == "NONE" ]
    then
        echo "NFO: downloading busybox from www.busybox.net"
        wget -q -c http://www.busybox.net/downloads/busybox-0.60.5.tar.gz \
            2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: fetching busybox from www.busybox.net"
            exit 1
        }
 
        tar zxf ./busybox-0.60.5.tar.gz 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: uncompressing busybox tar ball"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }


        mv ./busybox-0.60.5 $TWDIR/ 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: moving busybox dir  to temporary working dir"
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }

        echo "INFO: Compiling static busybox... this will take few minutes"

        make -C $TWDIR/busybox-0.60.5 clean 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: compiling static busybox."
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }

        make -C $TWDIR/busybox-0.60.5 DOSTATIC=true 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: compiling static busybox."
            echo "FAILED: `cat $TWDIR/crfs.out`"
            exit 1
        }

        cp $TWDIR/busybox-0.60.5/busybox $TWDIR/mnt/bin/ 2>&1 \
            >$TWDIR/crfs.out || \
        {
            echo "FAILED: copying busybox binary to $TWDIR/mnt/bin/"
            exit 1
        }
    elif [ -z $BBLOC ]; then
        echo "FAILED: bad path for static busybox"
        usage
    else
        cp $BBLOC/busybox $TWDIR/mnt/bin/ 2>&1 \
           >$TWDIR/crfs.out || \
        {   
            echo "FAILED: copying busybox binary to $TWDIR/mnt/bin/"
            exit 1
        }   
    fi

    echo "INFO: installing busybox"
    # set up / directory
    ln -f $TWDIR/mnt/bin/busybox $TWDIR/mnt/linuxrc 2>&1 \
         >$TWDIR/crfs.out || \
    {
         echo "FAILED: linking busybox to linuxrc"
         exit 1
    }

    # set up /usr/sbin directory
     ln -f $TWDIR/mnt/bin/busybox $TWDIR/mnt/usr/sbin/chroot 2>&1 \
         >$TWDIR/crfs.out || \
     {
         echo "FAILED: linking busybox to chroot"
         exit 1
     }
 
     # set up /bin directory
     for SYS_CMD in ash chmod dd false kill mknod pidof rmdir sync umount \
                     chown df grep ln more ps sed tar uname cat cp dmesg  \
                     gunzip ls mount pwd sh touch zcat chgrp date echo gzip \
                     mkdir mv rm sleep true
     do
         ln -f $TWDIR/mnt/bin/busybox $TWDIR/mnt/bin/$SYS_CMD 2>&1 \
             >$TWDIR/crfs.out || \
         {
             echo "FAILED: linking busybox to $SYS_CMD"
             echo "FAILED: `cat $TWDIR/crfs.out`"
             exit 1
         }
     done
 
     # set up /sbin directory
     for SYS_CMD in halt  klogd  mkswap    poweroff  swapoff  syslogd \
                    init  lsmod  modprobe  reboot    swapon
     do
         ln -f $TWDIR/mnt/bin/busybox $TWDIR/mnt/sbin/$SYS_CMD 2>&1 \
             >$TWDIR/crfs.out || \
         {
             echo "FAILED: linking busybox to $SYS_CMD"
             echo "FAILED: `cat $TWDIR/crfs.out`"
             exit 1
         }
     done

     # set up /usr/bin directory
     for SYS_CMD in clear   du    free      killall  sort \
                    tty   wc      xargs basename  cut      env   head \
                    logger tail  uniq    which   yes chvt  dirname \
                    find  id    reset    test  uptime  whoami
     do
         ln -f $TWDIR/mnt/bin/busybox $TWDIR/mnt/usr/bin/$SYS_CMD 2>&1 \
             >$TWDIR/crfs.out || \
         {
             echo "FAILED: linking busybox to $SYS_CMD"
             echo "FAILED: `cat $TWDIR/crfs.out`"
             exit 1
         }
     done
 
    # sync'ing changes to disk.

    sync; sync; sync; sync; sync; sync;

    echo "INFO: creating compressed file system"
    # creating compressed file system.
    dd if=$TWDIR/ramdisk_fs bs=1k | gzip -v9 > $TWDIR/rootfs.gz || \
    {
        echo "FAILED: creating compressed file system."
        exit 1
    }

    # create a copy of the rootfs.gz on PWD. 
    cp $TWDIR/rootfs.gz ./ 2>&1 >$TWDIR/crfs.out || \
    {
        echo "FAILED:  coping rootfs.gz from temp directory to $PWD"
        echo "FAILED: `cat $TWDIR/crfs.out`"
        exit 1
    }
 
    if [ $CREATEFD -ne 0 ]
    then
        # creating filesystem on floppy 
        if [ $FSTYPE == "ext2" ]; then
            mke2fs -v -m 0 -N 24 /dev/fd0h1440 2>&1 >$TWDIR/crfs.out || \
            {
                echo "FAILED: unable to create EXT2 filesystem on floppy"
                echo "FAILED: `cat $TWDIR/crfs.out`"
                echo "INFO: mke2fs -m 0 -N 24 /dev/fd0h1440"
                echo "INFO: and dd rootfs.gz to this floppy"
                exit 1
            } 
        else 
            [ "$FSTYPE" == "reiserfs" ] && \
            { 
                FORCEREI="-f -f";
            }
            mkfs.$FSTYPE $FORCEREI /dev/fd0h1440 2>&1 >$TWDIR/crfs.out || \
            {
                echo "FAILED: unable to create $FSTYPE on floppy"
                echo "FAILED: `cat $TWDIR/crfs.out`"
                echo "INFO: mke2fs -m 0 -N 24 /dev/fd0h1440"
                echo "INFO: and dd rootfs.gz to this floppy"
                exit 1
            }
        fi

        sync; sync; sync; sync 
        # dd the rootfs on to floppy, if the rootfs.gz is greater than 
        # dd will fail so no pre-check is done on size of rootfs.gz
        dd if=$TWDIR/rootfs.gz of=/dev/fd0h1440 bs=1k 2>&1 >$TWDIR/crfs.out || \
        {
            echo "FAILED: dd'ing the rootfs.gz onto floppy."
            echo "FAILED: `cat $TWDIR/crfs.out`"
            echo "INFO: please try it manually" 
            echo "INFO: dd if=./rootfs.gz of=/dev/fd0 bs=1k"
            exit 1
        }
        exit 0
    else
            echo "INFO: create floppy manually"
            echo "INFO: rootfs.gz in in $PWD directory"
            echo "INFO: dd if=./rootfs.gz of=/dev/fd0 bs=1k"
            exit 0
    fi
}

main "$@@"
@


1.1.1.1
log
@Initial import of the Linux Test Project (http://ltp.sourceforge.net).

This import is minus the Posix test suite, which will be imported separately,
and the HPI suite, which doesn't concern us.
@
text
@@
