7 # based on mkinitrd from RedHat Linux
10 GENINITRD_RCSID='$Revision$ $Date:: $'
11 R=${GENINITRD_RCSID#* *}; VERSION=${R%% *}
14 . /etc/rc.d/init.d/functions
15 . /lib/geninitrd/functions
16 . /etc/sysconfig/system
18 # list of geninitrd modules which need setup routine after commandline args parsing
30 # device node for rootfs from fstab
40 # is /tmp mounted on tmpfs
43 # are /dev nodes already created from /proc/devices info?
47 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
48 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
49 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
50 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
51 echo " [--with-bootsplash] [--without-bootsplash]"
52 echo " [--with-fbsplash] [--without-fbsplash]"
53 echo " [--with-fbcondecor] [--without-fbcondecor]"
54 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
55 echo " [--with-suspend] [--without-suspend]"
56 echo " [--with-tuxonice] [--without-tuxonice]"
57 echo " [--without-dmraid]"
58 echo " [--with-multipath=DEVPATH] [--without-multipath]"
59 echo " [--without-blkid] [--without-luks]"
60 echo " <initrd-image> <kernel-version>"
65 for kdir in /lib/modules/*; do
66 [ -d $kdir ] || continue
68 echo " $0 -f --initrdfs=rom /boot/initrd-$kver.gz $kver $verbose"
81 [ -n "$verbose" ] && msg "$*" >&2
84 # aborts program abnormally
91 # find program from specified paths
97 debug "find_tool: found $x"
101 debug "find_tool: did not found any of: $@"
105 # loads geninitrd modules
106 geninitrd_load_mods() {
109 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
110 die "$mod geninitrd module can't be loaded"
112 . /lib/geninitrd/mod-$mod.sh
114 GENINITRD_MODS="$GENINITRD_MODS $mod"
118 # setup geninitrd modules
119 geninitrd_setup_mods() {
122 for mod in $GENINITRD_MODS; do
123 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
124 debug "# $rcsid (mod-$mod)"
126 # some mods want init
127 if type setup_mod_$mod > /dev/null; then
133 # append text to /linuxrc
134 # takes STDIN as input
139 # generate code to mount /dev on tmpfs and create initial nodes
140 # can be called multiple times. /dev is cleaned up (umounted) automatically at
143 if [ "$INITRDFS" = "initramfs" ]; then
144 # initramfs is read-write filesystem, no need for tmpfs
148 # we already generated tmpfs code; return
149 if is_yes "$dev_mounted"; then
155 busybox_applet mount mknod mkdir
158 mount -o mode=0755 -t tmpfs none /dev
159 mknod /dev/console c 5 1
160 mknod /dev/null c 1 3
161 mknod /dev/zero c 1 5
162 mknod /dev/random c 1 8
163 mknod /dev/snapshot c 10 231
164 mknod /dev/urandom c 1 9
170 # generate code to mount /proc on initrd
171 # can be called multiple times
173 if is_yes "$proc_mounted"; then
178 if [ "$INITRDFS" = "initramfs" ]; then
179 # /proc is mounted with initramfs 2.6.22.14 kernel
180 # XXX: remove when it is clear why proc was already mounted
181 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
183 echo "mount -t proc none /proc" | add_linuxrc
187 # generate code to mount /sys on initrd
188 # can be called multiple times
190 if is_yes "$sys_mounted"; then
195 echo "mount -t sysfs none /sys" | add_linuxrc
198 # generate code to mount /tmp on initrd
199 # can be called multiple times
201 if [ "$INITRDFS" = "initramfs" ]; then
202 # initramfs is read-write filesystem, no need for tmpfs
206 if is_yes "$tmp_mounted"; then
211 echo "mount -t tmpfs none /tmp" | add_linuxrc
214 # unmount all mountpoints mounted by geninitrd
218 : Last shell before umounting all and giving control over to real init.
222 if is_yes "$dev_mounted"; then
223 echo 'umount /dev' | add_linuxrc
226 if is_yes "$sys_mounted"; then
227 echo 'umount /sys' | add_linuxrc
230 if is_yes "$tmp_mounted"; then
231 echo 'umount /tmp' | add_linuxrc
234 if is_yes "$proc_mounted"; then
235 echo 'umount /proc' | add_linuxrc
241 # Checks if busybox has support for APPLET(s)
242 # Exits from geninitrd if the support is not present.
244 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
248 if [ -z "$busybox_functions" ]; then
249 local tmp=$($busybox 2>&1)
251 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
252 if [[ "$tmp" = *applet\ not\ found* ]]; then
254 ln -s $busybox $t/busybox
255 local tmp=$($t/busybox 2>&1)
259 busybox_functions=$(echo "$tmp" | \
260 sed -ne '/Currently defined functions:/,$p' | \
261 xargs | sed -e 's,.*Currently defined functions: ,,'
267 eval have='$'busybox_have_$applet
268 if [ -z "$have" ]; then
269 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
270 if [ "$have" = 0 ]; then
271 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
274 eval busybox_have_$applet=$have
277 if [ $err = 1 ]; then
282 # Extract the .config file from a kernel image
283 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
285 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
286 if [ -n "$kofile" ]; then
287 /lib/geninitrd/extract-ikconfig $kofile
291 # see if config available as separate file
292 if [ -f /boot/config-$kernel ]; then
293 cat /boot/config-$kernel
297 # finally try vmlinuz itself
298 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
301 # Finds module dependencies
305 # Outputs full path to module and it's dependencies
310 # if module is prefixed with dash, we should ignore errors if the module
312 if [ ${module#-} != $module ]; then
317 # This works when user has module-init-tools installed even on 2.4 kernels
319 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
322 if [ $skiperrors = 1 ]; then
327 if ! is_no "$EXIT_IF_MISSING"; then
328 die "$module: module not found for $kernel kernel"
331 warn "$module: module not found for $kernel kernel"
332 warn "If $module isn't compiled in kernel then this initrd may not start your system."
336 while read insmod modpath options; do
337 [ "$insmod" = "insmod" ] && echo $modpath
345 # no firmware support in 2.4 kernels
346 if [ "$kernel_version_long" -lt "002005048" ]; then
349 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
354 local mod depmod module=$1
356 depmod=$(find_depmod $module) || exit 1
357 for mod in $depmod; do
358 mod=${mod#/lib/modules/$kernel/}
360 # add each module only once
362 for m in $MODULES; do
363 [ $m = $mod ] && have=1
365 if [ $have = 0 ]; then
366 MODULES="$MODULES $mod"
371 # install a file to temporary mount image.
372 # it will operate recursively (copying directories)
373 # and will symlink destinations if source is symlink.
375 if [ $# -lt 2 ]; then
376 die 'Usage: inst <file> [<file>] <destination>'
379 local src i=0 c=$(($# - 1))
380 while [ $i -lt $c ]; do
387 local parentDir=$(dirname $DESTDIR$dest)
388 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
389 debug "+ cp $* $DESTDIR$dest"
390 cp -HR "$@" "$DESTDIR$dest"
395 die 'Usage: inst_d <destination> <destination>'
398 install -d "$DESTDIR$dir"
402 # install executable and it's shared libraries
404 if [ $# -lt 2 ]; then
405 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
407 local src i=0 c=$(($# - 1))
408 while [ $i -lt $c ]; do
418 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
420 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
422 inst_exec $lib /$_lib
426 # hack for uclibc linked binaries requiring this fixed path
427 # XXX: shouldn't rpath be used here instead so th
428 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
429 local lib=$DESTDIR/$_lib/libc.so.0
430 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
431 local libdir=$(cd $(dirname "$lib"); pwd)
432 if [ ! -e $DESTDIR$libdir ]; then
433 libdir=$(dirname "$libdir")
435 debug "+ ln -s /$_lib $DESTDIR$libdir"
436 ln -s /$_lib $DESTDIR$libdir
441 # output modules.conf / modprobe.conf
443 echo "$modprobe_conf_cache"
447 # defaults to modprobe -c if not told otherwise, this means include statements
449 cache_modprobe_conf() {
450 if [ "$kernel_version" -lt "002005" ]; then
451 modulefile=/etc/modules.conf
452 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
453 modulefile=/etc/conf.modules
457 if [ -n "$modulefile" ]; then
458 debug "Using $modulefile for modules config"
459 modprobe_conf_cache=$(cat $modulefile)
461 debug "Using modprobe -c to get modules config"
462 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
466 # find modules for $devpath
467 find_modules_for_devpath() {
469 if [ -z "$devpath" ]; then
470 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
473 if [[ "$devpath" = /dev/dm-* ]]; then
474 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
475 devpath=$(dm_node "$devpath")
478 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
479 # sanitize things like:
480 # /dev/block/104:2 -> /dev/cciss/c0d0p2
481 devpath=$(readlink -f "$devpath")
484 debug "Finding modules for device path $devpath"
486 if is_luks "$devpath"; then
487 find_modules_luks "$devpath"
491 if is_nfs "$devpath"; then
492 find_modules_nfs "$devpath"
496 if is_md "$devpath"; then
497 find_modules_md "$devpath"
501 if is_multipath "$devpath"; then
502 if find_modules_multipath "$devpath"; then
509 if is_dmraid "$devpath"; then
510 if find_modules_dmraid "$devpath"; then
516 if is_scsi "$devpath"; then
517 find_modules_scsi "$devpath"
521 if is_ide "$devpath"; then
522 find_modules_ide "$devpath"
526 if [[ "$devpath" == /dev/rd/* ]]; then
532 if [[ "$devpath" == /dev/ida/* ]]; then
533 find_module "cpqarray"
534 rootdev_add=/dev/ida/
538 if [[ "$devpath" == /dev/cciss/* ]]; then
540 rootdev_add=/dev/cciss/
544 if [[ "$devpath" == /dev/ataraid/* ]]; then
546 find_module "ataraid"
547 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
548 if [ -n "$ataraidmodules" ]; then
549 # FIXME: think about modules compiled in kernel
550 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
552 for n in $ataraidmodules; do
555 rootdev_add=/dev/ataraid/
559 # check to see if we need to set up a loopback filesystem
560 if [[ "$devpath" == /dev/loop* ]]; then
561 die "Sorry, root on loop device isn't supported."
562 # TODO: rewrite for bsp and make nfs ready
563 if [ ! -x /sbin/losetup ]; then
564 die "losetup is missing"
566 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
567 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
568 die "The root filesystem is on a $devpath, but there is no magic entry in $fstab for this device. Consult the $PROGRAM man page for more information"
571 line="`awk '/'$key'/ { print $0; }' $fstab`"
572 loopDev="$(echo $line | awk '{print $3}')"
573 loopFs="$(echo $line | awk '{print $4}')"
574 loopFile="$(echo $line | awk '{print $5}')"
576 BASICMODULES="$BASICMODULES -loop"
577 find_module "-$loopFs"
578 BASICMODULES="$BASICMODULES -${loopFs}"
582 if is_lvm "$devpath"; then
583 find_modules_lvm "$devpath"
588 firmware_install_module() {
590 local firmware_files="$2"
592 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
593 # firmware not yet installed
594 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
596 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
598 echo 1 > /sys$DEVPATH/loading
599 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
600 echo 0 > /sys$DEVPATH/loading
603 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
606 for firmware in $firmware_files; do
607 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
608 FIRMWAREDIR=${firmware%/*}
609 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
610 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
611 elif [ -f "/lib/firmware/$firmware" ]; then
612 FIRMWAREDIR=${firmware%/*}
613 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
614 inst /lib/firmware/$firmware /lib/firmware/$firmware
616 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
621 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
628 for mod in $modules; do
630 inst_d "/lib/modules/$kernel/$MODULEDIR"
631 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
632 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
636 modules_add_linuxrc() {
640 # module path without optional compression
644 local module=${modpath##*/}; module=${module%$modext}
645 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
646 local genericname=$(echo $module | tr - _)
647 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
648 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
650 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
651 options="scan=sync $options"
654 if [ -n "$verbose" ]; then
656 if [ "$options" ]; then
657 s="$s with options [$options]"
659 if [ "$usleep" ]; then
660 s="$s and $usleep usleep"
662 debug "Loading module [$module]$s"
665 if [ -n "$firmware" ]; then
666 firmware_install_module "$module" "$firmware"
668 for file in $(find_firmware "$module"); do
669 firmware_install_module "$module" "$file"
673 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
674 if [ -n "$usleep" ]; then
675 echo "usleep $usleep" | add_linuxrc
677 if [ "$module" = "scsi_wait_scan" ]; then
678 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
679 echo "rmmod scsi_wait_scan" | add_linuxrc
686 # Generates /dev nodes based on /proc/partitions information.
687 # Needs /proc mounted.
688 # Can be called multiple times.
689 initrd_gen_devices() {
690 if is_yes "$proc_partitions"; then
697 : 'Making device nodes'
698 cat /proc/partitions | (
699 # ignore first two lines: header, empty line
702 while read major minor blocks dev rest; do
705 [ -e $node ] || mknod $node b $major $minor
712 initrd_gen_setrootdev() {
713 debug "Adding rootfs finding based on kernel cmdline root= option support."
716 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
717 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
719 if [ -z "$rootnr" ]; then
720 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
722 if [ -n "$rootnr" ]; then
723 echo "$rootnr" > /proc/sys/kernel/real-root-dev
729 initrd_gen_initramfs_switchroot() {
731 if [ "$rootdev" = "/dev/nfs" ]; then
732 echo "rootfs on NFS root=/dev/nfs"
734 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
737 # parse 'root=xxx' kernel commandline
738 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
740 device=/dev/no_partition_found
741 eval "$(busybox awk -v c="$ROOT" '
743 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
744 num_pattern = "[0-9a-f]" num_pattern_short;
745 dev_pattern = "[hms][a-z][a-z]([0-9])+";
746 partition = "no_partition_found";
750 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
751 if (c ~ "^" num_pattern "$") {
752 maj = sprintf("%s",substr(c,1,2));
753 min = sprintf("%s",substr(c,3));
755 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
756 if (c ~ "^" dev_pattern "$") partition = c;
759 $4 ~ partition { maj = $1; min = $2; }
760 $1 ~ maj && $2 ~ min { partition = $4; }
763 if (maj >= 0 && min >= 0) {
764 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
768 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
769 mknod $device b $maj $min
779 if [ "$device" = '/dev/no_partition_found' ]; then
783 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
785 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
786 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
787 if [ -z "$init" -o ! -x "/newroot$init" ]; then
793 busybox_applet switch_root
795 exec switch_root /newroot $init ${1:+"$@"}
797 echo "Error! initramfs should not reach this place."
798 echo "It probably means you've got old version of busybox, with broken"
799 echo "initramfs support. Trying to boot anyway, but won't promise anything."
801 exec chroot /newroot $init ${1:+"$@"}
803 echo "Failed to chroot!"
806 # we need /init being real file, not symlink, otherwise the initramfs will
807 # not be ran by pid 1 which is required for switch_root
808 mv $DESTDIR/linuxrc $DESTDIR/init
809 ln -s init $DESTDIR/linuxrc
812 # find if $symbol exists in System.map $mapfile
816 if [ ! -f $mapfile ]; then
817 # missing mapfile (not a pld kernel?)
821 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
824 # find best compressor (or forced one) for initrd
827 # fastest initrd decompression speed is first
828 local compressors='lzo gzip xz lzma bzip2'
830 # a specified one, take it
831 if ! is_yes "$mode"; then
835 debug "finding compressor: $compressors (via $mode)"
836 # check for compressor validity
837 local c prog map=/boot/System.map-$kernel
838 for c in $compressors; do
861 # any existing sym will work
866 die "Unknown compressor $c"
869 if sym_exists $map $sym && [ -x $prog ]; then
875 debug "using gzip for compressor (fallback)"
879 # compresses kernel image image
880 # in function so we could retry with other compressor on failure
882 local compressor="$1" IMAGE="$2" target="$3" tmp
883 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
885 case "$compressor" in
887 # don't use -9 here since kernel won't understand it
888 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
891 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
894 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
897 gzip -9 < "$IMAGE" > "$tmp" || return $?
900 lzop -9 < "$IMAGE" > "$tmp" || return $?
903 cat < "$IMAGE" > "$tmp" || return $?
907 mv -f "$tmp" "$target"
910 if [ -r /etc/sysconfig/geninitrd ]; then
911 . /etc/sysconfig/geninitrd
914 if [ ! -f /proc/mounts ]; then
915 warn "/proc filesystem not mounted, may cause wrong results or failure."
918 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
920 while [ $# -gt 0 ]; do
930 modulefile=${1#--modules-conf=}
939 --without-bootsplash)
951 --without-fbcondecor)
960 --with-suspend2 | --with-tuxonice)
963 --without-suspend2 | --without-tuxonice)
967 LVMTOOLSVERSION=${1#--lvmversion=}
970 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
972 --lvmtoolsversion|--lvmversion)
989 USE_MULTIPATH=${1#--with-multipath=}
998 BASICMODULES="$BASICMODULES ${1#--with=}"
1001 BASICMODULES="$BASICMODULES $2"
1005 echo "$PROGRAM: version $VERSION"
1015 COMPRESS="${1#--compress=}"
1027 PREMODS="$PREMODS ${1#--preload=}"
1030 PREMODS="$PREMODS $2"
1034 die "--fs option is obsoleted. Use --initrdfs instead"
1037 INITRDFS=${1#--initrdfs=}
1050 if [ -z "$target" ]; then
1052 elif [ -z "$kernel" ]; then
1064 if [ -z "$target" -o -z "$kernel" ]; then
1070 if [ "$(id -u)" != 0 ]; then
1071 die "You need to be root to generate initrd"
1074 if [ -d /lib64 -a -d /usr/lib64 ]; then
1080 initrd_dir=/usr/$_lib/initrd
1081 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1082 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1084 debug "# $GENINITRD_RCSID (geninitrd)"
1085 debug "Using _lib: $_lib"
1086 debug "Using initrd_dir: $initrd_dir"
1088 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1090 # we setup mods after parsing command line args
1091 geninitrd_setup_mods
1093 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1094 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1097 if [ -z "$INITRDFS" ]; then
1098 if [ -n "$FS" ]; then
1099 # FS= can came only via /etc/sysconfig/geninitrd likely?
1100 die "FS configuration option is obsoleted. Use INITRDFS instead"
1104 if [ "$kernel_version" -ge "002005" ]; then
1105 INITRDFS="initramfs"
1113 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1116 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1119 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1122 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1123 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1126 die "Filesystem $INITRDFS on initrd is not supported"
1130 if [ -L "$target" ]; then
1131 target=$(readlink -f "$target")
1134 if [ -n "$img_vers" ]; then
1135 target="$target-$kernel"
1138 if [ -z "$force" -a -f "$target" ]; then
1139 die "$target already exists."
1142 if [ ! -d "/lib/modules/$kernel" ]; then
1143 die "/lib/modules/$kernel is not a directory."
1146 if [ "$kernel_version" -ge "002005" ]; then
1152 for n in $PREMODS; do
1156 if [ "$FBMODULE" ]; then
1157 find_module "$FBMODULE"
1160 # autodetect USB keyboards
1163 # allow forcing loading SCSI and/or IDE modules
1164 # XXX: where ADDSCSI cames from? drop?
1165 if is_yes "$ADDSCSI"; then
1169 # autodetect SATA modules
1172 # XXX: where ADDIDE cames from? drop?
1173 if is_yes "$ADDIDE"; then
1177 if is_yes "$USE_SUSPEND"; then
1178 find_modules_suspend
1181 find_root "$fstab" || exit
1182 debug "Using $rootdev as device for rootfs"
1184 find_modules_for_devpath "$rootdev"
1186 # if USE_MULTIPATH is path to device, scan that too
1187 # this is to bootstrap multipath setup into initrd.
1188 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1189 find_modules_multipath $USE_MULTIPATH
1192 find_module "-$rootFs"
1194 for n in $BASICMODULES; do
1198 if is_yes "$USE_TUXONICE"; then
1202 find_modules_fbsplash
1204 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1205 debug "No modules are needed -- not building initrd image."
1209 debug "Building initrd..."
1210 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1211 RCFILE="$DESTDIR/linuxrc"
1213 chmod a+rx "$RCFILE"
1214 ln -s linuxrc $DESTDIR/init
1216 # create dirs that we really need
1217 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1219 modules_install "$MODULES"
1221 # mknod'ing the devices instead of copying them works both with and
1223 mknod "$DESTDIR/dev/console" c 5 1
1224 mknod "$DESTDIR/dev/null" c 1 3
1225 mknod "$DESTDIR/dev/zero" c 1 5
1226 mknod "$DESTDIR/dev/random" c 1 8
1227 mknod "$DESTDIR/dev/urandom" c 1 9
1229 inst_exec $busybox /bin/busybox
1230 ln -s busybox $DESTDIR/bin/sh
1231 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1232 ln -s busybox $DESTDIR/bin/initrd-busybox
1236 # initrd generated by:
1241 add_linuxrc <<-'EOF'
1242 read CMDLINE < /proc/cmdline; export CMDLINE
1244 for arg in $CMDLINE; do
1245 if [ "${arg}" = "debuginitrd" ]; then
1248 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1249 DEBUGINITRD=${arg##debuginitrd=}
1251 if [ "${arg##root=}" != "${arg}" ]; then
1254 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1255 ROOTFSFLAGS=${arg##rootfsflags=}
1259 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1260 if [ "$DEBUGINITRD" = "sh" ]; then
1263 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1264 add_linuxrc <<-'EOF'
1265 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1268 add_linuxrc <<-'EOF'
1272 add_linuxrc <<-'EOF'
1280 if [ "$DEBUGINITRD" ]; then
1285 modules_add_linuxrc $MODULES
1287 # TODO: rewrite for busybox
1288 #if [ -n "$loopDev" ]; then
1289 # if [ ! -d /initrd ]; then
1293 # cp -a "$loopDev" "$DESTDIR/dev"
1294 # cp -a "$rootdev" "$DESTDIR/dev"
1295 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1296 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1297 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1298 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1301 if is_yes "$USE_UDEV"; then
1305 find_modules_uvesafb
1310 initrd_gen_multipath
1313 if is_yes "$have_nfs"; then
1319 initrd_gen_setrootdev
1325 # additional devs always needed
1326 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1328 initrd_gen_stop_udevd
1329 initrd_gen_stop_uvesafb
1331 if [ "$INITRDFS" = "initramfs" ]; then
1332 initrd_gen_initramfs_switchroot
1338 initrd_gen_fbcondecor
1340 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1342 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1343 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1345 debug "Creating $INITRDFS image $IMAGE"
1348 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1349 # NOTE: ext2 label is max 16 chars
1350 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1351 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1353 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1354 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1355 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1356 # We don't need this directory, so let's save space
1357 rm -rf "$tmpmnt"/lost+found
1359 debug "Copy recursively $DESTDIR -> $tmpmnt"
1360 cp -a $DESTDIR/* $tmpmnt
1366 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1369 mkcramfs "$DESTDIR" "$IMAGE"
1372 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1375 die "Filesystem $INITRDFS not supported by $PROGRAM"
1378 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1379 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1380 CONFIG_BLK_DEV_RAM_SIZE=4096
1383 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1384 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1387 if ! is_no "$COMPRESS"; then
1388 compressor=$(find_compressor "$COMPRESS")
1389 debug "Compressing $target with $compressor"
1391 # TODO: the image name (specified from kernel.spec) already contains
1392 # extension, which is .gz most of the time.
1393 compress_image "$compressor" "$IMAGE" "$target" || {
1394 if [ $compressor != gzip ]; then
1395 warn "Could not compress with $compressor, retrying with gzip"
1396 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1398 die "Could not compress image with $compressor"
1402 cp -a "$IMAGE" "$target"
1405 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1406 initrd_gen_bootsplash "$target"
1408 rm -rf "$DESTDIR" "$IMAGE"
1410 # vim:ts=4:sw=4:noet:fdm=marker