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=initramfs $dir/initrd-$kver.gz $kver $verbose"
83 [ -n "$verbose" ] && msg "$*" >&3
87 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
90 # aborts program abnormally
97 # find program from specified paths
100 local paths="$initrd_dir /bin /sbin /usr/bin /usr/sbin"
102 debug "find_tool: checking $x"
105 verbose "find_tool: found $x"
111 debug "find_tool: checking $p/$b"
112 if [ -x "$p/$b" ]; then
114 verbose "find_tool: found $p/$b"
120 debug "find_tool: did not find any of: $n"
124 # loads geninitrd modules
125 geninitrd_load_mods() {
128 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
129 die "$mod geninitrd module can't be loaded"
131 . /lib/geninitrd/mod-$mod.sh
133 GENINITRD_MODS="$GENINITRD_MODS $mod"
137 # setup geninitrd modules
138 geninitrd_setup_mods() {
141 for mod in $GENINITRD_MODS; do
142 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
143 debug "# $rcsid (mod-$mod)"
145 # some mods want init
146 if type setup_mod_$mod > /dev/null; then
152 # append text to /linuxrc
153 # takes STDIN as input
158 # generate code to mount /dev on tmpfs and create initial nodes
159 # can be called multiple times. /dev is cleaned up (umounted) automatically at
162 # we already generated tmpfs code; return
163 if is_yes "$dev_mounted"; then
169 busybox_applet mount mknod mkdir
172 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
173 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
174 mknod -m 600 /dev/console c 5 1
175 mknod -m 666 /dev/null c 1 3
176 mknod -m 666 /dev/zero c 1 5
177 mknod -m 666 /dev/random c 1 8
178 mknod -m 600 /dev/snapshot c 10 231
179 mknod -m 666 /dev/urandom c 1 9
180 mknod -m 666 /dev/ptmx c 5 2
181 mknod -m 644 /dev/kmsg c 1 11
188 # generate code to mount /proc on initrd
189 # can be called multiple times
191 if is_yes "$proc_mounted"; then
196 if [ "$INITRDFS" = "initramfs" ]; then
197 # /proc is mounted with initramfs 2.6.22.14 kernel
198 # XXX: remove when it is clear why proc was already mounted
199 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
201 echo "mount -t proc none /proc" | add_linuxrc
205 # generate code to mount /sys on initrd
206 # can be called multiple times
208 if is_yes "$sys_mounted"; then
213 echo "mount -t sysfs none /sys" | add_linuxrc
216 # generate code to mount /tmp on initrd
217 # can be called multiple times
219 if [ "$INITRDFS" = "initramfs" ]; then
220 # initramfs is read-write filesystem, no need for tmpfs
224 if is_yes "$tmp_mounted"; then
229 echo "mount -t tmpfs none /tmp" | add_linuxrc
232 # generate code to mount /run on initrd
233 # can be called multiple times
235 if is_yes "$run_mounted"; then
240 echo "mount -t tmpfs run /run" | add_linuxrc
243 # unmount all mountpoints mounted by geninitrd
247 : Last shell before umounting all and giving control over to real init.
251 if is_yes "$run_mounted"; then
252 echo 'mount --bind /run /newroot/run' | add_linuxrc
253 echo 'umount /run' | add_linuxrc
256 if is_yes "$dev_mounted"; then
257 echo 'umount /dev' | add_linuxrc
260 if is_yes "$sys_mounted"; then
261 echo 'umount /sys' | add_linuxrc
264 if is_yes "$tmp_mounted"; then
265 echo 'umount /tmp' | add_linuxrc
268 if is_yes "$proc_mounted"; then
269 echo 'umount /proc' | add_linuxrc
275 # Checks if busybox has support for APPLET(s)
276 # Exits from geninitrd if the support is not present.
278 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
282 if [ -z "$busybox_functions" ]; then
283 local tmp=$($busybox 2>&1)
285 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
286 if [[ "$tmp" = *applet\ not\ found* ]]; then
288 ln -s $busybox $t/busybox
289 local tmp=$($t/busybox 2>&1)
293 busybox_functions=$(echo "$tmp" | \
294 sed -ne '/Currently defined functions:/,$p' | \
295 xargs | sed -e 's,.*Currently defined functions: ,,'
301 eval have='$'busybox_have_$applet
302 if [ -z "$have" ]; then
303 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
304 if [ "$have" = 0 ]; then
305 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
308 eval busybox_have_$applet=$have
311 if [ $err = 1 ]; then
316 # Extract the .config file from a kernel image
317 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
319 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
320 if [ -n "$kofile" ]; then
321 /lib/geninitrd/extract-ikconfig $kofile
325 # see if config available as separate file
326 if [ -f /boot/config-$kernel ]; then
327 cat /boot/config-$kernel
331 # finally try vmlinuz itself
332 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
340 module=${module%$modext*}
344 # Finds module dependencies
348 # Outputs full path to module and it's dependencies
353 # if module is prefixed with dash, we should ignore errors if the module
355 if [ ${module#-} != $module ]; then
360 # This works when user has module-init-tools installed even on 2.4 kernels
362 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
365 if [ $skiperrors = 1 ]; then
370 if ! is_no "$EXIT_IF_MISSING"; then
371 die "$module: module not found for $kernel kernel"
374 warn "$module: module not found for $kernel kernel"
375 warn "If $module isn't compiled in kernel then this initrd may not start your system."
381 while read insmod modpath options; do
382 if [ "$insmod" = "insmod" ]; then
384 # XXX: find a away to autodetect
385 smodule=$(basename_module $modpath)
388 find_depmod "-crc32c-intel"
389 find_depmod "-crc32c"
402 # no firmware support in 2.4 kernels
403 if [ "$kernel_version_long" -lt "002005048" ]; then
406 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
411 local mod depmod module=$1
413 depmod=$(find_depmod $module) || exit 1
414 for mod in $depmod; do
415 mod=${mod#/lib/modules/$kernel/}
417 # add each module only once
419 for m in $MODULES; do
420 [ $m = $mod ] && have=1
422 if [ $have = 0 ]; then
423 MODULES="$MODULES $mod"
428 # install a file to temporary mount image.
429 # it will operate recursively (copying directories)
430 # and will symlink destinations if source is symlink.
432 if [ $# -lt 2 ]; then
433 die 'Usage: inst <file> [<file>] <destination>'
436 local src i=0 c=$(($# - 1))
437 while [ $i -lt $c ]; do
444 local parentDir=$(dirname $DESTDIR$dest)
445 if [ ! -d "$parentDir" ]; then
446 verbose "+ mkdir -p $parentDir"
449 verbose "+ cp $* $DESTDIR$dest"
450 cp -HR "$@" "$DESTDIR$dest"
455 die 'Usage: inst_d <destination> <destination>'
458 install -d "$DESTDIR$dir"
462 # install executable and it's shared libraries
464 if [ $# -lt 2 ]; then
465 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
467 local src i=0 c=$(($# - 1))
468 while [ $i -lt $c ]; do
481 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
485 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
487 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
489 inst_exec $lib /$_lib
494 # hack for uclibc linked binaries requiring this fixed path
495 # XXX: shouldn't rpath be used here instead so th
496 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
497 local lib=$DESTDIR/$_lib/libc.so.0
498 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
499 local libdir=$(cd $(dirname "$lib"); pwd)
500 if [ ! -e $DESTDIR$libdir ]; then
501 libdir=$(dirname "$libdir")
503 verbose "+ ln -s /$_lib $DESTDIR$libdir"
504 ln -s /$_lib $DESTDIR$libdir
509 # output modules.conf / modprobe.conf
511 echo "$modprobe_conf_cache"
514 # return options for MODULE
515 # @param $1 module name
518 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
523 # defaults to modprobe -c if not told otherwise, this means include statements
525 cache_modprobe_conf() {
526 if [ "$kernel_version" -lt "002005" ]; then
527 modulefile=/etc/modules.conf
528 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
529 modulefile=/etc/conf.modules
533 if [ -n "$modulefile" ]; then
534 debug "Using $modulefile for modules config"
535 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
538 debug "Using modprobe -c to get modules config"
539 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
543 # find modules for $devpath
544 find_modules_for_devpath() {
546 if [ -z "$devpath" ]; then
547 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
550 if [[ "$devpath" = /dev/dm-* ]]; then
551 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
552 devpath=$(dm_node "$devpath")
555 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
556 # sanitize things like:
557 # /dev/block/104:2 -> /dev/cciss/c0d0p2
558 devpath=$(readlink -f "$devpath")
561 verbose "Finding modules for device path $devpath"
563 if is_luks "$devpath"; then
564 find_modules_luks "$devpath"
568 if is_nfs "$devpath"; then
569 find_modules_nfs "$devpath"
573 if is_md "$devpath"; then
574 find_modules_md "$devpath"
578 if is_multipath "$devpath"; then
579 if find_modules_multipath "$devpath"; then
586 if is_dmraid "$devpath"; then
587 if find_modules_dmraid "$devpath"; then
593 if is_scsi "$devpath"; then
594 find_modules_scsi "$devpath"
598 if is_ide "$devpath"; then
599 find_modules_ide "$devpath"
603 if [[ "$devpath" == /dev/rd/* ]]; then
609 if [[ "$devpath" == /dev/ida/* ]]; then
610 find_module "cpqarray"
611 rootdev_add=/dev/ida/
615 if [[ "$devpath" == /dev/cciss/* ]]; then
616 rootdev_add=/dev/cciss/
618 # load hpsa for future kernels, cciss for backwards compat
619 if [ "$kernel_version_long" -ge "003000000" ]; then
620 find_module "hpsa" "-cciss"
621 find_modules_scsi "$devpath"
629 if [[ "$devpath" == /dev/ataraid/* ]]; then
631 find_module "ataraid"
632 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
633 if [ -n "$ataraidmodules" ]; then
634 # FIXME: think about modules compiled in kernel
635 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
637 for n in $ataraidmodules; do
640 rootdev_add=/dev/ataraid/
644 # check to see if we need to set up a loopback filesystem
645 if [[ "$devpath" == /dev/loop* ]]; then
646 die "Sorry, root on loop device isn't supported."
647 # TODO: rewrite for bsp and make nfs ready
648 if [ ! -x /sbin/losetup ]; then
649 die "losetup is missing"
651 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
652 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
653 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"
656 line="`awk '/'$key'/ { print $0; }' $fstab`"
657 loopDev="$(echo $line | awk '{print $3}')"
658 loopFs="$(echo $line | awk '{print $4}')"
659 loopFile="$(echo $line | awk '{print $5}')"
661 BASICMODULES="$BASICMODULES -loop"
662 find_module "-$loopFs"
663 BASICMODULES="$BASICMODULES -${loopFs}"
667 if is_lvm "$devpath"; then
668 find_modules_lvm "$devpath"
673 firmware_install_module() {
675 local firmware_files="$2"
677 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
678 # firmware not yet installed
679 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
681 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
683 echo 1 > /sys$DEVPATH/loading
684 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
685 echo 0 > /sys$DEVPATH/loading
688 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
690 # setup firmware loader agent
691 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
694 for firmware in $firmware_files; do
695 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
696 FIRMWAREDIR=${firmware%/*}
697 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
698 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
699 elif [ -f "/lib/firmware/$firmware" ]; then
700 FIRMWAREDIR=${firmware%/*}
701 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
702 inst /lib/firmware/$firmware /lib/firmware/$firmware
704 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
715 for mod in $modules; do
717 inst_d "/lib/modules/$kernel/$MODULEDIR"
718 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
719 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
720 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
721 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
726 modules_add_linuxrc() {
730 # module path without optional compression
734 local module=${modpath##*/}; module=${module%$modext}
735 local options=$(modprobe_options "$module")
736 local genericname=$(echo $module | tr - _)
737 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
738 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
740 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
741 options="scan=sync $options"
744 if [ x"$verbose" = x"-v" ]; then
746 if [ "$options" ]; then
747 s="$s with options [$options]"
749 if [ "$usleep" ]; then
750 s="$s and $usleep usleep"
752 verbose "Loading module [$module]$s"
755 if [ -n "$firmware" ]; then
756 firmware_install_module "$module" "$firmware"
758 for file in $(find_firmware "$module"); do
759 firmware_install_module "$module" "$file"
763 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
764 if [ -n "$usleep" ]; then
765 echo "usleep $usleep" | add_linuxrc
767 if [ "$module" = "scsi_wait_scan" ]; then
768 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
769 echo "rmmod scsi_wait_scan" | add_linuxrc
776 # Generates /dev nodes based on /proc/partitions information.
777 # Needs /proc mounted.
778 # Can be called multiple times.
779 initrd_gen_devices() {
780 if is_yes "$proc_partitions"; then
787 : 'Making device nodes'
788 cat /proc/partitions | (
789 # ignore first two lines: header, empty line
792 while read major minor blocks dev rest; do
795 [ -e $node ] || mknod -m 660 $node b $major $minor
802 initrd_gen_setrootdev() {
803 verbose "Adding rootfs finding based on kernel cmdline root= option support."
805 debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
807 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
808 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
810 if [ -z "$rootnr" ]; then
811 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
813 if [ -n "$rootnr" ]; then
814 echo "$rootnr" > /proc/sys/kernel/real-root-dev
820 initrd_gen_initramfs_switchroot() {
822 if [ "$rootdev" = "/dev/nfs" ]; then
823 echo "rootfs on NFS root=/dev/nfs"
825 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
828 # parse 'root=xxx' kernel commandline
829 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
831 # from lilo-23.2/readme/README:
832 # root=<device> changes the root device. This overrides settings that may
833 # have been made in the boot image and on the LILO command line. <device> is
834 # either the hexadecimal device number or the full path name of the device,
837 # * The device names are hard-coded in the kernel. Therefore, only the
838 # "standard" names are supported and some less common devices may not be
839 # recognized. In those cases, only numbers can be used.
842 eval "$(busybox awk -v root="$ROOT" '
843 # http://9fans.net/archive/2006/09/261
844 function h2d(str, hstr, res, num, n, digit, i) {
845 hstr = "0123456789abdcef";
847 n = split(tolower(str), digit, "");
849 for (i = 1; i <= n; i++) {
850 num = index(hstr, digit[i]) - 1;
851 res = res + (num * 16 ^ (n - i));
858 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
859 num_pattern = "[0-9a-fA-F]" num_pattern_short;
860 dev_pattern = "[hms][a-z][a-z]([0-9])+";
864 # see if we have /dev/hdX or hdX, we can just take partition name
865 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
867 sub("^/dev/", "", partition);
871 if (root ~ "^" num_pattern_short "$") {
872 # change "303" => "0x0303"
874 } else if (root ~ "^" num_pattern "$") {
875 # change "0303" => "0x0303"
879 maj = h2d(substr(root, 3, 2));
880 min = h2d(substr(root, 5, 2));
884 partition && $4 == partition { maj = $1; min = $2; }
885 $1 == maj && $2 == min { partition = $4; }
888 if (maj >= 0 && min >= 0) {
889 printf("maj=%s; min=%s;\n", maj, min);
892 printf("device=/dev/%s;\n", partition);
897 if [ -z "$device" ]; then
901 if [ "$device" -a ! -b $device ]; then
902 mknod -m 660 $device b $maj $min
905 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
907 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
909 if [ -z "$init" -o ! -x "/newroot$init" ]; then
915 busybox_applet switch_root
917 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
918 exec switch_root /newroot $init ${1:+"$@"}
920 echo "Error! initramfs should not reach this place."
921 echo "It probably means you've got old version of busybox, with broken"
922 echo "initramfs support. Trying to boot anyway, but won't promise anything."
924 exec chroot /newroot $init ${1:+"$@"}
926 echo "Failed to chroot!"
929 # we need /init being real file, not symlink, otherwise the initramfs will
930 # not be ran by pid 1 which is required for switch_root
931 mv $DESTDIR/linuxrc $DESTDIR/init
932 ln -s init $DESTDIR/linuxrc
935 # find if $symbol exists in System.map $mapfile
939 if [ ! -f $mapfile ]; then
940 # missing mapfile (not a pld kernel?)
944 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
947 # find best compressor (or forced one) for initrd
950 # fastest initrd decompression speed is first
951 local compressors='lzo gzip xz lzma bzip2'
953 # a specified one, take it
954 if ! is_yes "$mode"; then
958 verbose "finding compressor: $compressors (via $mode)"
959 # check for compressor validity
960 local c prog map=/boot/System.map-$kernel
961 for c in $compressors; do
984 # any existing sym will work
989 die "Unknown compressor $c"
992 if sym_exists $map $sym && [ -x $prog ]; then
998 verbose "using gzip for compressor (fallback)"
1002 # compresses kernel image image
1003 # in function so we could retry with other compressor on failure
1005 local compressor="$1" IMAGE="$2" target="$3" tmp
1006 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1008 case "$compressor" in
1010 # don't use -9 here since kernel won't understand it
1011 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1014 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1017 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1020 gzip -9 < "$IMAGE" > "$tmp" || return $?
1023 lzop -9 < "$IMAGE" > "$tmp" || return $?
1026 cat < "$IMAGE" > "$tmp" || return $?
1030 mv -f "$tmp" "$target"
1033 if [ -r /etc/sysconfig/geninitrd ]; then
1034 . /etc/sysconfig/geninitrd
1037 if [ ! -f /proc/mounts ]; then
1038 warn "/proc filesystem not mounted, may cause wrong results or failure."
1041 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1043 while [ $# -gt 0 ]; do
1053 modulefile=${1#--modules-conf=}
1062 --without-bootsplash)
1074 --without-fbcondecor)
1083 --with-suspend2 | --with-tuxonice)
1086 --without-suspend2 | --without-tuxonice)
1090 LVMTOOLSVERSION=${1#--lvmversion=}
1092 --lvmtoolsversion=*)
1093 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1095 --lvmtoolsversion|--lvmversion)
1108 --without-multipath)
1112 USE_MULTIPATH=${1#--with-multipath=}
1121 BASICMODULES="$BASICMODULES ${1#--with=}"
1124 BASICMODULES="$BASICMODULES $2"
1128 echo "$PROGRAM: version $VERSION"
1132 if [ x"$verbose" = x"-v" ]; then
1143 COMPRESS="${1#--compress=}"
1152 STRIP="${1#--strip=}"
1165 PREMODS="$PREMODS ${1#--preload=}"
1168 PREMODS="$PREMODS $2"
1172 die "--fs option is obsoleted. Use --initrdfs instead"
1175 INITRDFS=${1#--initrdfs=}
1188 if [ -z "$target" ]; then
1190 elif [ -z "$kernel" ]; then
1202 if [ -z "$target" -o -z "$kernel" ]; then
1208 if [ "$(id -u)" != 0 ]; then
1209 die "You need to be root to generate initrd"
1212 if [ -d /lib64 -a -d /usr/lib64 ]; then
1218 initrd_dir=/usr/$_lib/initrd
1219 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1220 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1222 verbose "# $GENINITRD_RCSID (geninitrd)"
1223 debug "Using _lib: $_lib"
1224 debug "Using initrd_dir: $initrd_dir"
1226 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1228 # we setup mods after parsing command line args
1229 geninitrd_setup_mods
1231 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1232 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1235 if [ -z "$INITRDFS" ]; then
1236 if [ -n "$FS" ]; then
1237 # FS= can came only via /etc/sysconfig/geninitrd likely?
1238 die "FS configuration option is obsoleted. Use INITRDFS instead"
1242 if [ "$kernel_version" -ge "002005" ]; then
1243 INITRDFS="initramfs"
1251 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1254 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1257 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1260 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1261 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1264 die "Filesystem $INITRDFS on initrd is not supported"
1268 if [ -L "$target" ]; then
1269 target=$(readlink -f "$target")
1272 if [ -n "$img_vers" ]; then
1273 target="$target-$kernel"
1276 if [ -z "$force" -a -f "$target" ]; then
1277 die "$target already exists."
1280 if [ ! -d "/lib/modules/$kernel" ]; then
1281 die "/lib/modules/$kernel is not a directory."
1284 if [ "$kernel_version" -ge "002005" ]; then
1290 for n in $PREMODS; do
1294 if [ "$FBMODULE" ]; then
1295 find_module "$FBMODULE"
1298 # autodetect USB keyboards
1301 # allow forcing loading SCSI and/or IDE modules
1302 # XXX: where ADDSCSI cames from? drop?
1303 if is_yes "$ADDSCSI"; then
1307 # autodetect SATA modules
1310 # XXX: where ADDIDE cames from? drop?
1311 if is_yes "$ADDIDE"; then
1315 if is_yes "$USE_SUSPEND"; then
1316 find_modules_suspend
1319 find_root "$fstab" || exit
1320 verbose "Using $rootdev as device for rootfs"
1322 find_modules_for_devpath "$rootdev"
1324 # if USE_MULTIPATH is path to device, scan that too
1325 # this is to bootstrap multipath setup into initrd.
1326 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1327 find_modules_multipath $USE_MULTIPATH
1330 find_module "-$rootFs"
1332 for n in $BASICMODULES; do
1336 if is_yes "$USE_TUXONICE"; then
1340 find_modules_fbsplash
1342 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1343 verbose "No modules are needed -- not building initrd image."
1347 verbose "Building initrd..."
1348 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1349 RCFILE="$DESTDIR/linuxrc"
1351 chmod a+rx "$RCFILE"
1352 ln -s linuxrc $DESTDIR/init
1354 # create dirs that we really need
1355 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1357 modules_install "$MODULES"
1359 # mknod'ing the devices instead of copying them works both with and
1361 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1362 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1363 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1364 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1365 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1367 inst_exec $busybox /bin/busybox
1368 ln -s busybox $DESTDIR/bin/sh
1369 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1370 ln -s busybox $DESTDIR/bin/initrd-busybox
1374 # initrd generated by:
1380 # builtin defaults from geninitrd
1384 add_linuxrc <<-'EOF'
1385 read CMDLINE < /proc/cmdline
1387 for arg in $CMDLINE; do
1388 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1391 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1392 DEBUGINITRD=${arg##debug*rd=}
1394 if [ "${arg##root=}" != "${arg}" ]; then
1397 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1398 ROOTFSFLAGS=${arg##rootfsflags=}
1400 if [ "${arg##init=}" != "${arg}" ]; then
1405 if [ "$DEBUGINITRD" = "sh" ]; then
1406 # export some vars for subshell debug to work
1407 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1408 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1409 export rootnr attrs majmin major minor device
1411 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1414 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1415 add_linuxrc <<-'EOF'
1416 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1419 add_linuxrc <<-'EOF'
1423 add_linuxrc <<-'EOF'
1431 if [ "$DEBUGINITRD" ]; then
1436 modules_add_linuxrc $MODULES
1438 # TODO: rewrite for busybox
1439 #if [ -n "$loopDev" ]; then
1440 # if [ ! -d /initrd ]; then
1444 # cp -a "$loopDev" "$DESTDIR/dev"
1445 # cp -a "$rootdev" "$DESTDIR/dev"
1446 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1447 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1448 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1449 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1452 if is_yes "$USE_UDEV"; then
1458 find_modules_uvesafb
1463 initrd_gen_multipath
1466 if is_yes "$have_nfs"; then
1473 initrd_gen_setrootdev
1476 # additional devs always needed
1477 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1479 initrd_gen_stop_udevd
1480 initrd_gen_stop_mdev
1481 initrd_gen_stop_uvesafb
1483 # resume after killing local processes
1488 add_linuxrc <<-'EOF'
1489 if [ ! "$DEBUGINITRD" ]; then
1493 for i in $(export -p); do
1494 i=${i#declare -x } # ksh/bash
1495 i=${i#export } # busybox
1506 [ -z "$i" ] && continue
1509 ROOT|PATH|HOME|TERM)
1521 if [ "$INITRDFS" = "initramfs" ]; then
1522 initrd_gen_initramfs_switchroot
1528 initrd_gen_fbcondecor
1530 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1532 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1534 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1535 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1537 verbose "Creating $INITRDFS image $IMAGE"
1540 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1541 # NOTE: ext2 label is max 16 chars
1542 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1543 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1545 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1546 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1547 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1548 # We don't need this directory, so let's save space
1549 rm -rf "$tmpmnt"/lost+found
1551 debug "Copy recursively $DESTDIR -> $tmpmnt"
1552 cp -a $DESTDIR/* $tmpmnt
1558 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1561 mkcramfs "$DESTDIR" "$IMAGE"
1564 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1567 die "Filesystem $INITRDFS not supported by $PROGRAM"
1570 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1571 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1572 CONFIG_BLK_DEV_RAM_SIZE=4096
1573 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1576 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1577 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1580 if ! is_no "$COMPRESS"; then
1581 compressor=$(find_compressor "$COMPRESS")
1582 verbose "Compressing $target with $compressor"
1584 # TODO: the image name (specified from kernel.spec) already contains
1585 # extension, which is .gz most of the time.
1586 compress_image "$compressor" "$IMAGE" "$target" || {
1587 if [ $compressor != gzip ]; then
1588 warn "Could not compress with $compressor, retrying with gzip"
1589 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1591 die "Could not compress image with $compressor"
1595 cp -a "$IMAGE" "$target"
1598 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1599 initrd_gen_bootsplash "$target"
1601 rm -rf "$DESTDIR" "$IMAGE"
1603 # vim:ts=4:sw=4:noet:fdm=marker