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
|