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 verbose "find_tool: checking $x"
105 verbose "find_tool: found $x"
111 verbose "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 /dev/console c 5 1
175 mknod /dev/null c 1 3
176 mknod /dev/zero c 1 5
177 mknod /dev/random c 1 8
178 mknod /dev/snapshot c 10 231
179 mknod /dev/urandom c 1 9
180 mknod /dev/ptmx c 5 2
181 mknod /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" | egrep -c "( |^)$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
335 # Finds module dependencies
339 # Outputs full path to module and it's dependencies
344 # if module is prefixed with dash, we should ignore errors if the module
346 if [ ${module#-} != $module ]; then
351 # This works when user has module-init-tools installed even on 2.4 kernels
353 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
356 if [ $skiperrors = 1 ]; then
361 if ! is_no "$EXIT_IF_MISSING"; then
362 die "$module: module not found for $kernel kernel"
365 warn "$module: module not found for $kernel kernel"
366 warn "If $module isn't compiled in kernel then this initrd may not start your system."
370 while read insmod modpath options; do
371 [ "$insmod" = "insmod" ] && echo $modpath
379 # no firmware support in 2.4 kernels
380 if [ "$kernel_version_long" -lt "002005048" ]; then
383 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
388 local mod depmod module=$1
390 depmod=$(find_depmod $module) || exit 1
391 for mod in $depmod; do
392 mod=${mod#/lib/modules/$kernel/}
394 # add each module only once
396 for m in $MODULES; do
397 [ $m = $mod ] && have=1
399 if [ $have = 0 ]; then
400 MODULES="$MODULES $mod"
405 # install a file to temporary mount image.
406 # it will operate recursively (copying directories)
407 # and will symlink destinations if source is symlink.
409 if [ $# -lt 2 ]; then
410 die 'Usage: inst <file> [<file>] <destination>'
413 local src i=0 c=$(($# - 1))
414 while [ $i -lt $c ]; do
421 local parentDir=$(dirname $DESTDIR$dest)
422 if [ ! -d "$parentDir" ]; then
423 verbose "+ mkdir -p $parentDir"
426 verbose "+ cp $* $DESTDIR$dest"
427 cp -HR "$@" "$DESTDIR$dest"
432 die 'Usage: inst_d <destination> <destination>'
435 install -d "$DESTDIR$dir"
439 # install executable and it's shared libraries
441 if [ $# -lt 2 ]; then
442 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
444 local src i=0 c=$(($# - 1))
445 while [ $i -lt $c ]; do
458 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
462 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
464 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
466 inst_exec $lib /$_lib
471 # hack for uclibc linked binaries requiring this fixed path
472 # XXX: shouldn't rpath be used here instead so th
473 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
474 local lib=$DESTDIR/$_lib/libc.so.0
475 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
476 local libdir=$(cd $(dirname "$lib"); pwd)
477 if [ ! -e $DESTDIR$libdir ]; then
478 libdir=$(dirname "$libdir")
480 verbose "+ ln -s /$_lib $DESTDIR$libdir"
481 ln -s /$_lib $DESTDIR$libdir
486 # output modules.conf / modprobe.conf
488 echo "$modprobe_conf_cache"
491 # return options for MODULE
492 # @param $1 module name
495 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
500 # defaults to modprobe -c if not told otherwise, this means include statements
502 cache_modprobe_conf() {
503 if [ "$kernel_version" -lt "002005" ]; then
504 modulefile=/etc/modules.conf
505 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
506 modulefile=/etc/conf.modules
510 if [ -n "$modulefile" ]; then
511 debug "Using $modulefile for modules config"
512 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
515 debug "Using modprobe -c to get modules config"
516 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
520 # find modules for $devpath
521 find_modules_for_devpath() {
523 if [ -z "$devpath" ]; then
524 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
527 if [[ "$devpath" = /dev/dm-* ]]; then
528 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
529 devpath=$(dm_node "$devpath")
532 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
533 # sanitize things like:
534 # /dev/block/104:2 -> /dev/cciss/c0d0p2
535 devpath=$(readlink -f "$devpath")
538 verbose "Finding modules for device path $devpath"
540 if is_luks "$devpath"; then
541 find_modules_luks "$devpath"
545 if is_nfs "$devpath"; then
546 find_modules_nfs "$devpath"
550 if is_md "$devpath"; then
551 find_modules_md "$devpath"
555 if is_multipath "$devpath"; then
556 if find_modules_multipath "$devpath"; then
563 if is_dmraid "$devpath"; then
564 if find_modules_dmraid "$devpath"; then
570 if is_scsi "$devpath"; then
571 find_modules_scsi "$devpath"
575 if is_ide "$devpath"; then
576 find_modules_ide "$devpath"
580 if [[ "$devpath" == /dev/rd/* ]]; then
586 if [[ "$devpath" == /dev/ida/* ]]; then
587 find_module "cpqarray"
588 rootdev_add=/dev/ida/
592 if [[ "$devpath" == /dev/cciss/* ]]; then
593 rootdev_add=/dev/cciss/
595 # load hpsa for future kernels, cciss for backwards compat
596 if [ "$kernel_version_long" -ge "003000000" ]; then
597 find_module "hpsa" "-cciss"
598 find_modules_scsi "$devpath"
606 if [[ "$devpath" == /dev/ataraid/* ]]; then
608 find_module "ataraid"
609 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
610 if [ -n "$ataraidmodules" ]; then
611 # FIXME: think about modules compiled in kernel
612 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
614 for n in $ataraidmodules; do
617 rootdev_add=/dev/ataraid/
621 # check to see if we need to set up a loopback filesystem
622 if [[ "$devpath" == /dev/loop* ]]; then
623 die "Sorry, root on loop device isn't supported."
624 # TODO: rewrite for bsp and make nfs ready
625 if [ ! -x /sbin/losetup ]; then
626 die "losetup is missing"
628 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
629 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
630 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"
633 line="`awk '/'$key'/ { print $0; }' $fstab`"
634 loopDev="$(echo $line | awk '{print $3}')"
635 loopFs="$(echo $line | awk '{print $4}')"
636 loopFile="$(echo $line | awk '{print $5}')"
638 BASICMODULES="$BASICMODULES -loop"
639 find_module "-$loopFs"
640 BASICMODULES="$BASICMODULES -${loopFs}"
644 if is_lvm "$devpath"; then
645 find_modules_lvm "$devpath"
650 firmware_install_module() {
652 local firmware_files="$2"
654 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
655 # firmware not yet installed
656 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
658 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
660 echo 1 > /sys$DEVPATH/loading
661 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
662 echo 0 > /sys$DEVPATH/loading
665 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
667 # setup firmware loader agent
668 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
671 for firmware in $firmware_files; do
672 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
673 FIRMWAREDIR=${firmware%/*}
674 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
675 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
676 elif [ -f "/lib/firmware/$firmware" ]; then
677 FIRMWAREDIR=${firmware%/*}
678 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
679 inst /lib/firmware/$firmware /lib/firmware/$firmware
681 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
692 for mod in $modules; do
694 inst_d "/lib/modules/$kernel/$MODULEDIR"
695 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
696 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
697 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
698 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
703 modules_add_linuxrc() {
707 # module path without optional compression
711 local module=${modpath##*/}; module=${module%$modext}
712 local options=$(modprobe_options "$module")
713 local genericname=$(echo $module | tr - _)
714 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
715 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
717 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
718 options="scan=sync $options"
721 if [ x"$verbose" = x"-v" ]; then
723 if [ "$options" ]; then
724 s="$s with options [$options]"
726 if [ "$usleep" ]; then
727 s="$s and $usleep usleep"
729 verbose "Loading module [$module]$s"
732 if [ -n "$firmware" ]; then
733 firmware_install_module "$module" "$firmware"
735 for file in $(find_firmware "$module"); do
736 firmware_install_module "$module" "$file"
740 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
741 if [ -n "$usleep" ]; then
742 echo "usleep $usleep" | add_linuxrc
744 if [ "$module" = "scsi_wait_scan" ]; then
745 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
746 echo "rmmod scsi_wait_scan" | add_linuxrc
753 # Generates /dev nodes based on /proc/partitions information.
754 # Needs /proc mounted.
755 # Can be called multiple times.
756 initrd_gen_devices() {
757 if is_yes "$proc_partitions"; then
764 : 'Making device nodes'
765 cat /proc/partitions | (
766 # ignore first two lines: header, empty line
769 while read major minor blocks dev rest; do
772 [ -e $node ] || mknod $node b $major $minor
779 initrd_gen_setrootdev() {
780 verbose "Adding rootfs finding based on kernel cmdline root= option support."
782 debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
784 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
785 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
787 if [ -z "$rootnr" ]; then
788 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
790 if [ -n "$rootnr" ]; then
791 echo "$rootnr" > /proc/sys/kernel/real-root-dev
797 initrd_gen_initramfs_switchroot() {
799 if [ "$rootdev" = "/dev/nfs" ]; then
800 echo "rootfs on NFS root=/dev/nfs"
802 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
805 # parse 'root=xxx' kernel commandline
806 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
808 # from lilo-23.2/readme/README:
809 # root=<device> changes the root device. This overrides settings that may
810 # have been made in the boot image and on the LILO command line. <device> is
811 # either the hexadecimal device number or the full path name of the device,
814 # * The device names are hard-coded in the kernel. Therefore, only the
815 # "standard" names are supported and some less common devices may not be
816 # recognized. In those cases, only numbers can be used.
819 eval "$(busybox awk -v root="$ROOT" '
820 # http://9fans.net/archive/2006/09/261
821 function h2d(str, hstr, res, num, n, digit, i) {
822 hstr = "0123456789abdcef";
824 n = split(tolower(str), digit, "");
826 for (i = 1; i <= n; i++) {
827 num = index(hstr, digit[i]) - 1;
828 res = res + (num * 16 ^ (n - i));
835 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
836 num_pattern = "[0-9a-fA-F]" num_pattern_short;
837 dev_pattern = "[hms][a-z][a-z]([0-9])+";
841 # see if we have /dev/hdX or hdX, we can just take partition name
842 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
844 sub("^/dev/", "", partition);
848 if (root ~ "^" num_pattern_short "$") {
849 # change "303" => "0x0303"
851 } else if (root ~ "^" num_pattern "$") {
852 # change "0303" => "0x0303"
856 maj = h2d(substr(root, 3, 2));
857 min = h2d(substr(root, 5, 2));
861 partition && $4 == partition { maj = $1; min = $2; }
862 $1 == maj && $2 == min { partition = $4; }
865 if (maj >= 0 && min >= 0) {
866 printf("maj=%s; min=%s;\n", maj, min);
869 printf("device=/dev/%s;\n", partition);
874 if [ -z "$device" ]; then
878 if [ "$device" -a ! -b $device ]; then
879 mknod $device b $maj $min
882 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
884 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
886 if [ -z "$init" -o ! -x "/newroot$init" ]; then
892 busybox_applet switch_root
894 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
895 exec switch_root /newroot $init ${1:+"$@"}
897 echo "Error! initramfs should not reach this place."
898 echo "It probably means you've got old version of busybox, with broken"
899 echo "initramfs support. Trying to boot anyway, but won't promise anything."
901 exec chroot /newroot $init ${1:+"$@"}
903 echo "Failed to chroot!"
906 # we need /init being real file, not symlink, otherwise the initramfs will
907 # not be ran by pid 1 which is required for switch_root
908 mv $DESTDIR/linuxrc $DESTDIR/init
909 ln -s init $DESTDIR/linuxrc
912 # find if $symbol exists in System.map $mapfile
916 if [ ! -f $mapfile ]; then
917 # missing mapfile (not a pld kernel?)
921 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
924 # find best compressor (or forced one) for initrd
927 # fastest initrd decompression speed is first
928 local compressors='lzo gzip xz lzma bzip2'
930 # a specified one, take it
931 if ! is_yes "$mode"; then
935 verbose "finding compressor: $compressors (via $mode)"
936 # check for compressor validity
937 local c prog map=/boot/System.map-$kernel
938 for c in $compressors; do
961 # any existing sym will work
966 die "Unknown compressor $c"
969 if sym_exists $map $sym && [ -x $prog ]; then
975 verbose "using gzip for compressor (fallback)"
979 # compresses kernel image image
980 # in function so we could retry with other compressor on failure
982 local compressor="$1" IMAGE="$2" target="$3" tmp
983 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
985 case "$compressor" in
987 # don't use -9 here since kernel won't understand it
988 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
991 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
994 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
997 gzip -9 < "$IMAGE" > "$tmp" || return $?
1000 lzop -9 < "$IMAGE" > "$tmp" || return $?
1003 cat < "$IMAGE" > "$tmp" || return $?
1007 mv -f "$tmp" "$target"
1010 if [ -r /etc/sysconfig/geninitrd ]; then
1011 . /etc/sysconfig/geninitrd
1014 if [ ! -f /proc/mounts ]; then
1015 warn "/proc filesystem not mounted, may cause wrong results or failure."
1018 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1020 while [ $# -gt 0 ]; do
1030 modulefile=${1#--modules-conf=}
1039 --without-bootsplash)
1051 --without-fbcondecor)
1060 --with-suspend2 | --with-tuxonice)
1063 --without-suspend2 | --without-tuxonice)
1067 LVMTOOLSVERSION=${1#--lvmversion=}
1069 --lvmtoolsversion=*)
1070 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1072 --lvmtoolsversion|--lvmversion)
1085 --without-multipath)
1089 USE_MULTIPATH=${1#--with-multipath=}
1098 BASICMODULES="$BASICMODULES ${1#--with=}"
1101 BASICMODULES="$BASICMODULES $2"
1105 echo "$PROGRAM: version $VERSION"
1109 if [ x"$verbose" = x"-v" ]; then
1120 COMPRESS="${1#--compress=}"
1129 STRIP="${1#--strip=}"
1142 PREMODS="$PREMODS ${1#--preload=}"
1145 PREMODS="$PREMODS $2"
1149 die "--fs option is obsoleted. Use --initrdfs instead"
1152 INITRDFS=${1#--initrdfs=}
1165 if [ -z "$target" ]; then
1167 elif [ -z "$kernel" ]; then
1179 if [ -z "$target" -o -z "$kernel" ]; then
1185 if [ "$(id -u)" != 0 ]; then
1186 die "You need to be root to generate initrd"
1189 if [ -d /lib64 -a -d /usr/lib64 ]; then
1195 initrd_dir=/usr/$_lib/initrd
1196 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1197 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1199 verbose "# $GENINITRD_RCSID (geninitrd)"
1200 debug "Using _lib: $_lib"
1201 debug "Using initrd_dir: $initrd_dir"
1203 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1205 # we setup mods after parsing command line args
1206 geninitrd_setup_mods
1208 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1209 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1212 if [ -z "$INITRDFS" ]; then
1213 if [ -n "$FS" ]; then
1214 # FS= can came only via /etc/sysconfig/geninitrd likely?
1215 die "FS configuration option is obsoleted. Use INITRDFS instead"
1219 if [ "$kernel_version" -ge "002005" ]; then
1220 INITRDFS="initramfs"
1228 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1231 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1234 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1237 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1238 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1241 die "Filesystem $INITRDFS on initrd is not supported"
1245 if [ -L "$target" ]; then
1246 target=$(readlink -f "$target")
1249 if [ -n "$img_vers" ]; then
1250 target="$target-$kernel"
1253 if [ -z "$force" -a -f "$target" ]; then
1254 die "$target already exists."
1257 if [ ! -d "/lib/modules/$kernel" ]; then
1258 die "/lib/modules/$kernel is not a directory."
1261 if [ "$kernel_version" -ge "002005" ]; then
1267 for n in $PREMODS; do
1271 if [ "$FBMODULE" ]; then
1272 find_module "$FBMODULE"
1275 # autodetect USB keyboards
1278 # allow forcing loading SCSI and/or IDE modules
1279 # XXX: where ADDSCSI cames from? drop?
1280 if is_yes "$ADDSCSI"; then
1284 # autodetect SATA modules
1287 # XXX: where ADDIDE cames from? drop?
1288 if is_yes "$ADDIDE"; then
1292 if is_yes "$USE_SUSPEND"; then
1293 find_modules_suspend
1296 find_root "$fstab" || exit
1297 verbose "Using $rootdev as device for rootfs"
1299 find_modules_for_devpath "$rootdev"
1301 # if USE_MULTIPATH is path to device, scan that too
1302 # this is to bootstrap multipath setup into initrd.
1303 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1304 find_modules_multipath $USE_MULTIPATH
1307 find_module "-$rootFs"
1309 for n in $BASICMODULES; do
1313 if is_yes "$USE_TUXONICE"; then
1317 find_modules_fbsplash
1319 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1320 verbose "No modules are needed -- not building initrd image."
1324 verbose "Building initrd..."
1325 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1326 RCFILE="$DESTDIR/linuxrc"
1328 chmod a+rx "$RCFILE"
1329 ln -s linuxrc $DESTDIR/init
1331 # create dirs that we really need
1332 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1334 modules_install "$MODULES"
1336 # mknod'ing the devices instead of copying them works both with and
1338 mknod "$DESTDIR/dev/console" c 5 1
1339 mknod "$DESTDIR/dev/null" c 1 3
1340 mknod "$DESTDIR/dev/zero" c 1 5
1341 mknod "$DESTDIR/dev/random" c 1 8
1342 mknod "$DESTDIR/dev/urandom" c 1 9
1344 inst_exec $busybox /bin/busybox
1345 ln -s busybox $DESTDIR/bin/sh
1346 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1347 ln -s busybox $DESTDIR/bin/initrd-busybox
1351 # initrd generated by:
1357 # builtin defaults from geninitrd
1361 add_linuxrc <<-'EOF'
1362 read CMDLINE < /proc/cmdline
1364 for arg in $CMDLINE; do
1365 if [ "${arg}" = "debuginitrd" ]; then
1368 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1369 DEBUGINITRD=${arg##debuginitrd=}
1371 if [ "${arg##root=}" != "${arg}" ]; then
1374 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1375 ROOTFSFLAGS=${arg##rootfsflags=}
1377 if [ "${arg##init=}" != "${arg}" ]; then
1382 if [ "$DEBUGINITRD" = "sh" ]; then
1383 # export some vars for subshell debug to work
1384 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1385 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1386 export rootnr attrs majmin major minor device
1388 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1391 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1392 add_linuxrc <<-'EOF'
1393 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1396 add_linuxrc <<-'EOF'
1400 add_linuxrc <<-'EOF'
1408 if [ "$DEBUGINITRD" ]; then
1413 modules_add_linuxrc $MODULES
1415 # TODO: rewrite for busybox
1416 #if [ -n "$loopDev" ]; then
1417 # if [ ! -d /initrd ]; then
1421 # cp -a "$loopDev" "$DESTDIR/dev"
1422 # cp -a "$rootdev" "$DESTDIR/dev"
1423 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1424 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1425 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1426 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1429 if is_yes "$USE_UDEV"; then
1435 find_modules_uvesafb
1440 initrd_gen_multipath
1443 if is_yes "$have_nfs"; then
1449 initrd_gen_setrootdev
1455 # additional devs always needed
1456 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1458 initrd_gen_stop_udevd
1459 initrd_gen_stop_mdev
1460 initrd_gen_stop_uvesafb
1463 add_linuxrc <<-'EOF'
1464 if [ ! "$DEBUGINITRD" ]; then
1468 for i in $(export -p); do
1469 i=${i#declare -x } # ksh/bash
1470 i=${i#export } # busybox
1481 [ -z "$i" ] && continue
1484 ROOT|PATH|HOME|TERM)
1496 if [ "$INITRDFS" = "initramfs" ]; then
1497 initrd_gen_initramfs_switchroot
1503 initrd_gen_fbcondecor
1505 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1507 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1509 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1510 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1512 verbose "Creating $INITRDFS image $IMAGE"
1515 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1516 # NOTE: ext2 label is max 16 chars
1517 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1518 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1520 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1521 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1522 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1523 # We don't need this directory, so let's save space
1524 rm -rf "$tmpmnt"/lost+found
1526 debug "Copy recursively $DESTDIR -> $tmpmnt"
1527 cp -a $DESTDIR/* $tmpmnt
1533 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1536 mkcramfs "$DESTDIR" "$IMAGE"
1539 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1542 die "Filesystem $INITRDFS not supported by $PROGRAM"
1545 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1546 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1547 CONFIG_BLK_DEV_RAM_SIZE=4096
1548 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1551 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1552 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1555 if ! is_no "$COMPRESS"; then
1556 compressor=$(find_compressor "$COMPRESS")
1557 verbose "Compressing $target with $compressor"
1559 # TODO: the image name (specified from kernel.spec) already contains
1560 # extension, which is .gz most of the time.
1561 compress_image "$compressor" "$IMAGE" "$target" || {
1562 if [ $compressor != gzip ]; then
1563 warn "Could not compress with $compressor, retrying with gzip"
1564 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1566 die "Could not compress image with $compressor"
1570 cp -a "$IMAGE" "$target"
1573 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1574 initrd_gen_bootsplash "$target"
1576 rm -rf "$DESTDIR" "$IMAGE"
1578 # vim:ts=4:sw=4:noet:fdm=marker