Subversion Repositories livecd

Rev

Rev 69 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

#!/bin/bash
# initrd_create:  make initrd rootdisk by using busybox
#
# Author:         Tomas M. <http://www.linux-live.org>
#
# added by Urs Beyerle, PSI:
#
# add modules: nfs, sunrpc, lockd, nfs_acl (found in nfs_common)
# add drivers/net
# add x86_64 support
# add sata modules: ata_piix, libata
# add module: jbd
# add module: sr_mod
# unionctl.static can be installed locally
# add module ahci
# add module forcedeth 
# source ../../livecd.conf instead of ../config
# changes need for SL5:
#  - initrd blocksize to 4096 (instead of 1024)
#  - add fscache (for NFS support)
#  - add ide-cd, cdrom (for CD-ROM support)
# read $KERNEL from $1, can overwrite setting in livecd.conf
# add aufs (replacement for unionfs)
# add rev to static-binaries (for unionctl of aufs)
#

# . ../config || exit 1

. ../../livecd.conf || exit 1

# set an other kernel than the one set in livecd.conf
[ "$1" ] && KERNEL=$1
echo "take blocksize=$INITRD_BLOCKSIZE for initrd"

# arch
ARCH=$( /bin/arch )
[ "$ARCH" != "x86_64" ] && ARCH=i686



# rcopy is a recursive cp, which copies also symlink's real source
# $1 = source (may be a regular file or symlink)
# $2 = target PARENT
#
rcopy()
{
   if [ -L "$1" ]; then
      REALPATH="`readlink -f \"$1\"`"
      cp --parent -R "$REALPATH" "$2"
      ln -sf "$REALPATH" "$2/$1"
   else
      cp --parent -R "$1" "$2"
   fi
   if [ "$?" -ne 0 ]; then
      echo "---------------------------"
      echo "Error occured while trying to copy \"$1\" to \"$2\""
      echo "nevertheless your LiveCD may still work."
      echo "Possible reason: not enough free space in initrd or source doesn't exist"
      echo "---------------------------"
   fi
}

# copy file/dir only if it exists, else skip with no error
# $1 = source (may not exist)
# $2 = target PARENT
#
rcopy_ex()
{
   if [ -a "$1" ]; then
      rcopy "$1" "$2"
   fi
}

debug()
{
   # uncomment to show debug messages
   # echo "$@"
   return 0
}

##################################################
# Create INITRD image now:

MOUNTDIR=/tmp/initrd_mountdir_$$
INITRD_TREE=/tmp/initrd_tree_$$

LMK="lib/modules/$KERNEL"

UNIONFS_TYPE=""

if [ -e /$LMK/kernel/fs/unionfs/unionfs.ko ] || \
   [ -e kernel-modules/${KERNEL}_$ARCH/unionfs.ko.gz ]; then
    UNIONFS_TYPE="unionfs"
fi
if [ -e /$LMK/kernel/fs/aufs/aufs.ko ] || \
   [ -e kernel-modules/${KERNEL}_$ARCH/aufs.ko.gz ]; then
    UNIONFS_TYPE="aufs"
fi
if [ ! $UNIONFS_TYPE ]; then
    echo "ERROR: Neither aufs nor unionfs kernel module not found."
    exit 1
fi

if [ ! -e /$LMK/kernel/fs/squashfs/squashfs.ko ] && \
   [ ! -e kernel-modules/${KERNEL}_$ARCH/squashfs.ko.gz ]; then
    echo "ERROR: Squashfs kernel module not found."
    exit 1
fi

debug "creating directories"
mkdir -p $INITRD_TREE/{etc,dev,bin,mnt,livecd,proc,lib,sbin,sys,tmp,var/log}

debug "creating some essential devices in rootdisk"
mknod $INITRD_TREE/dev/console c 5 1
mknod $INITRD_TREE/dev/null c 1 3
mknod $INITRD_TREE/dev/ram b 1 1
mknod $INITRD_TREE/dev/systty c 4 0
mknod $INITRD_TREE/dev/tty c 5 0
for i in 1 2 3 4 5 6; do
  mknod $INITRD_TREE/dev/tty$i c 4 $i;
done

loops=255
while [ $loops -ge 0 ]; do
   mknod $INITRD_TREE/dev/loop$loops b 7 $loops
   loops=$(($loops-1))
done

debug "copying files to the rootdisk"
touch $INITRD_TREE/etc/{m,fs}tab
cp {linuxrc,liblinuxlive} $INITRD_TREE # symlink will be copied as original file
chmod a+x $INITRD_TREE/linuxrc

cp static-binaries/modprobe $INITRD_TREE/sbin
cp static-binaries/busybox $INITRD_TREE/bin
cp static-binaries/unionctl_${ARCH} $INITRD_TREE/bin/unionctl 
[ -x /usr/sbin/unionctl.static ] && cp -a /usr/sbin/unionctl.static $INITRD_TREE/bin/unionctl 
ln -s busybox $INITRD_TREE/bin/ash
ln -s busybox $INITRD_TREE/bin/sh
ln -s busybox $INITRD_TREE/bin/[

BUSYBOXCMDS="ash awk basename cat chmod chown chroot \
        clear cp cut dd df dirname du echo egrep eject \
        expr false fdisk fgrep find free grep gunzip halt \
        hdparm head hostname ifconfig ifdown ifup insmod \
        kill killall last ln logger losetup ls lsmod md5sum \
        mkdir mkfifo mknod mkswap mktemp more \
        mount mv pivot_root poweroff ps pwd readlink realpath \
        reboot rm rmdir rmmod route sed sh sleep sort \
        swapoff swapon sync tail tar tee test touch tr \
        true umount uname uniq vi wc xargs zcat"

for c in $BUSYBOXCMDS; do
    ln -s busybox $INITRD_TREE/bin/$c
done

# dhcp startup script
cp static-binaries/udhcpc.script $INITRD_TREE/bin
ln -s ../bin/busybox $INITRD_TREE/sbin/ifconfig

# lspci and pcitable for network card detection
cp static-binaries/lspci    $INITRD_TREE/sbin
cp static-binaries/pcitable $INITRD_TREE/bin

# rev needed for unionctl of aufs
if [ "$UNIONFS_TYPE" = "aufs" ]; then
    cp static-binaries/rev      $INITRD_TREE/bin
fi

LMK="lib/modules/$KERNEL"

# necessary modules and dependency files
mkdir -p $INITRD_TREE/$LMK/kernel/fs
cp kernel-modules/${KERNEL}_$ARCH/unionfs.ko.gz $INITRD_TREE/$LMK/kernel/fs 2>/dev/null
cp kernel-modules/${KERNEL}_$ARCH/aufs.ko.gz $INITRD_TREE/$LMK/kernel/fs 2>/dev/null
cp kernel-modules/${KERNEL}_$ARCH/squashfs.ko.gz $INITRD_TREE/$LMK/kernel/fs 2>/dev/null
rcopy_ex /$LMK/kernel/fs/unionfs $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/aufs $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/squashfs $INITRD_TREE 2>/dev/null

# copy filesystem modules, if not directly copied into kernel
rcopy_ex /$LMK/kernel/lib/zlib_inflate $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/block/loop* $INITRD_TREE 2>/dev/null

rcopy_ex /$LMK/kernel/fs/isofs $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/fat $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/vfat $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/ntfs $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/ext3 $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/jbd $INITRD_TREE 2>/dev/null

# for NFS support
rcopy_ex /$LMK/kernel/fs/nfs $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/nfs_common $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/lockd $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/fscache $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/net/sunrpc $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/net/sunrpc $INITRD_TREE 2>/dev/null

# net drivers
rcopy_ex /$LMK/kernel/drivers/net/mii.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/3c59x.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/8139cp.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/8139too.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/8390.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/e1000/e1000.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/e100.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/ns83820.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/tg3.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/pcnet32.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/tulip/tulip.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/b44.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/sk98lin/sk98lin.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/sky2.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/net/forcedeth.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/updates/drivers/net/sky2/sky2.ko $INITRD_TREE 2>/dev/null

# add language support for filesystems
# rcopy_ex /$LMK/kernel/fs/nls/ $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/nls/nls_cp437.*     $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/nls/nls_iso8859-1.* $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/fs/nls/nls_iso8859-2.* $INITRD_TREE 2>/dev/null

# cdrom support (for SL5)
rcopy_ex /$LMK/kernel/drivers/ide/ide-cd.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/cdrom/cdrom.ko $INITRD_TREE 2>/dev/null

# usb modules
rcopy_ex /$LMK/kernel/drivers/usb/storage $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/usb/host/ehci-hcd* $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/usb/host/ohci-hcd* $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/usb/host/uhci-hcd* $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/scsi/scsi_mod.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/scsi/sd_mod.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/scsi/sr_mod.ko $INITRD_TREE 2>/dev/null

# disk (scsi, ide, raid, pcmcia) modules
#rcopy_ex /$LMK/kernel/drivers/scsi $INITRD_TREE
#rcopy_ex /$LMK/kernel/drivers/ide $INITRD_TREE
#rcopy_ex /$LMK/kernel/drivers/pcmcia $INITRD_TREE

# disk sata (some sata modules)
rcopy_ex /$LMK/kernel/drivers/scsi/libata.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/scsi/ata_piix.ko $INITRD_TREE 2>/dev/null
rcopy_ex /$LMK/kernel/drivers/scsi/ahci.ko $INITRD_TREE 2>/dev/null


debug "gzipping kernel modules"
find $INITRD_TREE -name "*.ko" | xargs -r gzip --best

debug "generating module dependency files"
depmod -b $INITRD_TREE $KERNEL

debug "creating empty image file $INITRDIMG"
dd if=/dev/zero of=$INITRDIMG bs=$INITRD_BLOCKSIZE count=$RAM0SIZE >/dev/null 2>/dev/null

debug "making filesystem"
mkfs -t ext2 -F -m 0 -b $INITRD_BLOCKSIZE -i 1024 $INITRDIMG 2>/dev/null >/dev/null

debug "creating empty directory $MOUNTDIR"
rm -Rf $MOUNTDIR
mkdir $MOUNTDIR

debug "mounting $INITRDIMG to it"
mount -o loop $INITRDIMG $MOUNTDIR
if [ "$?" -ne 0 ]; then
   echo "Error mounting initrd! Not enough free loop devices?"
   exit 1
fi

debug "copying content of $INITRD_TREE to $MOUNTDIR"
rmdir $MOUNTDIR/lost+found
cp -R --preserve $INITRD_TREE/* $MOUNTDIR

debug "unmounting $MOUNTDIR"
umount $MOUNTDIR

debug "gzipping $INITRDIMG"
gzip --best $INITRDIMG

debug "deleting directory $MOUNTDIR"
rmdir $MOUNTDIR

debug "deleting directory $INITRD_TREE"
rm -Rf $INITRD_TREE

debug "$INITRDIMG.gz created"