From b3b2f8339029befa0914467901fac24bd2ea1d40 Mon Sep 17 00:00:00 2001 From: Tobias Hintze Date: Thu, 23 Mar 2006 00:32:30 +0000 Subject: [PATCH] Tobias Hintze : hotfix from stf for rockinitrd git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@7330 c5f82cb5-29bc-0310-9cd0-bff59a50e3bc --- package/base/rockinitrd/initrd_essential.txt | 12 + package/base/rockinitrd/mkinitrd.sh | 234 ++++++++++++++----- package/base/rockinitrd/rockinitrd.conf | 1 + package/base/rockinitrd/rockinitrd.desc | 2 +- 4 files changed, 188 insertions(+), 61 deletions(-) create mode 100644 package/base/rockinitrd/initrd_essential.txt diff --git a/package/base/rockinitrd/initrd_essential.txt b/package/base/rockinitrd/initrd_essential.txt new file mode 100644 index 000000000..014ad7c2c --- /dev/null +++ b/package/base/rockinitrd/initrd_essential.txt @@ -0,0 +1,12 @@ +/bin/bash /bin/bash +/bin/bash2 /bin/bash2 +/bin/sh /bin/sh +/bin/ls /bin/ls +/sbin/pivot_root /sbin/pivot_root +/sbin/insmod /sbin/insmod +/sbin/insmod.old /sbin/insmod.old +/bin/mount /bin/mount +/bin/umount /bin/umount +/usr/bin/chroot /usr/bin/chroot +/etc/fstab /etc/fstab +/bin/mkdir /bin/mkdir diff --git a/package/base/rockinitrd/mkinitrd.sh b/package/base/rockinitrd/mkinitrd.sh index 883d93018..1d073033b 100644 --- a/package/base/rockinitrd/mkinitrd.sh +++ b/package/base/rockinitrd/mkinitrd.sh @@ -1,110 +1,224 @@ #!/bin/bash kernel=`uname -r` -tmpdir=`mktemp -d` +targetdir=`mktemp -d` modprobeopt=`echo $kernel | sed '/2.4/ { s,.*,-n,; q; }; s,.*,--show-depends,'` empty=0 -if [ "$1" = "empty" ]; then - empty=1; shift -fi +rootdir="" +cross_compile="" +initrdfs="cramfs" +block_size="" +ramdisk_size=8192 -if [ -n "$1" ]; then - if [ -d "/lib/modules/$1" ]; then - kernel="$1" - else - echo "Can't open /lib/modules/$1: No such directory." - echo "Usage: $0 [ kernel-version ]" - exit 1 - fi -fi +# Successfully tested combinations: +# ARM (QEMU) 1024 ext2fs +# ARM (QEMU) 4096 cramfs +# x86 (QEMU) 1024 ext2fs +# x86 (QEMU) 4096 cramfs + +while [ $# -gt 0 ] ; do + case $1 in + empty) empty=1 ;; + -root) + if [ -d "$2/" ]; then + rootdir="${2%/}" ; shift + else + echo "Can't open ${2}: No such directory." + echo "Usage: $0 [ kernel-version ]" + exit 1 + fi + ;; + -cross) cross_compile="$2" ; shift ;; + -bs) block_size="$2" ; shift ;; + -fs) + case "$2" in + ext2fs|ext3fs|cramfs|ramfs) initrdfs="$2" ; shift ;; + *) + echo "Filesystem $2 not supported as initrd filesystem." + exit 1 + ;; + esac + ;; + *) + if [ -d "${rootdir}/lib/modules/$1" ]; then + kernel="$1" + echo kernel $kernel + else + echo "Can't open ${rootdir}/lib/modules/$1: No such directory." + echo "Usage: $0 [ kernel-version ]" + exit 1 + fi + ;; + esac + shift +done -echo "Creating /boot/initrd-${kernel}.img ..." -mkdir -p $tmpdir/etc/conf +case $initrdfs in + ext2fs|ext3fs|cramfs) + initrd_img="${rootdir}/boot/initrd-${kernel}.img" + ;; + ramfs) + initrd_img="${rootdir}/boot/initrd-${kernel}.cpio" + ;; +esac + +echo "Creating $initrd_img ..." +mkdir -p $targetdir/etc/conf if [ "$empty" = 0 ] ; then - grep '^modprobe ' /etc/conf/kernel | grep -v 'no-initrd' | \ + grep '^modprobe ' ${rootdir}/etc/conf/kernel | grep -v 'no-initrd' | \ sed 's,[ ]#.*,,' | \ while read a b ; do $a $modprobeopt -v $b 2> /dev/null; done | while read a b c; do [[ "$b" = *.ko ]] && b=${b/.ko/}; - b="`find /lib/modules/$kernel -wholename "$b.o" -o -wholename "$b.ko"`" + b="`find ${rootdir}/lib/modules/$kernel -wholename "$b.o" -o -wholename "$b.ko"`" echo "Adding $b." - mkdir -p $tmpdir/${b%/*} - cp $b $tmpdir/$b - echo "/sbin/insmod $b $c" >> $tmpdir/etc/conf/kernel + mkdir -p $targetdir/${b%/*} + cp $b $targetdir/$b + echo "/sbin/insmod $b $c" >> $targetdir/etc/conf/kernel done fi -mkdir -p $tmpdir/dev $tmpdir/root $tmpdir/tmp $tmpdir/proc $tmpdir/sys -mknod $tmpdir/dev/ram0 b 1 0 -mknod $tmpdir/dev/null c 1 3 -mknod $tmpdir/dev/zero c 1 5 -mknod $tmpdir/dev/tty c 5 0 -mknod $tmpdir/dev/console c 5 1 + +mkdir -p $targetdir/{dev,root,tmp,proc,sys} +mknod $targetdir/dev/ram0 b 1 0 +mknod $targetdir/dev/null c 1 3 +mknod $targetdir/dev/zero c 1 5 +mknod $targetdir/dev/tty c 5 0 +mknod $targetdir/dev/console c 5 1 + # this copies a set of programs and the necessary libraries into a # chroot environment echo -n "Checking necessary fsck programs ... " while read dev a mnt b fs c ; do - [ -e "/sbin/fsck.${fs}" ] && echo "/sbin/fsck.${fs} /sbin/fsck.${fs}" + [ -e "${rootdir}/sbin/fsck.${fs}" ] && echo "/sbin/fsck.${fs} /sbin/fsck.${fs}" done < <( mount ) | sort | uniq >/etc/conf/initrd/initrd_fsck echo "/sbin/fsck /sbin/fsck" >>/etc/conf/initrd/initrd_fsck echo "done" -targetdir=$tmpdir -programs="/bin/bash /bin/bash2 /bin/sh /bin/ls /sbin/pivot_root /sbin/insmod /sbin/insmod.old /bin/mount /bin/umount /usr/bin/chroot /etc/fstab /bin/mkdir" +libdirs="${rootdir}/lib `sed -e"s,^\(.*\),${rootdir}\1," ${rootdir}/etc/ld.so.conf | tr '\n' ' '`" -libs="/lib/ld-linux.so.2" -for x in $programs ; do - [ -e $x ] || continue - mkdir -p $targetdir/${x%/*} - cp -a $x $targetdir/$x - file $x | grep -q ELF || continue - libs="$libs `ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '`" -done +needed_libs() { + local x="$1" library -for x in /etc/conf/initrd/initrd_* ; do + ${cross_compile}readelf -d $x 2>/dev/null | grep "(NEEDED)" | + sed -e"s,.*Shared library: \[\(.*\)\],\1," | + while read library ; do + find $libdirs -name "$library" 2>/dev/null | + sed -e "s,^$rootdir,,g" | tr '\n' ' ' + done +} + +echo -n "Copying other files ... " +for x in ${rootdir}/etc/conf/initrd/initrd_* ; do [ -f $x ] || continue while read file target ; do - if [ -d $file ] ; then - find $file -type f -o -type b -o -type c -o -type l | while read f ; do - tfile=${targetdir}/${target}/${f#$file} - [ -e $tfile ] && continue + file="${rootdir}/$file" + [ -e $file ] || continue + + for f in `find $file` ; do + tfile=${targetdir}/${target}${f#$file} + [ -e $tfile ] && continue + + if [ -d $f -a ! -L $f ] ; then + mkdir -p ${tfile} + continue + else mkdir -p ${tfile%/*} + fi + +# if [ -b $f -o -c $f -o -p $f -o -L $f ] ; then cp -a $f $tfile - file $x | grep -q ELF || continue - libs="$libs `ldd $f 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '`" - done - fi - [ -f $file ] || continue - mkdir -p $targetdir/${target%/*} - cp $file $targetdir/$target - file $file | grep -q ELF || continue - libs="$libs `ldd $file 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '`" +# else +# cp $f $tfile +# fi + + file -L $f | grep -q ELF || continue + libs="$libs `needed_libs $f`" + done done < $x done +echo "done" +echo -n "Copying required libraries ... " while [ -n "$libs" ] ; do oldlibs=$libs libs="" for x in $oldlibs ; do + [ -e $targetdir/$x ] && continue mkdir -p $targetdir/${x%/*} - cp $x $targetdir/$x - file $x | grep -q ELF || continue - for y in `ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '` ; do + cp $rootdir/$x $targetdir/$x + file -L $rootdir/$x | grep -q ELF || continue + for y in `needed_libs $rootdir/$x` ; do [ ! -e "$targetdir/$y" ] && libs="$libs $y" done done done +echo "done" + +echo "Creating links for identical files ..." +while read ck fn +do + # don't link empty files... + if [ "$oldck" = "$ck" -a -s "$fn" ] ; then + echo "\`- Found ${fn#$targetdir} -> ${oldfn#$targetdir}." + rm $fn ; ln -s /${oldfn#$targetdir} $fn + else + oldck=$ck ; oldfn=$fn + fi +done < <( find $targetdir -type f | xargs md5sum | sort ) # though this is not clean, it helps avoid a warning from fsck about # it being unable to determine wether a filesystem is mounted. ln -s /proc/mounts $targetdir/etc/mtab -itmp=`mktemp` -mkfs.cramfs $tmpdir ${itmp} -gzip -9 < ${itmp} > /boot/initrd-${kernel}.img -rm -f ${itmp} +echo "Creating initrd filesystem image ($initrdfs): " +case "$initrdfs" in +cramfs) + [ "$block_size" == "" ] && block_size=4096 + mkfs.cramfs -b $block_size $targetdir $initrd_img + ;; +ramfs) +# cp -a $targetdir/{linuxrc,init} + ( cd $targetdir ; find | cpio -o -c > $initrd_img ; ) + ;; +ext2fs|ext3fs) + [ "$block_size" == "" ] && block_size=1024 + block_count=$(( ( 1024 * $ramdisk_size ) / $block_size )) -rm -rf $tmpdir -echo "Done." + echo "Creating temporary files." + tmpdir=`mktemp -d` ; mkdir -p $tmpdir + dd if=/dev/zero of=$initrd_img bs=${block_size} count=$block_count &> /dev/null + tmpdev="`losetup -f 2>/dev/null`" + if [ -z "$tmpdev" ] ; then + for x in /dev/loop* /dev/loop/* ; do + [ -b "${x}" ] || continue + losetup ${x} 2>&1 >/dev/null || tmpdev="${x}" + [ -n "${tmpdev}" ] && break + done + if [ -z "${tmpdev}" ] ; then + echo "No free loopback device found!" + rm -f $tmpfile ; rmdir $tmpdir; exit 1 + fi + fi + echo "Using loopback device $tmpdev." + losetup "$tmpdev" $initrd_img + + echo "Writing initrd image file." + mkfs.${initrdfs:0:4} -b $block_size -m 0 -N 360 -q $tmpdev &> /dev/null + mount -t ${initrdfs:0:4} $tmpdev $tmpdir + rmdir $tmpdir/lost+found/ + cp -a $targetdir/* $tmpdir + umount $tmpdir + + echo "Removing temporary files." + losetup -d $tmpdev + rm -rf $tmpdir + ;; +esac +echo "Compressing initrd image file." +gzip -9 -c $initrd_img > $initrd_img.gz + +rm -rf $targetdir +echo "Done." diff --git a/package/base/rockinitrd/rockinitrd.conf b/package/base/rockinitrd/rockinitrd.conf index 826633eab..a3124674a 100644 --- a/package/base/rockinitrd/rockinitrd.conf +++ b/package/base/rockinitrd/rockinitrd.conf @@ -23,6 +23,7 @@ rockinitrd_main() { mkdir -p $root/etc/conf/initrd install -m 644 ${confdir}/initrd_base.txt $root/etc/conf/initrd/initrd_base + install -m 644 ${confdir}/initrd_essential.txt $root/etc/conf/initrd/initrd_essential install -m 755 ${confdir}/init $root/etc/conf/initrd/init install -m 755 ${confdir}/mkinitrd.sh $root/sbin/mkinitrd } diff --git a/package/base/rockinitrd/rockinitrd.desc b/package/base/rockinitrd/rockinitrd.desc index b10ab9f94..a452aa745 100644 --- a/package/base/rockinitrd/rockinitrd.desc +++ b/package/base/rockinitrd/rockinitrd.desc @@ -40,5 +40,5 @@ [L] GPL [S] Beta [V] 20050720 -[P] X -----5---9 100.199 +[P] X -X---5---9 100.199