5 # by Jacek Konieczny <jajcus@pld.org.pl>
7 # based on mkinitrd from RedHat
9 RCSID='$Id: geninitrd,v 2.16 2002/02/20 11:30:17 wiget Exp $'
13 VERSION="`echo "$RCSID"|awk '{print $3}'`"
15 . /etc/rc.d/init.d/functions
18 # INITRDFS is set later (catch obsoleted FS option)
21 # it should be safe to remove scsi_mod from here, but I'm not sure...
22 PRESCSIMODS="-scsi_mod unknown -sd_mod"
23 PREIDEMODS="-ide-probe -ide-probe-mod -ide-disk"
30 modulefile=/etc/modules.conf
35 echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
36 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2
37 echo " [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]" 1>&2
38 echo " <initrd-image> <kernel-version>" 1>&2
39 echo " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
45 echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
49 typeset mods module f level depfile first
51 depfile=/lib/modules/$kernel/modules.dep
53 if test -f $depfile ; then
56 echo "Error: no $depfile ! Run depmod and rerun geninitrd." 1>&2
60 # prepend / if no path given, append .o if not given,
62 module=$(echo "$2" | \
63 awk '/\// {print;next} {print "/" $0}' | \
64 awk '/\.o$/ {print;next} {print $0 ".o"}' |
65 awk '{gsub("/","\\/");print}')
68 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
70 /(.*)/ { gsub(/\\/," "); if (here) print }
73 if [ "$mods" = "" ] ; then
74 if [ "$1" != silent ] ; then
75 echo "$module: module not found in $depfile" 1>&2
77 if ! is_no "$EXIT_IF_MISSING" ; then
80 echo "If $module isn't compiled in kernel then this initrd may not start your system". 1>&2
85 if [ "$level" = "" ] ; then
88 level=$(awk "BEGIN{print $level + 1}")
89 if [ $level -gt 20 ] ; then
90 echo "$module: cycle in $depfile" 1>&2
96 if [ "$first" = "" ] ; then
99 find_depmod $1 $f $level
110 if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
111 if [ -n "$skiperrors" ]; then
115 echo "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)" 1>&2
119 # only need to add each module once
121 tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
122 if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
123 MODULES="$MODULES $fmPath"
131 if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
133 modName="$(echo $modName | awk '{print(substr($0,2));}')"
137 if [ "$modName" = "pluto" ]; then
141 if [ "$modName" = "fcal" ]; then
146 if [ -n "$skiperrors" ]; then
147 allModulesToFind=`find_depmod silent $modName`
149 allModulesToFind=`find_depmod normal $modName`
150 if [ $? != 0 ] ; then
155 for mod in $allModulesToFind ; do
157 awk '{sub(/^\/lib\/modules\/[^\/]*\//,"");print}')
158 addmodule $mod "$skiperrors"
163 if [ "$#" != "2" ];then
164 echo "usage: inst <file> <destination>"
167 [ -n "$verbose" ] && echo "$1 -> $2"
172 /sbin/e2label $1 2> /dev/null
176 /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
180 /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
185 /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
189 eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
194 if [ ! -x /sbin/e2label ] ; then
195 echo "/sbin/e2label is missing" 1>&2
198 get_label="get_label_ext2"
201 if [ ! -x /usr/sbin/xfs_db ] ; then
202 echo "/usr/sbin/xfs_db is missing" 1>&2
205 get_label="get_label_xfs"
208 echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
212 if [ ! -r /proc/partitions ] ; then
213 echo '/proc/partitions is not readable'; 1>&2
216 label=${rootdev#"LABEL="}
217 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
218 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
219 if [ -n "$verbose" ] ; then
220 echo "Using $dev as device for rootfs"
227 if [ "$rootdev_found" != 1 ] ; then
228 echo "geninitrd can't find real device for LABEL=$label" 1>&2
235 if [ ! -x /sbin/tune2fs ] ; then
236 echo "/sbin/tune2fs is missing" 1>&2
239 get_uuid="get_uuid_ext2"
242 if [ ! -x /usr/sbin/xfs_db ] ; then
243 echo "/usr/sbin/xfs_db is missing" 1>&2
246 get_label="get_uuid_xfs"
249 echo "UUID on $rootFs in not supported by geninitrd" 1>&2
253 if [ ! -r /proc/partitions ] ; then
254 echo '/proc/partitions is not readable'; 1>&2
257 uuid=${rootdev#"UUID="}
258 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
259 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
260 if [ -n "$verbose" ] ; then
261 echo "Using $dev as device for rootfs"
268 if [ "$rootdev_found" != 1 ] ; then
269 echo "geninitrd can't find real device for UUID=$uuid" 1>&2
277 if [ -r /etc/sysconfig/geninitrd ] ; then
278 . /etc/sysconfig/geninitrd
281 if [ "x" = "x$INITRDFS" ] ; then
282 if [ "x" = "x$FS" ] ; then
286 echo "Warning: FS configuration options is obsoleted. Use INITRDFS instead" 1>&2
291 if [ ! -x /sbin/bsp ] ; then
292 echo "/sbin/bsp is missing !"
295 if [ "`uname -m`" = "ia64" ]; then
300 while [ $# -gt 0 ]; do
303 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
304 fstab="`echo $1 | awk -F= '{print $2;}'`"
311 modulefile="`echo $1 | awk -F= '{print $2;}'`"
318 raidtab="`echo $1 | awk -F= '{print $2;}'`"
325 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
326 modname="`echo $1 | awk -F= '{print $2;}'`"
332 BASICMODULES="$BASICMODULES $modname"
335 echo "geninitrd: version $VERSION"
351 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
352 modname="`echo $1 | awk -F= '{print $2;}'`"
357 PREMODS="$PREMODS $modname"
360 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
361 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
364 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
367 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
382 if [ -z "$target" ]; then
384 elif [ -z "$kernel" ]; then
395 if [ -z "$target" -o -z "$kernel" ]; then
401 if [ ! -x /sbin/mke2fs ]; then
402 echo "/sbin/mke2fs is missing" 1>&2
407 if [ ! -x /sbin/genromfs ]; then
408 echo "/sbin/genromfs is missing" 1>&2
413 if [ ! -x /sbin/mkcramfs ]; then
414 echo "/sbin/mkcramfs is missing" 1>&2
419 echo "Filesystem $INITRDFS on initrd is not supported" 1>&2
424 if [ -n "$img_vers" ]; then
425 target="$target-$kernel"
428 if [ -z "$force" -a -f "$target" ]; then
429 echo "$target already exists." 1>&2
433 if [ ! -d "/lib/modules/$kernel" ]; then
434 echo "/lib/modules/$kernel is not a directory." 1>&2
438 for n in $PREMODS; do
444 if is_yes "`echo "$rootdev" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
445 eval `awk -v rootdev=$rootdev 'BEGIN {
461 if (found == "yes") {
466 if (found == "yes") {
467 if ($1 == "device") {
468 if ($2 ~ /\/dev\/(sd|scsi)/) {
471 if ($2 ~ /\/dev\/(hd|ide)/) {
475 if ($1 == "raid-level") {
482 print "raidfound=" found "\nADDSCSI=" addscsi "\nADDIDE=" addide "\nraidlevel=" raidlevel "\n";
484 if is_yes "$raidfound" ; then
487 findmodule "raid$raidlevel"
493 echo "raid level $number (in $raidtab) not recognized" 1>&2
502 if is_yes "$ADDSCSI" || is_yes "$(echo "$rootdev" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
504 for n in $PRESCSIMODS; do
505 if [ "X$n" = "Xunknown" ] ; then
506 if [ ! -f "$modulefile" ]; then
507 modulefile=/etc/conf.modules
509 if [ -f "$modulefile" ]; then
510 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
511 for n in $scsimodules; do
512 # for now allow scsi modules to come from anywhere. There are some
513 # RAID controllers with drivers in block
524 if is_yes "$ADDIDE" || is_yes "`echo "$rootdev" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }'`" ; then
525 for n in $PREIDEMODS; do
530 if is_yes "`echo "$rootdev" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
534 if is_yes "`echo "$rootdev" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
535 findmodule "cpqarray"
538 if is_yes "`echo "$rootdev" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
542 # check to see if we need to set up a loopback filesystem
543 if is_yes "`echo "$rootdev" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
544 echo "Sorry, root on loop device isn't supported." 1>&2
546 # TODO: rewrite for bsp and make nfs ready
547 if [ ! -x /sbin/losetup ]; then
548 echo "losetup is missing"
551 key="^# $(echo $rootdev | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
552 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
553 echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
554 echo "for this device. Consult the geninitrd man page for more information" 1>&2
558 line="`awk '/'$key'/ { print $0; }' $fstab`"
559 loopDev="$(echo $line | awk '{print $3}')"
560 loopFs="$(echo $line | awk '{print $4}')"
561 loopFile="$(echo $line | awk '{print $5}')"
563 BASICMODULES="$BASICMODULES -loop"
564 findmodule "-$loopFs"
565 BASICMODULES="$BASICMODULES -${loopFs}"
566 # don't have any clue, how is this supposed to work
567 else # Check for other filesystems
568 findmodule "-$rootFs"
571 for n in $BASICMODULES; do
575 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
576 if [ -n "$verbose" ]; then
577 echo "No modules are needed -- not building initrd image."
582 if [ -n "$verbose" ]; then
583 echo "Using modules: $MODULES"
586 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
587 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
588 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
589 RCFILE="$MNTIMAGE/linuxrc"
591 if [ -f "$MNTIMAGE" ]; then
592 echo "$MNTIMAGE already exists. Remove it and try again" 1>&2
596 if [ -f "$IMAGE" ]; then
597 echo "$IMAGE already exists. Remove it and try again" 1>&2
601 if [ "$INITRDFS" = "ext2" ] ; then
602 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
604 # We have to "echo y |" so that it doesn't complain about $IMAGE not
605 # being a block device
606 echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
609 mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
615 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
618 # We don't need this directory, so let's save space
619 rm -rf "$MNTPOINT"/lost+found
621 for MODULE in $MODULES; do
622 MODULEDIR="`my_dirname "$MODULE"`"
623 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
624 cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
627 # mknod'ing the devices instead of copying them works both with and
629 mknod "$MNTIMAGE/dev/console" c 5 1
631 s="$MNTIMAGE/etc/startup"
632 inst /sbin/bsp "$RCFILE"
633 echo "# autogenerated startup" > "$s"
636 for MODULE in $MODULES; do
637 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
638 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
640 if [ -n "$verbose" ]; then
641 /bin/echo -n "Loading module $module "
642 if [ -n "$options" ] ; then
643 echo "with options $options."
645 echo "without options."
648 echo "insmod /lib/modules/$kernel/$MODULE $options" >> "$s"
651 # TODO: rewrite for bsp
652 #if [ -n "$loopDev" ]; then
653 # if [ ! -d /initrd ]; then
657 # cp -a "$loopDev" "$MNTIMAGE/dev"
658 # cp -a "$rootdev" "$MNTIMAGE/dev"
659 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
660 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
661 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
662 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
665 if is_yes "$USERAIDSTART" ; then
666 if [ -x /sbin/raidstart.static ] ; then
667 [ -n "$verbose" ] && echo "Add raidstart to initrd"
668 mkdir -p "$MNTIMAGE/etc" || true
669 inst /sbin/raidstart.static "$MNTIMAGE/bin/raidstart"
670 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
671 echo "echo \"Starting RAID\"" >> "$RCFILE"
672 echo "/bin/raidstart $rootdev" >> "$RCFILE"
674 echo "/sbin/raidstart.static is missing" 1>&2
681 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
688 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
691 mkcramfs "$MNTPOINT" "$IMAGE"
694 echo "Filesystem $INITRDFS not supported by $0";
697 if is_yes "$COMPRESS" ; then
698 gzip -9 < "$IMAGE" > "$target"
700 cp -a "$IMAGE" "$target"
702 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"