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
244 # try to move pseudo filesystems to newroot if possible
248 : Last shell before umounting all and giving control over to real init.
252 if is_yes "$run_mounted"; then
254 mount --bind /run /newroot/run
259 if is_yes "$dev_mounted"; then
261 mount --bind /dev /newroot/dev
266 if is_yes "$sys_mounted"; then
268 mount --bind /sys /newroot/sys
273 if is_yes "$proc_mounted"; then
275 mount --bind /proc /newroot/proc
280 if is_yes "$tmp_mounted"; then
281 echo 'umount /tmp' | add_linuxrc
286 # Checks if busybox has support for APPLET(s)
287 # Exits from geninitrd if the support is not present.
289 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
293 if [ -z "$busybox_functions" ]; then
294 local tmp=$($busybox 2>&1)
296 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
297 if [[ "$tmp" = *applet\ not\ found* ]]; then
299 ln -s $busybox $t/busybox
300 local tmp=$($t/busybox 2>&1)
304 busybox_functions=$(echo "$tmp" | \
305 sed -ne '/Currently defined functions:/,$p' | \
306 xargs | sed -e 's,.*Currently defined functions: ,,'
312 eval have='$'busybox_have_$applet
313 if [ -z "$have" ]; then
314 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
315 if [ "$have" = 0 ]; then
316 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
319 eval busybox_have_$applet=$have
322 if [ $err = 1 ]; then
327 # Extract the .config file from a kernel image
328 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
330 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
331 if [ -n "$kofile" ]; then
332 /lib/geninitrd/extract-ikconfig $kofile
336 # see if config available as separate file
337 if [ -f /boot/config-$kernel ]; then
338 cat /boot/config-$kernel
342 # finally try vmlinuz itself
343 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
351 module=${module%$modext*}
355 # Finds module dependencies
359 # Outputs full path to module and it's dependencies
364 # if module is prefixed with dash, we should ignore errors if the module
366 if [ ${module#-} != $module ]; then
371 # This works when user has module-init-tools installed even on 2.4 kernels
373 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
376 if [ $skiperrors = 1 ]; then
381 if ! is_no "$EXIT_IF_MISSING"; then
382 die "$module: module not found for $kernel kernel"
385 warn "$module: module not found for $kernel kernel"
386 warn "If $module isn't compiled in kernel then this initrd may not start your system."
392 while read insmod modpath options; do
393 if [ "$insmod" = "insmod" ]; then
395 # XXX: find a away to autodetect
396 smodule=$(basename_module $modpath)
399 find_depmod "-crct10dif-pclmul"
400 find_depmod "-crct10dif"
403 find_depmod "-crc32c-intel"
404 find_depmod "-crc32c"
406 virtio_blk|virtio_scsi)
407 find_depmod "-virtio_pci"
408 find_depmod "-virtio_mmio"
421 # no firmware support in 2.4 kernels
422 if [ "$kernel_version_long" -lt "002005048" ]; then
425 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
430 local mod depmod module=$1
432 depmod=$(find_depmod $module) || exit 1
433 for mod in $depmod; do
434 mod=${mod#/lib/modules/$kernel/}
436 # add each module only once
438 for m in $MODULES; do
439 [ $m = $mod ] && have=1
441 if [ $have = 0 ]; then
442 MODULES="$MODULES $mod"
447 # install a file to temporary mount image.
448 # it will operate recursively (copying directories)
449 # and will symlink destinations if source is symlink.
451 if [ $# -lt 2 ]; then
452 die 'Usage: inst <file> [<file>] <destination>'
455 local src i=0 c=$(($# - 1))
456 while [ $i -lt $c ]; do
463 local parentDir=$(dirname $DESTDIR$dest)
464 if [ ! -d "$parentDir" ]; then
465 verbose "+ mkdir -p $parentDir"
468 verbose "+ cp $* $DESTDIR$dest"
469 cp -HR "$@" "$DESTDIR$dest"
474 die 'Usage: inst_d <destination> <destination>'
477 install -d "$DESTDIR$dir"
481 # install executable and it's shared libraries
483 if [ $# -lt 2 ]; then
484 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
486 local src i=0 c=$(($# - 1))
487 while [ $i -lt $c ]; do
500 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
504 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
506 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
508 inst_exec $lib /$_lib
513 # hack for uclibc linked binaries requiring this fixed path
514 # XXX: shouldn't rpath be used here instead so th
515 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
516 local lib=$DESTDIR/$_lib/libc.so.0
517 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
518 local libdir=$(cd $(dirname "$lib"); pwd)
519 if [ ! -e $DESTDIR$libdir ]; then
520 libdir=$(dirname "$libdir")
522 verbose "+ ln -s /$_lib $DESTDIR$libdir"
523 ln -s /$_lib $DESTDIR$libdir
528 # output modules.conf / modprobe.conf
530 echo "$modprobe_conf_cache"
533 # return options for MODULE
534 # @param $1 module name
537 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
542 # defaults to modprobe -c if not told otherwise, this means include statements
544 cache_modprobe_conf() {
545 if [ "$kernel_version" -lt "002005" ]; then
546 modulefile=/etc/modules.conf
547 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
548 modulefile=/etc/conf.modules
552 if [ -n "$modulefile" ]; then
553 debug "Using $modulefile for modules config"
554 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
557 debug "Using modprobe -c to get modules config"
558 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
562 # find modules for $devpath
563 find_modules_for_devpath() {
565 if [ -z "$devpath" ]; then
566 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
569 if [[ "$devpath" = /dev/dm-* ]]; then
570 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
571 devpath=$(dm_node "$devpath")
574 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
575 # sanitize things like:
576 # /dev/block/104:2 -> /dev/cciss/c0d0p2
577 devpath=$(readlink -f "$devpath")
580 verbose "Finding modules for device path $devpath"
582 if is_luks "$devpath"; then
583 find_modules_luks "$devpath"
587 if is_nfs "$devpath"; then
588 find_modules_nfs "$devpath"
592 if is_md "$devpath"; then
593 find_modules_md "$devpath"
597 if is_multipath "$devpath"; then
598 if find_modules_multipath "$devpath"; then
605 if is_dmraid "$devpath"; then
606 if find_modules_dmraid "$devpath"; then
612 if is_scsi "$devpath"; then
613 find_modules_scsi "$devpath"
617 if is_ide "$devpath"; then
618 find_modules_ide "$devpath"
622 if [[ "$devpath" == /dev/rd/* ]]; then
628 if [[ "$devpath" == /dev/ida/* ]]; then
629 find_module "cpqarray"
630 rootdev_add=/dev/ida/
634 if [[ "$devpath" == /dev/cciss/* ]]; then
635 rootdev_add=/dev/cciss/
637 # load hpsa for future kernels, cciss for backwards compat
638 if [ "$kernel_version_long" -ge "003000000" ]; then
639 find_module "hpsa" "-cciss"
640 find_modules_scsi "$devpath"
648 if [[ "$devpath" == /dev/ataraid/* ]]; then
650 find_module "ataraid"
651 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
652 if [ -n "$ataraidmodules" ]; then
653 # FIXME: think about modules compiled in kernel
654 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
656 for n in $ataraidmodules; do
659 rootdev_add=/dev/ataraid/
663 # check to see if we need to set up a loopback filesystem
664 if [[ "$devpath" == /dev/loop* ]]; then
665 die "Sorry, root on loop device isn't supported."
666 # TODO: rewrite for bsp and make nfs ready
667 if [ ! -x /sbin/losetup ]; then
668 die "losetup is missing"
670 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
671 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
672 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"
675 line="`awk '/'$key'/ { print $0; }' $fstab`"
676 loopDev="$(echo $line | awk '{print $3}')"
677 loopFs="$(echo $line | awk '{print $4}')"
678 loopFile="$(echo $line | awk '{print $5}')"
680 BASICMODULES="$BASICMODULES -loop"
681 find_module "-$loopFs"
682 BASICMODULES="$BASICMODULES -${loopFs}"
686 if is_lvm "$devpath"; then
687 find_modules_lvm "$devpath"
692 firmware_install_module() {
694 local firmware_files="$2"
696 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
697 # firmware not yet installed
698 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
700 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
702 echo 1 > /sys$DEVPATH/loading
703 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
704 echo 0 > /sys$DEVPATH/loading
707 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
709 # setup firmware loader agent
710 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
713 for firmware in $firmware_files; do
714 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
715 FIRMWAREDIR=${firmware%/*}
716 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
717 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
718 elif [ -f "/lib/firmware/$firmware" ]; then
719 FIRMWAREDIR=${firmware%/*}
720 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
721 inst /lib/firmware/$firmware /lib/firmware/$firmware
723 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
734 for mod in $modules; do
736 inst_d "/lib/modules/$kernel/$MODULEDIR"
737 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
738 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
739 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
740 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
745 modules_add_linuxrc() {
749 # module path without optional compression
753 local module=${modpath##*/}; module=${module%$modext}
754 local options=$(modprobe_options "$module")
755 local genericname=$(echo $module | tr - _)
756 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
757 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
759 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
760 options="scan=sync $options"
763 if [ x"$verbose" = x"-v" ]; then
765 if [ "$options" ]; then
766 s="$s with options [$options]"
768 if [ "$usleep" ]; then
769 s="$s and $usleep usleep"
771 verbose "Loading module [$module]$s"
774 if [ -n "$firmware" ]; then
775 firmware_install_module "$module" "$firmware"
777 for file in $(find_firmware "$module"); do
778 firmware_install_module "$module" "$file"
782 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
783 if [ -n "$usleep" ]; then
784 echo "usleep $usleep" | add_linuxrc
786 if [ "$module" = "scsi_wait_scan" ]; then
787 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
788 echo "rmmod scsi_wait_scan" | add_linuxrc
795 # Generates /dev nodes based on /proc/partitions information.
796 # Needs /proc mounted.
797 # Can be called multiple times.
798 initrd_gen_devices() {
799 if is_yes "$proc_partitions"; then
806 : 'Making device nodes'
807 cat /proc/partitions | (
808 # ignore first two lines: header, empty line
811 while read major minor blocks dev rest; do
814 [ -e $node ] || mknod -m 660 $node b $major $minor
821 initrd_gen_setrootdev() {
822 verbose "Adding rootfs finding based on kernel cmdline root= option support."
824 debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
826 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
827 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
829 if [ -z "$rootnr" ]; then
830 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
832 if [ -n "$rootnr" ]; then
833 echo "$rootnr" > /proc/sys/kernel/real-root-dev
839 initrd_gen_initramfs_switchroot() {
841 if [ "$rootdev" = "/dev/nfs" ]; then
842 echo "rootfs on NFS root=/dev/nfs"
844 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
847 # parse 'root=xxx' kernel commandline
848 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
850 # from lilo-23.2/readme/README:
851 # root=<device> changes the root device. This overrides settings that may
852 # have been made in the boot image and on the LILO command line. <device> is
853 # either the hexadecimal device number or the full path name of the device,
856 # * The device names are hard-coded in the kernel. Therefore, only the
857 # "standard" names are supported and some less common devices may not be
858 # recognized. In those cases, only numbers can be used.
862 eval "$(busybox awk -v root="$ROOT" '
863 # http://9fans.net/archive/2006/09/261
864 function h2d(str, hstr, res, num, n, digit, i) {
865 hstr = "0123456789abdcef";
867 n = split(tolower(str), digit, "");
869 for (i = 1; i <= n; i++) {
870 num = index(hstr, digit[i]) - 1;
871 res = res + (num * 16 ^ (n - i));
878 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
879 num_pattern = "[0-9a-fA-F]" num_pattern_short;
880 dev_pattern = "[hms][a-z][a-z]([0-9])+";
884 # see if we have /dev/hdX or hdX, we can just take partition name
885 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
887 sub("^/dev/", "", partition);
891 if (root ~ "^" num_pattern_short "$") {
892 # change "303" => "0x0303"
894 } else if (root ~ "^" num_pattern "$") {
895 # change "0303" => "0x0303"
899 maj = h2d(substr(root, 3, 2));
900 min = h2d(substr(root, 5, 2));
904 partition && $4 == partition { maj = $1; min = $2; }
905 $1 == maj && $2 == min { partition = $4; }
908 if (maj >= 0 && min >= 0) {
909 printf("maj=%s; min=%s;\n", maj, min);
912 printf("device=/dev/%s;\n", partition);
917 if [ -z "$device" ]; then
918 if [ "$DEBUGINITRD" ]; then
924 if [ "$device" -a ! -b $device ]; then
925 mknod -m 660 $device b $maj $min
928 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
930 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
932 if [ -z "$init" -o ! -x "/newroot$init" ]; then
940 if [ "$DEBUGINITRD" ]; then
941 echo "Last 20 lines of dmesg:"
947 busybox_applet switch_root
949 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
950 exec switch_root /newroot $init ${1:+"$@"}
952 echo "Error! initramfs should not reach this place."
953 echo "It probably means you've got old version of busybox, with broken"
954 echo "initramfs support. Trying to boot anyway, but won't promise anything."
956 exec chroot /newroot $init ${1:+"$@"}
958 echo "Failed to chroot!"
961 # we need /init being real file, not symlink, otherwise the initramfs will
962 # not be ran by pid 1 which is required for switch_root
963 mv $DESTDIR/linuxrc $DESTDIR/init
964 ln -s init $DESTDIR/linuxrc
967 # find if $symbol exists in System.map $mapfile
971 if [ ! -f $mapfile ]; then
972 # missing mapfile (not a pld kernel?)
976 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
979 # find best compressor (or forced one) for initrd
982 # fastest initrd decompression speed is first
983 local compressors='lzo gzip xz lzma bzip2'
985 # a specified one, take it
986 if ! is_yes "$mode"; then
990 verbose "finding compressor: $compressors (via $mode)"
991 # check for compressor validity
992 local c prog map=/boot/System.map-$kernel
993 for c in $compressors; do
1016 # any existing sym will work
1021 die "Unknown compressor $c"
1024 if sym_exists $map $sym && [ -x $prog ]; then
1030 verbose "using gzip for compressor (fallback)"
1034 # compresses kernel image image
1035 # in function so we could retry with other compressor on failure
1037 local compressor="$1" IMAGE="$2" target="$3" tmp
1038 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1040 case "$compressor" in
1042 # don't use -9 here since kernel won't understand it
1043 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1046 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1049 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1052 gzip -9 < "$IMAGE" > "$tmp" || return $?
1055 lzop -9 < "$IMAGE" > "$tmp" || return $?
1058 cat < "$IMAGE" > "$tmp" || return $?
1062 mv -f "$tmp" "$target"
1065 if [ -r /etc/sysconfig/geninitrd ]; then
1066 . /etc/sysconfig/geninitrd
1069 if [ ! -f /proc/mounts ]; then
1070 warn "/proc filesystem not mounted, may cause wrong results or failure."
1073 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1075 while [ $# -gt 0 ]; do
1085 modulefile=${1#--modules-conf=}
1094 --without-bootsplash)
1106 --without-fbcondecor)
1115 --with-suspend2 | --with-tuxonice)
1118 --without-suspend2 | --without-tuxonice)
1122 LVMTOOLSVERSION=${1#--lvmversion=}
1124 --lvmtoolsversion=*)
1125 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1127 --lvmtoolsversion|--lvmversion)
1140 --without-multipath)
1144 USE_MULTIPATH=${1#--with-multipath=}
1153 BASICMODULES="$BASICMODULES ${1#--with=}"
1156 BASICMODULES="$BASICMODULES $2"
1160 echo "$PROGRAM: version $VERSION"
1164 if [ x"$verbose" = x"-v" ]; then
1175 COMPRESS="${1#--compress=}"
1184 STRIP="${1#--strip=}"
1197 PREMODS="$PREMODS ${1#--preload=}"
1200 PREMODS="$PREMODS $2"
1204 die "--fs option is obsoleted. Use --initrdfs instead"
1207 INITRDFS=${1#--initrdfs=}
1220 if [ -z "$target" ]; then
1222 elif [ -z "$kernel" ]; then
1234 if [ -z "$target" -o -z "$kernel" ]; then
1240 if [ "$(id -u)" != 0 ]; then
1241 die "You need to be root to generate initrd"
1244 if [ -d /lib64 -a -d /usr/lib64 ]; then
1250 initrd_dir=/usr/$_lib/initrd
1251 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1252 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1254 verbose "# $GENINITRD_RCSID (geninitrd)"
1255 debug "Using _lib: $_lib"
1256 debug "Using initrd_dir: $initrd_dir"
1258 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1260 # we setup mods after parsing command line args
1261 geninitrd_setup_mods
1263 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1264 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1267 if [ -z "$INITRDFS" ]; then
1268 if [ -n "$FS" ]; then
1269 # FS= can came only via /etc/sysconfig/geninitrd likely?
1270 die "FS configuration option is obsoleted. Use INITRDFS instead"
1274 if [ "$kernel_version" -ge "002005" ]; then
1275 INITRDFS="initramfs"
1283 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1286 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1289 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1292 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1293 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1296 die "Filesystem $INITRDFS on initrd is not supported"
1300 if [ -L "$target" ]; then
1301 target=$(readlink -f "$target")
1304 if [ -n "$img_vers" ]; then
1305 target="$target-$kernel"
1308 if [ -z "$force" -a -f "$target" ]; then
1309 die "$target already exists."
1312 if [ ! -d "/lib/modules/$kernel" ]; then
1313 die "/lib/modules/$kernel is not a directory."
1316 if [ "$kernel_version" -ge "002005" ]; then
1322 for n in $PREMODS; do
1326 if [ "$FBMODULE" ]; then
1327 find_module "$FBMODULE"
1330 # autodetect USB keyboards
1333 # allow forcing loading SCSI and/or IDE modules
1334 # XXX: where ADDSCSI cames from? drop?
1335 if is_yes "$ADDSCSI"; then
1339 # autodetect SATA modules
1342 # XXX: where ADDIDE cames from? drop?
1343 if is_yes "$ADDIDE"; then
1347 if is_yes "$USE_SUSPEND"; then
1348 find_modules_suspend
1351 find_root "$fstab" || exit
1352 verbose "Using $rootdev as device for rootfs"
1354 find_modules_for_devpath "$rootdev"
1356 # if USE_MULTIPATH is path to device, scan that too
1357 # this is to bootstrap multipath setup into initrd.
1358 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1359 find_modules_multipath $USE_MULTIPATH
1362 find_module "-$rootFs"
1364 for n in $BASICMODULES; do
1368 if is_yes "$USE_TUXONICE"; then
1372 find_modules_fbsplash
1374 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1375 verbose "No modules are needed -- not building initrd image."
1379 verbose "Building initrd..."
1380 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1381 RCFILE="$DESTDIR/linuxrc"
1383 chmod a+rx "$RCFILE"
1384 ln -s linuxrc $DESTDIR/init
1386 # create dirs that we really need
1387 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1389 modules_install "$MODULES"
1391 # mknod'ing the devices instead of copying them works both with and
1393 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1394 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1395 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1396 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1397 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1399 inst_exec $busybox /bin/busybox
1400 ln -s busybox $DESTDIR/bin/sh
1401 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1402 ln -s busybox $DESTDIR/bin/initrd-busybox
1407 # on $(LC_ALL=C date)
1408 # by $GENINITRD_RCSID
1413 # builtin defaults from geninitrd
1417 add_linuxrc <<-'EOF'
1418 read CMDLINE < /proc/cmdline
1420 for arg in $CMDLINE; do
1421 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1424 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1425 DEBUGINITRD=${arg##debug*rd=}
1427 if [ "${arg##root=}" != "${arg}" ]; then
1430 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1431 ROOTFSFLAGS=${arg##rootfsflags=}
1433 if [ "${arg##init=}" != "${arg}" ]; then
1438 if [ "$DEBUGINITRD" = "sh" ]; then
1439 # export some vars to subshell for debug to work
1440 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1441 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1442 export rootnr attrs majmin major minor device
1444 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1447 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1448 add_linuxrc <<-'EOF'
1449 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1452 add_linuxrc <<-'EOF'
1456 add_linuxrc <<-'EOF'
1464 if [ "$DEBUGINITRD" ]; then
1469 modules_add_linuxrc $MODULES
1471 # TODO: rewrite for busybox
1472 #if [ -n "$loopDev" ]; then
1473 # if [ ! -d /initrd ]; then
1477 # cp -a "$loopDev" "$DESTDIR/dev"
1478 # cp -a "$rootdev" "$DESTDIR/dev"
1479 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1480 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1481 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1482 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1485 if is_yes "$USE_UDEV"; then
1491 find_modules_uvesafb
1496 initrd_gen_multipath
1499 if is_yes "$have_nfs"; then
1506 initrd_gen_setrootdev
1509 # additional devs always needed
1510 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1512 initrd_gen_stop_udevd
1513 initrd_gen_stop_mdev
1514 initrd_gen_stop_uvesafb
1516 # resume after killing local processes
1521 add_linuxrc <<-'EOF'
1522 if [ ! "$DEBUGINITRD" ]; then
1526 for i in $(export -p); do
1527 i=${i#declare -x } # ksh/bash
1528 i=${i#export } # busybox
1539 [ -z "$i" ] && continue
1542 ROOT|PATH|HOME|TERM)
1554 if [ "$INITRDFS" = "initramfs" ]; then
1555 initrd_gen_initramfs_switchroot
1561 initrd_gen_fbcondecor
1563 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1565 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1567 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1568 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1570 verbose "Creating $INITRDFS image $IMAGE"
1573 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1574 # NOTE: ext2 label is max 16 chars
1575 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1576 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1578 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1579 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1580 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1581 # We don't need this directory, so let's save space
1582 rm -rf "$tmpmnt"/lost+found
1584 debug "Copy recursively $DESTDIR -> $tmpmnt"
1585 cp -a $DESTDIR/* $tmpmnt
1591 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1594 mkcramfs "$DESTDIR" "$IMAGE"
1597 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1600 die "Filesystem $INITRDFS not supported by $PROGRAM"
1603 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1604 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1605 CONFIG_BLK_DEV_RAM_SIZE=4096
1606 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1609 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1610 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1613 if ! is_no "$COMPRESS"; then
1614 compressor=$(find_compressor "$COMPRESS")
1615 verbose "Compressing $target with $compressor"
1617 # TODO: the image name (specified from kernel.spec) already contains
1618 # extension, which is .gz most of the time.
1619 compress_image "$compressor" "$IMAGE" "$target" || {
1620 if [ $compressor != gzip ]; then
1621 warn "Could not compress with $compressor, retrying with gzip"
1622 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1624 die "Could not compress image with $compressor"
1628 cp -a "$IMAGE" "$target"
1631 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1632 initrd_gen_bootsplash "$target"
1634 rm -rf "$DESTDIR" "$IMAGE"
1636 # vim:ts=4:sw=4:noet:fdm=marker