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 $STRIP --strip-unneeded --remove-section=.comment --remove-section=.note.GNU-stack "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
641 modules_add_linuxrc() {
645 # module path without optional compression
649 local module=${modpath##*/}; module=${module%$modext}
650 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
651 local genericname=$(echo $module | tr - _)
652 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
653 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
655 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
656 options="scan=sync $options"
659 if [ -n "$verbose" ]; then
661 if [ "$options" ]; then
662 s="$s with options [$options]"
664 if [ "$usleep" ]; then
665 s="$s and $usleep usleep"
667 debug "Loading module [$module]$s"
670 if [ -n "$firmware" ]; then
671 firmware_install_module "$module" "$firmware"
673 for file in $(find_firmware "$module"); do
674 firmware_install_module "$module" "$file"
678 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
679 if [ -n "$usleep" ]; then
680 echo "usleep $usleep" | add_linuxrc
682 if [ "$module" = "scsi_wait_scan" ]; then
683 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
684 echo "rmmod scsi_wait_scan" | add_linuxrc
691 # Generates /dev nodes based on /proc/partitions information.
692 # Needs /proc mounted.
693 # Can be called multiple times.
694 initrd_gen_devices() {
695 if is_yes "$proc_partitions"; then
702 : 'Making device nodes'
703 cat /proc/partitions | (
704 # ignore first two lines: header, empty line
707 while read major minor blocks dev rest; do
710 [ -e $node ] || mknod $node b $major $minor
717 initrd_gen_setrootdev() {
718 debug "Adding rootfs finding based on kernel cmdline root= option support."
721 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
722 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
724 if [ -z "$rootnr" ]; then
725 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
727 if [ -n "$rootnr" ]; then
728 echo "$rootnr" > /proc/sys/kernel/real-root-dev
734 initrd_gen_initramfs_switchroot() {
736 if [ "$rootdev" = "/dev/nfs" ]; then
737 echo "rootfs on NFS root=/dev/nfs"
739 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
742 # parse 'root=xxx' kernel commandline
743 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
745 device=/dev/no_partition_found
746 eval "$(busybox awk -v c="$ROOT" '
748 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
749 num_pattern = "[0-9a-f]" num_pattern_short;
750 dev_pattern = "[hms][a-z][a-z]([0-9])+";
751 partition = "no_partition_found";
755 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
756 if (c ~ "^" num_pattern "$") {
757 maj = sprintf("%s",substr(c,1,2));
758 min = sprintf("%s",substr(c,3));
760 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
761 if (c ~ "^" dev_pattern "$") partition = c;
764 $4 ~ partition { maj = $1; min = $2; }
765 $1 ~ maj && $2 ~ min { partition = $4; }
768 if (maj >= 0 && min >= 0) {
769 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
773 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
774 mknod $device b $maj $min
784 if [ "$device" = '/dev/no_partition_found' ]; then
788 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
790 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
791 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
792 if [ -z "$init" -o ! -x "/newroot$init" ]; then
798 busybox_applet switch_root
800 exec switch_root /newroot $init ${1:+"$@"}
802 echo "Error! initramfs should not reach this place."
803 echo "It probably means you've got old version of busybox, with broken"
804 echo "initramfs support. Trying to boot anyway, but won't promise anything."
806 exec chroot /newroot $init ${1:+"$@"}
808 echo "Failed to chroot!"
811 # we need /init being real file, not symlink, otherwise the initramfs will
812 # not be ran by pid 1 which is required for switch_root
813 mv $DESTDIR/linuxrc $DESTDIR/init
814 ln -s init $DESTDIR/linuxrc
817 # find if $symbol exists in System.map $mapfile
821 if [ ! -f $mapfile ]; then
822 # missing mapfile (not a pld kernel?)
826 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
829 # find best compressor (or forced one) for initrd
832 # fastest initrd decompression speed is first
833 local compressors='lzo gzip xz lzma bzip2'
835 # a specified one, take it
836 if ! is_yes "$mode"; then
840 debug "finding compressor: $compressors (via $mode)"
841 # check for compressor validity
842 local c prog map=/boot/System.map-$kernel
843 for c in $compressors; do
866 # any existing sym will work
871 die "Unknown compressor $c"
874 if sym_exists $map $sym && [ -x $prog ]; then
880 debug "using gzip for compressor (fallback)"
884 # compresses kernel image image
885 # in function so we could retry with other compressor on failure
887 local compressor="$1" IMAGE="$2" target="$3" tmp
888 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
890 case "$compressor" in
892 # don't use -9 here since kernel won't understand it
893 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
896 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
899 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
902 gzip -9 < "$IMAGE" > "$tmp" || return $?
905 lzop -9 < "$IMAGE" > "$tmp" || return $?
908 cat < "$IMAGE" > "$tmp" || return $?
912 mv -f "$tmp" "$target"
915 if [ -r /etc/sysconfig/geninitrd ]; then
916 . /etc/sysconfig/geninitrd
919 if [ ! -f /proc/mounts ]; then
920 warn "/proc filesystem not mounted, may cause wrong results or failure."
923 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
925 while [ $# -gt 0 ]; do
935 modulefile=${1#--modules-conf=}
944 --without-bootsplash)
956 --without-fbcondecor)
965 --with-suspend2 | --with-tuxonice)
968 --without-suspend2 | --without-tuxonice)
972 LVMTOOLSVERSION=${1#--lvmversion=}
975 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
977 --lvmtoolsversion|--lvmversion)
994 USE_MULTIPATH=${1#--with-multipath=}
1003 BASICMODULES="$BASICMODULES ${1#--with=}"
1006 BASICMODULES="$BASICMODULES $2"
1010 echo "$PROGRAM: version $VERSION"
1020 COMPRESS="${1#--compress=}"
1029 STRIP="${1#--strip=}"
1042 PREMODS="$PREMODS ${1#--preload=}"
1045 PREMODS="$PREMODS $2"
1049 die "--fs option is obsoleted. Use --initrdfs instead"
1052 INITRDFS=${1#--initrdfs=}
1065 if [ -z "$target" ]; then
1067 elif [ -z "$kernel" ]; then
1079 if [ -z "$target" -o -z "$kernel" ]; then
1085 if [ "$(id -u)" != 0 ]; then
1086 die "You need to be root to generate initrd"
1089 if [ -d /lib64 -a -d /usr/lib64 ]; then
1095 initrd_dir=/usr/$_lib/initrd
1096 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1097 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1099 debug "# $GENINITRD_RCSID (geninitrd)"
1100 debug "Using _lib: $_lib"
1101 debug "Using initrd_dir: $initrd_dir"
1103 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1105 # we setup mods after parsing command line args
1106 geninitrd_setup_mods
1108 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1109 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1112 if [ -z "$INITRDFS" ]; then
1113 if [ -n "$FS" ]; then
1114 # FS= can came only via /etc/sysconfig/geninitrd likely?
1115 die "FS configuration option is obsoleted. Use INITRDFS instead"
1119 if [ "$kernel_version" -ge "002005" ]; then
1120 INITRDFS="initramfs"
1128 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1131 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1134 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1137 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1138 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1141 die "Filesystem $INITRDFS on initrd is not supported"
1145 if [ -L "$target" ]; then
1146 target=$(readlink -f "$target")
1149 if [ -n "$img_vers" ]; then
1150 target="$target-$kernel"
1153 if [ -z "$force" -a -f "$target" ]; then
1154 die "$target already exists."
1157 if [ ! -d "/lib/modules/$kernel" ]; then
1158 die "/lib/modules/$kernel is not a directory."
1161 if [ "$kernel_version" -ge "002005" ]; then
1167 for n in $PREMODS; do
1171 if [ "$FBMODULE" ]; then
1172 find_module "$FBMODULE"
1175 # autodetect USB keyboards
1178 # allow forcing loading SCSI and/or IDE modules
1179 # XXX: where ADDSCSI cames from? drop?
1180 if is_yes "$ADDSCSI"; then
1184 # autodetect SATA modules
1187 # XXX: where ADDIDE cames from? drop?
1188 if is_yes "$ADDIDE"; then
1192 if is_yes "$USE_SUSPEND"; then
1193 find_modules_suspend
1196 find_root "$fstab" || exit
1197 debug "Using $rootdev as device for rootfs"
1199 find_modules_for_devpath "$rootdev"
1201 # if USE_MULTIPATH is path to device, scan that too
1202 # this is to bootstrap multipath setup into initrd.
1203 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1204 find_modules_multipath $USE_MULTIPATH
1207 find_module "-$rootFs"
1209 for n in $BASICMODULES; do
1213 if is_yes "$USE_TUXONICE"; then
1217 find_modules_fbsplash
1219 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1220 debug "No modules are needed -- not building initrd image."
1224 debug "Building initrd..."
1225 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1226 RCFILE="$DESTDIR/linuxrc"
1228 chmod a+rx "$RCFILE"
1229 ln -s linuxrc $DESTDIR/init
1231 # create dirs that we really need
1232 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1234 modules_install "$MODULES"
1236 # mknod'ing the devices instead of copying them works both with and
1238 mknod "$DESTDIR/dev/console" c 5 1
1239 mknod "$DESTDIR/dev/null" c 1 3
1240 mknod "$DESTDIR/dev/zero" c 1 5
1241 mknod "$DESTDIR/dev/random" c 1 8
1242 mknod "$DESTDIR/dev/urandom" c 1 9
1244 inst_exec $busybox /bin/busybox
1245 ln -s busybox $DESTDIR/bin/sh
1246 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1247 ln -s busybox $DESTDIR/bin/initrd-busybox
1251 # initrd generated by:
1256 add_linuxrc <<-'EOF'
1257 read CMDLINE < /proc/cmdline; export CMDLINE
1259 for arg in $CMDLINE; do
1260 if [ "${arg}" = "debuginitrd" ]; then
1263 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1264 DEBUGINITRD=${arg##debuginitrd=}
1266 if [ "${arg##root=}" != "${arg}" ]; then
1269 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1270 ROOTFSFLAGS=${arg##rootfsflags=}
1274 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1275 if [ "$DEBUGINITRD" = "sh" ]; then
1278 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1279 add_linuxrc <<-'EOF'
1280 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1283 add_linuxrc <<-'EOF'
1287 add_linuxrc <<-'EOF'
1295 if [ "$DEBUGINITRD" ]; then
1300 modules_add_linuxrc $MODULES
1302 # TODO: rewrite for busybox
1303 #if [ -n "$loopDev" ]; then
1304 # if [ ! -d /initrd ]; then
1308 # cp -a "$loopDev" "$DESTDIR/dev"
1309 # cp -a "$rootdev" "$DESTDIR/dev"
1310 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1311 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1312 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1313 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1316 if is_yes "$USE_UDEV"; then
1320 find_modules_uvesafb
1325 initrd_gen_multipath
1328 if is_yes "$have_nfs"; then
1334 initrd_gen_setrootdev
1340 # additional devs always needed
1341 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1343 initrd_gen_stop_udevd
1344 initrd_gen_stop_uvesafb
1346 if [ "$INITRDFS" = "initramfs" ]; then
1347 initrd_gen_initramfs_switchroot
1353 initrd_gen_fbcondecor
1355 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1357 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1358 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1360 debug "Creating $INITRDFS image $IMAGE"
1363 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1364 # NOTE: ext2 label is max 16 chars
1365 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1366 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1368 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1369 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1370 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1371 # We don't need this directory, so let's save space
1372 rm -rf "$tmpmnt"/lost+found
1374 debug "Copy recursively $DESTDIR -> $tmpmnt"
1375 cp -a $DESTDIR/* $tmpmnt
1381 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1384 mkcramfs "$DESTDIR" "$IMAGE"
1387 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1390 die "Filesystem $INITRDFS not supported by $PROGRAM"
1393 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1394 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1395 CONFIG_BLK_DEV_RAM_SIZE=4096
1398 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1399 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1402 if ! is_no "$COMPRESS"; then
1403 compressor=$(find_compressor "$COMPRESS")
1404 debug "Compressing $target with $compressor"
1406 # TODO: the image name (specified from kernel.spec) already contains
1407 # extension, which is .gz most of the time.
1408 compress_image "$compressor" "$IMAGE" "$target" || {
1409 if [ $compressor != gzip ]; then
1410 warn "Could not compress with $compressor, retrying with gzip"
1411 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1413 die "Could not compress image with $compressor"
1417 cp -a "$IMAGE" "$target"
1420 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1421 initrd_gen_bootsplash "$target"
1423 rm -rf "$DESTDIR" "$IMAGE"
1425 # vim:ts=4:sw=4:noet:fdm=marker