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
31 # device node for rootfs from fstab
41 # is /tmp mounted on tmpfs
44 # are /dev nodes already created from /proc/devices info?
48 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
49 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
50 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
51 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
52 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
53 echo " [--with-bootsplash] [--without-bootsplash]"
54 echo " [--with-fbsplash] [--without-fbsplash]"
55 echo " [--with-fbcondecor] [--without-fbcondecor]"
56 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
57 echo " [--with-suspend] [--without-suspend]"
58 echo " [--with-tuxonice] [--without-tuxonice]"
59 echo " [--without-dmraid]"
60 echo " [--with-multipath=DEVPATH] [--without-multipath]"
61 echo " [--without-blkid] [--without-luks]"
62 echo " <initrd-image> <kernel-version>"
66 local kdir kver dir=${target:-/boot}
67 for kdir in /lib/modules/*; do
68 [ -d $kdir ] || continue
70 echo " $0 -f --initrdfs=rom $dir/initrd-$kver.gz $kver $verbose"
83 [ -n "$verbose" ] && msg "$*" >&2
86 # aborts program abnormally
93 # find program from specified paths
99 debug "find_tool: found $x"
103 debug "find_tool: did not found any of: $@"
107 # loads geninitrd modules
108 geninitrd_load_mods() {
111 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
112 die "$mod geninitrd module can't be loaded"
114 . /lib/geninitrd/mod-$mod.sh
116 GENINITRD_MODS="$GENINITRD_MODS $mod"
120 # setup geninitrd modules
121 geninitrd_setup_mods() {
124 for mod in $GENINITRD_MODS; do
125 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
126 debug "# $rcsid (mod-$mod)"
128 # some mods want init
129 if type setup_mod_$mod > /dev/null; then
135 # append text to /linuxrc
136 # takes STDIN as input
141 # generate code to mount /dev on tmpfs and create initial nodes
142 # can be called multiple times. /dev is cleaned up (umounted) automatically at
145 if [ "$INITRDFS" = "initramfs" ]; then
146 # initramfs is read-write filesystem, no need for tmpfs
150 # we already generated tmpfs code; return
151 if is_yes "$dev_mounted"; then
157 busybox_applet mount mknod mkdir
160 mount -o mode=0755 -t tmpfs none /dev
161 mknod /dev/console c 5 1
162 mknod /dev/null c 1 3
163 mknod /dev/zero c 1 5
164 mknod /dev/random c 1 8
165 mknod /dev/snapshot c 10 231
166 mknod /dev/urandom c 1 9
172 # generate code to mount /proc on initrd
173 # can be called multiple times
175 if is_yes "$proc_mounted"; then
180 if [ "$INITRDFS" = "initramfs" ]; then
181 # /proc is mounted with initramfs 2.6.22.14 kernel
182 # XXX: remove when it is clear why proc was already mounted
183 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
185 echo "mount -t proc none /proc" | add_linuxrc
189 # generate code to mount /sys on initrd
190 # can be called multiple times
192 if is_yes "$sys_mounted"; then
197 echo "mount -t sysfs none /sys" | add_linuxrc
200 # generate code to mount /tmp on initrd
201 # can be called multiple times
203 if [ "$INITRDFS" = "initramfs" ]; then
204 # initramfs is read-write filesystem, no need for tmpfs
208 if is_yes "$tmp_mounted"; then
213 echo "mount -t tmpfs none /tmp" | add_linuxrc
216 # unmount all mountpoints mounted by geninitrd
220 : Last shell before umounting all and giving control over to real init.
224 if is_yes "$dev_mounted"; then
225 echo 'umount /dev' | add_linuxrc
228 if is_yes "$sys_mounted"; then
229 echo 'umount /sys' | add_linuxrc
232 if is_yes "$tmp_mounted"; then
233 echo 'umount /tmp' | add_linuxrc
236 if is_yes "$proc_mounted"; then
237 echo 'umount /proc' | add_linuxrc
243 # Checks if busybox has support for APPLET(s)
244 # Exits from geninitrd if the support is not present.
246 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
250 if [ -z "$busybox_functions" ]; then
251 local tmp=$($busybox 2>&1)
253 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
254 if [[ "$tmp" = *applet\ not\ found* ]]; then
256 ln -s $busybox $t/busybox
257 local tmp=$($t/busybox 2>&1)
261 busybox_functions=$(echo "$tmp" | \
262 sed -ne '/Currently defined functions:/,$p' | \
263 xargs | sed -e 's,.*Currently defined functions: ,,'
269 eval have='$'busybox_have_$applet
270 if [ -z "$have" ]; then
271 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
272 if [ "$have" = 0 ]; then
273 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
276 eval busybox_have_$applet=$have
279 if [ $err = 1 ]; then
284 # Extract the .config file from a kernel image
285 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
287 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
288 if [ -n "$kofile" ]; then
289 /lib/geninitrd/extract-ikconfig $kofile
293 # see if config available as separate file
294 if [ -f /boot/config-$kernel ]; then
295 cat /boot/config-$kernel
299 # finally try vmlinuz itself
300 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
303 # Finds module dependencies
307 # Outputs full path to module and it's dependencies
312 # if module is prefixed with dash, we should ignore errors if the module
314 if [ ${module#-} != $module ]; then
319 # This works when user has module-init-tools installed even on 2.4 kernels
321 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
324 if [ $skiperrors = 1 ]; then
329 if ! is_no "$EXIT_IF_MISSING"; then
330 die "$module: module not found for $kernel kernel"
333 warn "$module: module not found for $kernel kernel"
334 warn "If $module isn't compiled in kernel then this initrd may not start your system."
338 while read insmod modpath options; do
339 [ "$insmod" = "insmod" ] && echo $modpath
347 # no firmware support in 2.4 kernels
348 if [ "$kernel_version_long" -lt "002005048" ]; then
351 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
356 local mod depmod module=$1
358 depmod=$(find_depmod $module) || exit 1
359 for mod in $depmod; do
360 mod=${mod#/lib/modules/$kernel/}
362 # add each module only once
364 for m in $MODULES; do
365 [ $m = $mod ] && have=1
367 if [ $have = 0 ]; then
368 MODULES="$MODULES $mod"
373 # install a file to temporary mount image.
374 # it will operate recursively (copying directories)
375 # and will symlink destinations if source is symlink.
377 if [ $# -lt 2 ]; then
378 die 'Usage: inst <file> [<file>] <destination>'
381 local src i=0 c=$(($# - 1))
382 while [ $i -lt $c ]; do
389 local parentDir=$(dirname $DESTDIR$dest)
390 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
391 debug "+ cp $* $DESTDIR$dest"
392 cp -HR "$@" "$DESTDIR$dest"
397 die 'Usage: inst_d <destination> <destination>'
400 install -d "$DESTDIR$dir"
404 # install executable and it's shared libraries
406 if [ $# -lt 2 ]; then
407 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
409 local src i=0 c=$(($# - 1))
410 while [ $i -lt $c ]; do
420 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
422 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
424 inst_exec $lib /$_lib
428 # hack for uclibc linked binaries requiring this fixed path
429 # XXX: shouldn't rpath be used here instead so th
430 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
431 local lib=$DESTDIR/$_lib/libc.so.0
432 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
433 local libdir=$(cd $(dirname "$lib"); pwd)
434 if [ ! -e $DESTDIR$libdir ]; then
435 libdir=$(dirname "$libdir")
437 debug "+ ln -s /$_lib $DESTDIR$libdir"
438 ln -s /$_lib $DESTDIR$libdir
443 # output modules.conf / modprobe.conf
445 echo "$modprobe_conf_cache"
449 # defaults to modprobe -c if not told otherwise, this means include statements
451 cache_modprobe_conf() {
452 if [ "$kernel_version" -lt "002005" ]; then
453 modulefile=/etc/modules.conf
454 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
455 modulefile=/etc/conf.modules
459 if [ -n "$modulefile" ]; then
460 debug "Using $modulefile for modules config"
461 modprobe_conf_cache=$(cat $modulefile)
463 debug "Using modprobe -c to get modules config"
464 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
468 # find modules for $devpath
469 find_modules_for_devpath() {
471 if [ -z "$devpath" ]; then
472 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
475 if [[ "$devpath" = /dev/dm-* ]]; then
476 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
477 devpath=$(dm_node "$devpath")
480 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
481 # sanitize things like:
482 # /dev/block/104:2 -> /dev/cciss/c0d0p2
483 devpath=$(readlink -f "$devpath")
486 debug "Finding modules for device path $devpath"
488 if is_luks "$devpath"; then
489 find_modules_luks "$devpath"
493 if is_nfs "$devpath"; then
494 find_modules_nfs "$devpath"
498 if is_md "$devpath"; then
499 find_modules_md "$devpath"
503 if is_multipath "$devpath"; then
504 if find_modules_multipath "$devpath"; then
511 if is_dmraid "$devpath"; then
512 if find_modules_dmraid "$devpath"; then
518 if is_scsi "$devpath"; then
519 find_modules_scsi "$devpath"
523 if is_ide "$devpath"; then
524 find_modules_ide "$devpath"
528 if [[ "$devpath" == /dev/rd/* ]]; then
534 if [[ "$devpath" == /dev/ida/* ]]; then
535 find_module "cpqarray"
536 rootdev_add=/dev/ida/
540 if [[ "$devpath" == /dev/cciss/* ]]; then
542 rootdev_add=/dev/cciss/
546 if [[ "$devpath" == /dev/ataraid/* ]]; then
548 find_module "ataraid"
549 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
550 if [ -n "$ataraidmodules" ]; then
551 # FIXME: think about modules compiled in kernel
552 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
554 for n in $ataraidmodules; do
557 rootdev_add=/dev/ataraid/
561 # check to see if we need to set up a loopback filesystem
562 if [[ "$devpath" == /dev/loop* ]]; then
563 die "Sorry, root on loop device isn't supported."
564 # TODO: rewrite for bsp and make nfs ready
565 if [ ! -x /sbin/losetup ]; then
566 die "losetup is missing"
568 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
569 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
570 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"
573 line="`awk '/'$key'/ { print $0; }' $fstab`"
574 loopDev="$(echo $line | awk '{print $3}')"
575 loopFs="$(echo $line | awk '{print $4}')"
576 loopFile="$(echo $line | awk '{print $5}')"
578 BASICMODULES="$BASICMODULES -loop"
579 find_module "-$loopFs"
580 BASICMODULES="$BASICMODULES -${loopFs}"
584 if is_lvm "$devpath"; then
585 find_modules_lvm "$devpath"
590 firmware_install_module() {
592 local firmware_files="$2"
594 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
595 # firmware not yet installed
596 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
598 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
600 echo 1 > /sys$DEVPATH/loading
601 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
602 echo 0 > /sys$DEVPATH/loading
605 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
608 for firmware in $firmware_files; do
609 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
610 FIRMWAREDIR=${firmware%/*}
611 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
612 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
613 elif [ -f "/lib/firmware/$firmware" ]; then
614 FIRMWAREDIR=${firmware%/*}
615 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
616 inst /lib/firmware/$firmware /lib/firmware/$firmware
618 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
623 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
630 for mod in $modules; do
632 inst_d "/lib/modules/$kernel/$MODULEDIR"
633 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
634 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
635 if [ "$STRIP" ] ; then
636 mod_nocomp=${mod%.gz}
637 $STRIP --strip-unneeded --remove-section=.comment --remove-section=.note.GNU-stack "$DESTDIR/lib/modules/$kernel/$mod_nocomp"
642 modules_add_linuxrc() {
646 # module path without optional compression
650 local module=${modpath##*/}; module=${module%$modext}
651 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
652 local genericname=$(echo $module | tr - _)
653 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
654 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
656 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
657 options="scan=sync $options"
660 if [ -n "$verbose" ]; then
662 if [ "$options" ]; then
663 s="$s with options [$options]"
665 if [ "$usleep" ]; then
666 s="$s and $usleep usleep"
668 debug "Loading module [$module]$s"
671 if [ -n "$firmware" ]; then
672 firmware_install_module "$module" "$firmware"
674 for file in $(find_firmware "$module"); do
675 firmware_install_module "$module" "$file"
679 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
680 if [ -n "$usleep" ]; then
681 echo "usleep $usleep" | add_linuxrc
683 if [ "$module" = "scsi_wait_scan" ]; then
684 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
685 echo "rmmod scsi_wait_scan" | add_linuxrc
692 # Generates /dev nodes based on /proc/partitions information.
693 # Needs /proc mounted.
694 # Can be called multiple times.
695 initrd_gen_devices() {
696 if is_yes "$proc_partitions"; then
703 : 'Making device nodes'
704 cat /proc/partitions | (
705 # ignore first two lines: header, empty line
708 while read major minor blocks dev rest; do
711 [ -e $node ] || mknod $node b $major $minor
718 initrd_gen_setrootdev() {
719 debug "Adding rootfs finding based on kernel cmdline root= option support."
722 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
723 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
725 if [ -z "$rootnr" ]; then
726 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
728 if [ -n "$rootnr" ]; then
729 echo "$rootnr" > /proc/sys/kernel/real-root-dev
735 initrd_gen_initramfs_switchroot() {
737 if [ "$rootdev" = "/dev/nfs" ]; then
738 echo "rootfs on NFS root=/dev/nfs"
740 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
743 # parse 'root=xxx' kernel commandline
744 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
746 device=/dev/no_partition_found
747 eval "$(busybox awk -v c="$ROOT" '
749 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
750 num_pattern = "[0-9a-f]" num_pattern_short;
751 dev_pattern = "[hms][a-z][a-z]([0-9])+";
752 partition = "no_partition_found";
756 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
757 if (c ~ "^" num_pattern "$") {
758 maj = sprintf("%s",substr(c,1,2));
759 min = sprintf("%s",substr(c,3));
761 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
762 if (c ~ "^" dev_pattern "$") partition = c;
765 $4 ~ partition { maj = $1; min = $2; }
766 $1 ~ maj && $2 ~ min { partition = $4; }
769 if (maj >= 0 && min >= 0) {
770 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
774 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
775 mknod $device b $maj $min
785 if [ "$device" = '/dev/no_partition_found' ]; then
789 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
791 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
792 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
793 if [ -z "$init" -o ! -x "/newroot$init" ]; then
799 busybox_applet switch_root
801 exec switch_root /newroot $init ${1:+"$@"}
803 echo "Error! initramfs should not reach this place."
804 echo "It probably means you've got old version of busybox, with broken"
805 echo "initramfs support. Trying to boot anyway, but won't promise anything."
807 exec chroot /newroot $init ${1:+"$@"}
809 echo "Failed to chroot!"
812 # we need /init being real file, not symlink, otherwise the initramfs will
813 # not be ran by pid 1 which is required for switch_root
814 mv $DESTDIR/linuxrc $DESTDIR/init
815 ln -s init $DESTDIR/linuxrc
818 # find if $symbol exists in System.map $mapfile
822 if [ ! -f $mapfile ]; then
823 # missing mapfile (not a pld kernel?)
827 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
830 # find best compressor (or forced one) for initrd
833 # fastest initrd decompression speed is first
834 local compressors='lzo gzip xz lzma bzip2'
836 # a specified one, take it
837 if ! is_yes "$mode"; then
841 debug "finding compressor: $compressors (via $mode)"
842 # check for compressor validity
843 local c prog map=/boot/System.map-$kernel
844 for c in $compressors; do
867 # any existing sym will work
872 die "Unknown compressor $c"
875 if sym_exists $map $sym && [ -x $prog ]; then
881 debug "using gzip for compressor (fallback)"
885 # compresses kernel image image
886 # in function so we could retry with other compressor on failure
888 local compressor="$1" IMAGE="$2" target="$3" tmp
889 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
891 case "$compressor" in
893 # don't use -9 here since kernel won't understand it
894 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
897 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
900 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
903 gzip -9 < "$IMAGE" > "$tmp" || return $?
906 lzop -9 < "$IMAGE" > "$tmp" || return $?
909 cat < "$IMAGE" > "$tmp" || return $?
913 mv -f "$tmp" "$target"
916 if [ -r /etc/sysconfig/geninitrd ]; then
917 . /etc/sysconfig/geninitrd
920 if [ ! -f /proc/mounts ]; then
921 warn "/proc filesystem not mounted, may cause wrong results or failure."
924 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
926 while [ $# -gt 0 ]; do
936 modulefile=${1#--modules-conf=}
945 --without-bootsplash)
957 --without-fbcondecor)
966 --with-suspend2 | --with-tuxonice)
969 --without-suspend2 | --without-tuxonice)
973 LVMTOOLSVERSION=${1#--lvmversion=}
976 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
978 --lvmtoolsversion|--lvmversion)
995 USE_MULTIPATH=${1#--with-multipath=}
1004 BASICMODULES="$BASICMODULES ${1#--with=}"
1007 BASICMODULES="$BASICMODULES $2"
1011 echo "$PROGRAM: version $VERSION"
1021 COMPRESS="${1#--compress=}"
1030 STRIP="${1#--strip=}"
1043 PREMODS="$PREMODS ${1#--preload=}"
1046 PREMODS="$PREMODS $2"
1050 die "--fs option is obsoleted. Use --initrdfs instead"
1053 INITRDFS=${1#--initrdfs=}
1066 if [ -z "$target" ]; then
1068 elif [ -z "$kernel" ]; then
1080 if [ -z "$target" -o -z "$kernel" ]; then
1086 if [ "$(id -u)" != 0 ]; then
1087 die "You need to be root to generate initrd"
1090 if [ -d /lib64 -a -d /usr/lib64 ]; then
1096 initrd_dir=/usr/$_lib/initrd
1097 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1098 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1100 debug "# $GENINITRD_RCSID (geninitrd)"
1101 debug "Using _lib: $_lib"
1102 debug "Using initrd_dir: $initrd_dir"
1104 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1106 # we setup mods after parsing command line args
1107 geninitrd_setup_mods
1109 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1110 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1113 if [ -z "$INITRDFS" ]; then
1114 if [ -n "$FS" ]; then
1115 # FS= can came only via /etc/sysconfig/geninitrd likely?
1116 die "FS configuration option is obsoleted. Use INITRDFS instead"
1120 if [ "$kernel_version" -ge "002005" ]; then
1121 INITRDFS="initramfs"
1129 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1132 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1135 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1138 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1139 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1142 die "Filesystem $INITRDFS on initrd is not supported"
1146 if [ -L "$target" ]; then
1147 target=$(readlink -f "$target")
1150 if [ -n "$img_vers" ]; then
1151 target="$target-$kernel"
1154 if [ -z "$force" -a -f "$target" ]; then
1155 die "$target already exists."
1158 if [ ! -d "/lib/modules/$kernel" ]; then
1159 die "/lib/modules/$kernel is not a directory."
1162 if [ "$kernel_version" -ge "002005" ]; then
1168 for n in $PREMODS; do
1172 if [ "$FBMODULE" ]; then
1173 find_module "$FBMODULE"
1176 # autodetect USB keyboards
1179 # allow forcing loading SCSI and/or IDE modules
1180 # XXX: where ADDSCSI cames from? drop?
1181 if is_yes "$ADDSCSI"; then
1185 # autodetect SATA modules
1188 # XXX: where ADDIDE cames from? drop?
1189 if is_yes "$ADDIDE"; then
1193 if is_yes "$USE_SUSPEND"; then
1194 find_modules_suspend
1197 find_root "$fstab" || exit
1198 debug "Using $rootdev as device for rootfs"
1200 find_modules_for_devpath "$rootdev"
1202 # if USE_MULTIPATH is path to device, scan that too
1203 # this is to bootstrap multipath setup into initrd.
1204 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1205 find_modules_multipath $USE_MULTIPATH
1208 find_module "-$rootFs"
1210 for n in $BASICMODULES; do
1214 if is_yes "$USE_TUXONICE"; then
1218 find_modules_fbsplash
1220 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1221 debug "No modules are needed -- not building initrd image."
1225 debug "Building initrd..."
1226 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1227 RCFILE="$DESTDIR/linuxrc"
1229 chmod a+rx "$RCFILE"
1230 ln -s linuxrc $DESTDIR/init
1232 # create dirs that we really need
1233 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1235 modules_install "$MODULES"
1237 # mknod'ing the devices instead of copying them works both with and
1239 mknod "$DESTDIR/dev/console" c 5 1
1240 mknod "$DESTDIR/dev/null" c 1 3
1241 mknod "$DESTDIR/dev/zero" c 1 5
1242 mknod "$DESTDIR/dev/random" c 1 8
1243 mknod "$DESTDIR/dev/urandom" c 1 9
1245 inst_exec $busybox /bin/busybox
1246 ln -s busybox $DESTDIR/bin/sh
1247 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1248 ln -s busybox $DESTDIR/bin/initrd-busybox
1252 # initrd generated by:
1257 add_linuxrc <<-'EOF'
1258 read CMDLINE < /proc/cmdline; export CMDLINE
1260 for arg in $CMDLINE; do
1261 if [ "${arg}" = "debuginitrd" ]; then
1264 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1265 DEBUGINITRD=${arg##debuginitrd=}
1267 if [ "${arg##root=}" != "${arg}" ]; then
1270 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1271 ROOTFSFLAGS=${arg##rootfsflags=}
1275 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1276 if [ "$DEBUGINITRD" = "sh" ]; then
1279 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1280 add_linuxrc <<-'EOF'
1281 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1284 add_linuxrc <<-'EOF'
1288 add_linuxrc <<-'EOF'
1296 if [ "$DEBUGINITRD" ]; then
1301 modules_add_linuxrc $MODULES
1303 # TODO: rewrite for busybox
1304 #if [ -n "$loopDev" ]; then
1305 # if [ ! -d /initrd ]; then
1309 # cp -a "$loopDev" "$DESTDIR/dev"
1310 # cp -a "$rootdev" "$DESTDIR/dev"
1311 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1312 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1313 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1314 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1317 if is_yes "$USE_UDEV"; then
1321 find_modules_uvesafb
1326 initrd_gen_multipath
1329 if is_yes "$have_nfs"; then
1335 initrd_gen_setrootdev
1341 # additional devs always needed
1342 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1344 initrd_gen_stop_udevd
1345 initrd_gen_stop_uvesafb
1347 if [ "$INITRDFS" = "initramfs" ]; then
1348 initrd_gen_initramfs_switchroot
1354 initrd_gen_fbcondecor
1356 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1358 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1359 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1361 debug "Creating $INITRDFS image $IMAGE"
1364 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1365 # NOTE: ext2 label is max 16 chars
1366 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1367 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1369 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1370 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1371 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1372 # We don't need this directory, so let's save space
1373 rm -rf "$tmpmnt"/lost+found
1375 debug "Copy recursively $DESTDIR -> $tmpmnt"
1376 cp -a $DESTDIR/* $tmpmnt
1382 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1385 mkcramfs "$DESTDIR" "$IMAGE"
1388 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1391 die "Filesystem $INITRDFS not supported by $PROGRAM"
1394 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1395 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1396 CONFIG_BLK_DEV_RAM_SIZE=4096
1399 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1400 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1403 if ! is_no "$COMPRESS"; then
1404 compressor=$(find_compressor "$COMPRESS")
1405 debug "Compressing $target with $compressor"
1407 # TODO: the image name (specified from kernel.spec) already contains
1408 # extension, which is .gz most of the time.
1409 compress_image "$compressor" "$IMAGE" "$target" || {
1410 if [ $compressor != gzip ]; then
1411 warn "Could not compress with $compressor, retrying with gzip"
1412 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1414 die "Could not compress image with $compressor"
1418 cp -a "$IMAGE" "$target"
1421 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1422 initrd_gen_bootsplash "$target"
1424 rm -rf "$DESTDIR" "$IMAGE"
1426 # vim:ts=4:sw=4:noet:fdm=marker