#!/bin/bash # Part of the gn*nix conspiracy http://gnnix.org # Copyright (c) 2004 Linus Sphinx # /usr/sbin/gnxinitrfs # builds an initramfs disk with the desired modules # IF NOT -a -m -k use DIALOG to select kernel/modules # and handle all dependencies # backtitle="gn*nix initial ram file system builder" # filtered out in longlist, stuff not on the menu for -a auto-mode # are forbidden directories to skip under /lib/module/$KVER/kernel/ FORBIDDEN="net sound drivers/net drivers/sound drivers/video drivers/input/gameport" # PATH=/bin:/sbin:/usr/bin:/usr/sbin DIALOG=dialog DIALOGRC=/etc/bw.rc # note trailing slash in BOOTDIR BOOTDIR=/boot/ KLIBC=/usr/share/klibc DEFAULTLINK=/boot/initramfs.img # use default link to avoid editing grub menu DEFAULTRAMFS="/boot/gnxinitramfs-`uname -r`.img" INITRFSROOT=/tmp/gnxinitramfs-root-$$ SHORTLIST=/tmp/gnxinitramfs-sl-$$ LONGLIST=/tmp/gnxinitramfs-ll-$$ MKRFSLOG=/tmp/gnxinitramfs-log-$$ ROOTDEV="" ROOTTYP="" # hush is set by -a, means link DEFAULTRAMFS to DEFAULTLINK quietly no menu HUSH=0 export DIALOG DIALOGRC INITRFSROOT KLIBC MKRFSLOG SHORTLIST ROOTDEV ROOTTYP KVER LONGLIST cleanup() { echo "" rm -f ${LONGLIST} rm -f ${SHORTLIST} rm -rf ${INITRFSROOT} rm -f $MKRFSLOG } driverslist() { if [ "$1" = "fs" ]; then # different path pat=^/lib/modules/${KVER}/kernel/${1}/ # /lib/modules/2.6.7/kernel/fs/smbfs/smbfs.ko: else pat=^/lib/modules/${KVER}/kernel/drivers/${1}/ fi grep -q -E "${pat}" /lib/modules/${KVER}/modules.dep if [ "$?" = "0" ]; then grep -E "${pat}" /lib/modules/${KVER}/modules.dep | while read g do set $g mod=$(basename $1 .ko: | sed sG^/w+/GG) for d in $2 $3 $4 $5 $6 $7 $8 $9 do dep="$dep $(basename $d .ko | sed sG^/w+/GG)" done if [ "$mod" = "" ]; then mod=none fi if [ "$dep" = "" ]; then dep=none else dep=$(echo $dep | sed sQ\ Q/Qg) fi echo $mod ${dep# } $mod dep="" done else echo none none none fi } builddriverlist() { $DIALOG --clear --separate-output \ --backtitle "$backtitle" --ok-label "Load selected" \ --title "available drivers" --cancel-label "Back" --checklist \ "Install Module Dependents" 0 40 0 $(driverslist ${1}) 2>>${SHORTLIST} } longlist() { if [ -s ${SHORTLIST} ]; then while read b do todo=$(grep /${b}.ko: /lib/modules/${KVER}/modules.dep | sed sQ:QQ) if [ ! -z "$todo" ]; then z=0 for y in $FORBIDDEN do echo $todo | grep -q ^/lib/modules/${KVER}/kernel/${y} if [ "$?" = "0" ]; then z=1 fi done if [ "$z" = "0" ]; then set $todo echo "$9 $8 $7 $6 $5 $4 $3 $2 $1" | sort | uniq | while read driver do if [ ! "$driver" = "none" -a ! -z "$driver" ]; then mkdir -p ${INITRFSROOT}${driver%/*} cp -a ${driver} ${INITRFSROOT}${driver} echo /bin/insmod ${driver} fi done fi fi done < ${SHORTLIST} fi } modulemenu() { while true do exec 3>&1 modval=$($DIALOG --clear \ --backtitle "$backtitle" \ --title "available modules" --ok-label "Select" --cancel-label "Back" --menu \ "Select/load the minimum required to recognize your target media and filesystem(s) to use." 0 0 0 \ "fs" "File Systems " \ "md" "Medial Distribution(raid) " \ "scsi" "SCSI Disk Controllers " \ "ide" "IDE Disk Controllers " \ 2>&1 1>&3) modretval=$? exec 3>&- case $modretval in 0) builddriverlist $modval ;; 1) echo "Exiting" return ;; esac done } modchooser() { #11 55 4 \ while true do exec 3>&1 modval=$($DIALOG --clear \ --backtitle "$backtitle" \ --title "Select modules and create an initial ram file system" \ --ok-label "Select" --cancel-label "Quit" --menu \ "Kernel: $1 Root: $2 Type: $3" \ 0 0 0 \ "1" "Add To The Modules List " \ "2" "View The Modules List " \ "3" "Create Init Ram Filesystem " \ "4" "Clear The Modules List " \ 2>&1 1>&3) modretval=$? exec 3>&- case $modretval in 0) if [ "$modval" = "1" ]; then modulemenu elif [ "$modval" = "2" ]; then if [ -s $SHORTLIST ]; then rm -f $LONGLIST longlist | while read i do echo ${i#/bin/insmod } >> $LONGLIST done $DIALOG --clear \ --backtitle "$backtitle" \ --title "modules for initial ram file system" --exit-label "Close" --tailbox $LONGLIST 0 0 else $DIALOG --clear \ --backtitle "$backtitle" \ --title "modules for initial ram file system" --exit-label "Close" --msgbox "List Is Empty" 0 0 fi elif [ "$modval" = "3" ]; then buildinitrfs elif [ "$modval" = "4" ]; then $DIALOG --clear \ --backtitle "$backtitle" \ --yesno "Clear Module List?" 0 0 if [ $? = 0 ]; then rm -f ${SHORTLIST} fi fi ;; 1) cleanup exit 0 ;; esac done } findtype() { grep -E '^\/dev\/' /etc/fstab | while read i do set $i if [ "$2" == "/" ]; then echo $3 return fi done } findroot() { grep -E '^\/dev\/' /etc/fstab | while read i do set $i if [ "$2" == "/" ]; then echo $1 return fi done } autoshortlist() { while read i do if [ ! -z "${i}" ]; then set ${i} echo $1 >> ${SHORTLIST} fi done } < /proc/modules # pass $FILE updatedefaultlink() { $DIALOG --clear --backtitle "$backtitle" --yesno \ "Link default menu boot to ${FILE}?" 6 30 case $? in 0) cd /boot ln -sf ${1#/boot/} ${DEFAULTLINK#/boot/} ;; 1) ;; esac cd /boot $DIALOG --clear --backtitle "$backtitle" --title "default boot menu link" \ --msgbox "`ls -logn ${DEFAULTLINK#/boot/}`" 6 70 } # passed INITRFSROOT INITRAMFS makeramfs() { retcode=1 while [ $retcode = 1 ] do exec 3>&1 FILE=`$DIALOG --backtitle "$backtitle" --title \ "Do Not Use initramfs.img" --fselect $2 6 55 2>&1 1>&3` code=$? exec 3>&- case $code in 0) #echo "\"$FILE\" chosen" if [ -d $FILE ]; then BOOTDIR=$FILE/ elif [ -e $FILE ]; then $DIALOG --clear --backtitle "$backtitle" --yesno \ "Overwrite ${FILE}?" 6 30 case $? in 0) echo " Overwrote Image: ${FILE} Root Device: ${ROOTDEV} Root Type: ${ROOTTYP}" > $MKRFSLOG cd $INITRFSROOT find | cpio --create --dereference --format=newc | gzip -9 - > $FILE 2>> $MKRFSLOG cd /boot echo "Modules:" >> $MKRFSLOG longlist | while read i do echo " ${i#/bin/insmod }" >> $MKRFSLOG done ls -logn $FILE >> $MKRFSLOG df -k $BOOTDIR >> $MKRFSLOG # echo "Activating init script to reclaim memory at startup..." >> $MKRFSLOG # chmod +x /sbin/init.d/initrd # echo "chmod +x /sbin/init.d/initrd returned: $?" >> $MKRFSLOG retcode=0 ;; 1) FILE=$2 retcode=1 ;; esac else $DIALOG --clear --backtitle "$backtitle" --yesno "Write NEW ${FILE}?" 6 30 case $? in 0) echo " New Image: ${FILE} Root Device: ${ROOTDEV} Root Type: ${ROOTTYP}" > $MKRFSLOG cd $INITRFSROOT find | cpio --create --dereference --format=newc | gzip -9 - > $FILE 2>> $MKRFSLOG cd /boot ls -logn $FILE >> $MKRFSLOG df -k $BOOTDIR >> $MKRFSLOG # echo "Activating init script to reclaim memory at startup..." >> $MKRFSLOG # chmod +x /sbin/init.d/initrd # echo "chmod +x /sbin/init.d/initrd returned: $?" >> $MKRFSLOG retcode=0 ;; 1) FILE=$2 retcode=1 ;; esac fi retcode=0 ;; 1) #echo "Cancel pressed." retcode=0 ;; 255) #echo "Box closed." retcode=0 ;; esac done if [ -e $MKRFSLOG ]; then $DIALOG --clear \ --backtitle "$backtitle" \ --title "Make Init Ram File System Log" --exit-label "Close" --tailbox $MKRFSLOG 0 0 updatedefaultlink $FILE fi } buildinitrfs() { mkdir -p ${INITRFSROOT}/{bin,sbin,dev,etc,lib,proc,sys,sysroot} cd ${INITRFSROOT} ln -s ${KLIBC}/bin/* ${INITRFSROOT}/bin ln -s ${KLIBC}/lib/* ${INITRFSROOT}/lib ln -s /etc/fstab ${INITRFSROOT}/etc/fstab # udev ln -s /etc/udev ${INITRFSROOT}/etc ln -s /sbin/udev ${INITRFSROOT}/sbin ln -s /sbin/udevstart ${INITRFSROOT}/sbin ln -s /lib/libc.so.* ${INITRFSROOT}/lib ln -s /lib/ld*.so.* ${INITRFSROOT}/lib # eoudev if [ -e /etc/modprobe.conf ]; then ln -s /etc/modprobe.conf etc/modprobe.conf fi # launch sequence echo "#!/bin/sh echo gnxinitramfs engaged... /bin/mount -t proc proc /proc /bin/mount -t sysfs sysfs /sys" >> ${INITRFSROOT}/init longlist >> ${INITRFSROOT}/init echo "/sbin/udevstart /bin/mount -t ${ROOTTYP} -o ro ${ROOTDEV} /sysroot umount /sys umount /proc echo activating launch sequence exec run-init /sysroot /sbin/init $@" >> ${INITRFSROOT}/init chmod +x ${INITRFSROOT}/init # eo launch sequence if [ $HUSH = 0 ]; then makeramfs $INITRFSROOT $INITRAMFS else cd $INITRFSROOT find | cpio --create --dereference --format=newc | gzip -9 - > $DEFAULTRAMFS cd /boot ln -sf ${DEFAULTRAMFS#/boot/} ${DEFAULTLINK#/boot/} fi } usage() { echo " usage: $0 where possible options are: -k version number of the kernel to use as 2.6.7 -r path of the device in /dev to mount as root -t type of the root device in /dev to fsck -a auto build with all of the currently loaded modules -m \"module1 module2 module3...\" auto build but use the modules, auto adding any dependents in the quoted list of modules needed to see a root device -? this message note: zcat /boot/gnxinitrd-.img | cpio --extract will unpack one. " cleanup 0 } if [ ! -e ${INITRFSROOT} ]; then mkdir -p ${INITRFSROOT} fi while getopts :k:r:t:m:a narg do case $narg in k) KVER=${OPTARG} ;; r) ROOTDEV=${OPTARG} ;; t) ROOTTYP=${OPTARG} ;; m) HUSH=1 KVER=$(uname -r) ROOTDEV=$(findroot) ROOTTYP=$(findtype) INITRAMFS=$DEFAULTRAMFS MODULES="${OPTARG}" rm -f $SHORTLIST for i in $MODULES do echo $i >> $SHORTLIST done buildinitrfs exit 0 ;; a) if [ ! -s /proc/modules ]; then HUSH=1 KVER=$(uname -r) ROOTDEV=$(findroot) ROOTTYP=$(findtype) INITRAMFS=$DEFAULTRAMFS autoshortlist buildinitrfs else rm -f /boot/gnnix.img touch /boot/gnnix.img fi cleanup exit 0 # end program ;; \?|h) usage exit 0 ;; esac done lskernel() { ls -1 /lib/modules | while read i do echo -n "$i _ " done } kernelmenu() { k=$(lskernel) while true do exec 3>&1 kern=$($DIALOG --clear \ --backtitle "$backtitle" --cancel-label "Quit" \ --title " gnnix initial ram file system" --ok-label "Select" \ --menu "Version kernel modules available:" 10 38 3 $k 1>&2 2>&3) retval=$? exec 3>&- case $retval in 0) echo $kern return ;; 1) exit 0 ;; esac done } if [ -z $KVER ]; then KVER=$(kernelmenu) fi if [ -z $ROOTDEV ]; then ROOTDEV=$(findroot) fi if [ -z $ROOTTYP ]; then ROOTTYP=$(findtype) fi if [ -z $INITRAMFS ]; then INITRAMFS=$DEFAULTRAMFS fi if [ -z $KVER ]; then echo no kernel version chosen cleanup exit 1 fi if [ ! -e ${INITRFSROOT} ]; then mkdir -p ${INITRFSROOT} fi INITRAMFS="/boot/gnxinitrd-$KVER.img" if [ -z "$ROOTDEV" ]; then ROOTDEV=$(findroot) fi if [ -z "$ROOTTYP" ]; then ROOTTYP=$(findtype) fi if [ -z "$MODULES" ]; then modchooser $KVER $ROOTDEV $ROOTTYP fi #eof