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
86 # aborts program abnormally
93 # find program from specified paths
99 debug "find_tool: found $x"
103 debug "find_tool: did not find 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 # we already generated tmpfs code; return
146 if is_yes "$dev_mounted"; then
152 busybox_applet mount mknod mkdir
155 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
156 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
157 mknod /dev/console c 5 1
158 mknod /dev/null c 1 3
159 mknod /dev/zero c 1 5
160 mknod /dev/random c 1 8
161 mknod /dev/snapshot c 10 231
162 mknod /dev/urandom c 1 9
163 mknod /dev/ptmx c 5 2
164 mknod /dev/kmsg c 1 11
171 # generate code to mount /proc on initrd
172 # can be called multiple times
174 if is_yes "$proc_mounted"; then
179 if [ "$INITRDFS" = "initramfs" ]; then
180 # /proc is mounted with initramfs 2.6.22.14 kernel
181 # XXX: remove when it is clear why proc was already mounted
182 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
184 echo "mount -t proc none /proc" | add_linuxrc
188 # generate code to mount /sys on initrd
189 # can be called multiple times
191 if is_yes "$sys_mounted"; then
196 echo "mount -t sysfs none /sys" | add_linuxrc
199 # generate code to mount /tmp on initrd
200 # can be called multiple times
202 if [ "$INITRDFS" = "initramfs" ]; then
203 # initramfs is read-write filesystem, no need for tmpfs
207 if is_yes "$tmp_mounted"; then
212 echo "mount -t tmpfs none /tmp" | add_linuxrc
215 # generate code to mount /run on initrd
216 # can be called multiple times
218 if is_yes "$run_mounted"; then
223 echo "mount -t tmpfs run /run" | add_linuxrc
226 # unmount all mountpoints mounted by geninitrd
230 : Last shell before umounting all and giving control over to real init.
234 if is_yes "$run_mounted"; then
235 echo 'mount --bind /run /newroot/run' | add_linuxrc
236 echo 'umount /run' | add_linuxrc
239 if is_yes "$dev_mounted"; then
240 echo 'umount /dev' | add_linuxrc
243 if is_yes "$sys_mounted"; then
244 echo 'umount /sys' | add_linuxrc
247 if is_yes "$tmp_mounted"; then
248 echo 'umount /tmp' | add_linuxrc
251 if is_yes "$proc_mounted"; then
252 echo 'umount /proc' | add_linuxrc
258 # Checks if busybox has support for APPLET(s)
259 # Exits from geninitrd if the support is not present.
261 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
265 if [ -z "$busybox_functions" ]; then
266 local tmp=$($busybox 2>&1)
268 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
269 if [[ "$tmp" = *applet\ not\ found* ]]; then
271 ln -s $busybox $t/busybox
272 local tmp=$($t/busybox 2>&1)
276 busybox_functions=$(echo "$tmp" | \
277 sed -ne '/Currently defined functions:/,$p' | \
278 xargs | sed -e 's,.*Currently defined functions: ,,'
284 eval have='$'busybox_have_$applet
285 if [ -z "$have" ]; then
286 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
287 if [ "$have" = 0 ]; then
288 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
291 eval busybox_have_$applet=$have
294 if [ $err = 1 ]; then
299 # Extract the .config file from a kernel image
300 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
302 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
303 if [ -n "$kofile" ]; then
304 /lib/geninitrd/extract-ikconfig $kofile
308 # see if config available as separate file
309 if [ -f /boot/config-$kernel ]; then
310 cat /boot/config-$kernel
314 # finally try vmlinuz itself
315 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
318 # Finds module dependencies
322 # Outputs full path to module and it's dependencies
327 # if module is prefixed with dash, we should ignore errors if the module
329 if [ ${module#-} != $module ]; then
334 # This works when user has module-init-tools installed even on 2.4 kernels
336 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
339 if [ $skiperrors = 1 ]; then
344 if ! is_no "$EXIT_IF_MISSING"; then
345 die "$module: module not found for $kernel kernel"
348 warn "$module: module not found for $kernel kernel"
349 warn "If $module isn't compiled in kernel then this initrd may not start your system."
353 while read insmod modpath options; do
354 [ "$insmod" = "insmod" ] && echo $modpath
362 # no firmware support in 2.4 kernels
363 if [ "$kernel_version_long" -lt "002005048" ]; then
366 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
371 local mod depmod module=$1
373 depmod=$(find_depmod $module) || exit 1
374 for mod in $depmod; do
375 mod=${mod#/lib/modules/$kernel/}
377 # add each module only once
379 for m in $MODULES; do
380 [ $m = $mod ] && have=1
382 if [ $have = 0 ]; then
383 MODULES="$MODULES $mod"
388 # install a file to temporary mount image.
389 # it will operate recursively (copying directories)
390 # and will symlink destinations if source is symlink.
392 if [ $# -lt 2 ]; then
393 die 'Usage: inst <file> [<file>] <destination>'
396 local src i=0 c=$(($# - 1))
397 while [ $i -lt $c ]; do
404 local parentDir=$(dirname $DESTDIR$dest)
405 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
406 debug "+ cp $* $DESTDIR$dest"
407 cp -HR "$@" "$DESTDIR$dest"
412 die 'Usage: inst_d <destination> <destination>'
415 install -d "$DESTDIR$dir"
419 # install executable and it's shared libraries
421 if [ $# -lt 2 ]; then
422 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
424 local src i=0 c=$(($# - 1))
425 while [ $i -lt $c ]; do
438 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
442 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
444 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
446 inst_exec $lib /$_lib
451 # hack for uclibc linked binaries requiring this fixed path
452 # XXX: shouldn't rpath be used here instead so th
453 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
454 local lib=$DESTDIR/$_lib/libc.so.0
455 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
456 local libdir=$(cd $(dirname "$lib"); pwd)
457 if [ ! -e $DESTDIR$libdir ]; then
458 libdir=$(dirname "$libdir")
460 debug "+ ln -s /$_lib $DESTDIR$libdir"
461 ln -s /$_lib $DESTDIR$libdir
466 # output modules.conf / modprobe.conf
468 echo "$modprobe_conf_cache"
471 # return options for MODULE
472 # @param $1 module name
475 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
480 # defaults to modprobe -c if not told otherwise, this means include statements
482 cache_modprobe_conf() {
483 if [ "$kernel_version" -lt "002005" ]; then
484 modulefile=/etc/modules.conf
485 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
486 modulefile=/etc/conf.modules
490 if [ -n "$modulefile" ]; then
491 debug "Using $modulefile for modules config"
492 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
495 debug "Using modprobe -c to get modules config"
496 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
500 # find modules for $devpath
501 find_modules_for_devpath() {
503 if [ -z "$devpath" ]; then
504 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
507 if [[ "$devpath" = /dev/dm-* ]]; then
508 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
509 devpath=$(dm_node "$devpath")
512 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
513 # sanitize things like:
514 # /dev/block/104:2 -> /dev/cciss/c0d0p2
515 devpath=$(readlink -f "$devpath")
518 debug "Finding modules for device path $devpath"
520 if is_luks "$devpath"; then
521 find_modules_luks "$devpath"
525 if is_nfs "$devpath"; then
526 find_modules_nfs "$devpath"
530 if is_md "$devpath"; then
531 find_modules_md "$devpath"
535 if is_multipath "$devpath"; then
536 if find_modules_multipath "$devpath"; then
543 if is_dmraid "$devpath"; then
544 if find_modules_dmraid "$devpath"; then
550 if is_scsi "$devpath"; then
551 find_modules_scsi "$devpath"
555 if is_ide "$devpath"; then
556 find_modules_ide "$devpath"
560 if [[ "$devpath" == /dev/rd/* ]]; then
566 if [[ "$devpath" == /dev/ida/* ]]; then
567 find_module "cpqarray"
568 rootdev_add=/dev/ida/
572 if [[ "$devpath" == /dev/cciss/* ]]; then
573 rootdev_add=/dev/cciss/
575 # load hpsa for future kernels, cciss for backwards compat
576 if [ "$kernel_version_long" -ge "003000000" ]; then
577 find_module "hpsa" "-cciss"
578 find_modules_scsi "$devpath"
586 if [[ "$devpath" == /dev/ataraid/* ]]; then
588 find_module "ataraid"
589 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
590 if [ -n "$ataraidmodules" ]; then
591 # FIXME: think about modules compiled in kernel
592 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
594 for n in $ataraidmodules; do
597 rootdev_add=/dev/ataraid/
601 # check to see if we need to set up a loopback filesystem
602 if [[ "$devpath" == /dev/loop* ]]; then
603 die "Sorry, root on loop device isn't supported."
604 # TODO: rewrite for bsp and make nfs ready
605 if [ ! -x /sbin/losetup ]; then
606 die "losetup is missing"
608 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
609 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
610 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"
613 line="`awk '/'$key'/ { print $0; }' $fstab`"
614 loopDev="$(echo $line | awk '{print $3}')"
615 loopFs="$(echo $line | awk '{print $4}')"
616 loopFile="$(echo $line | awk '{print $5}')"
618 BASICMODULES="$BASICMODULES -loop"
619 find_module "-$loopFs"
620 BASICMODULES="$BASICMODULES -${loopFs}"
624 if is_lvm "$devpath"; then
625 find_modules_lvm "$devpath"
630 firmware_install_module() {
632 local firmware_files="$2"
634 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
635 # firmware not yet installed
636 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
638 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
640 echo 1 > /sys$DEVPATH/loading
641 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
642 echo 0 > /sys$DEVPATH/loading
645 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
647 # setup firmware loader agent
648 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
651 for firmware in $firmware_files; do
652 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
653 FIRMWAREDIR=${firmware%/*}
654 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
655 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
656 elif [ -f "/lib/firmware/$firmware" ]; then
657 FIRMWAREDIR=${firmware%/*}
658 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
659 inst /lib/firmware/$firmware /lib/firmware/$firmware
661 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
672 for mod in $modules; do
674 inst_d "/lib/modules/$kernel/$MODULEDIR"
675 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
676 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
677 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
678 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
683 modules_add_linuxrc() {
687 # module path without optional compression
691 local module=${modpath##*/}; module=${module%$modext}
692 local options=$(modprobe_options "$module")
693 local genericname=$(echo $module | tr - _)
694 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
695 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
697 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
698 options="scan=sync $options"
701 if [ -n "$verbose" ]; then
703 if [ "$options" ]; then
704 s="$s with options [$options]"
706 if [ "$usleep" ]; then
707 s="$s and $usleep usleep"
709 debug "Loading module [$module]$s"
712 if [ -n "$firmware" ]; then
713 firmware_install_module "$module" "$firmware"
715 for file in $(find_firmware "$module"); do
716 firmware_install_module "$module" "$file"
720 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
721 if [ -n "$usleep" ]; then
722 echo "usleep $usleep" | add_linuxrc
724 if [ "$module" = "scsi_wait_scan" ]; then
725 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
726 echo "rmmod scsi_wait_scan" | add_linuxrc
733 # Generates /dev nodes based on /proc/partitions information.
734 # Needs /proc mounted.
735 # Can be called multiple times.
736 initrd_gen_devices() {
737 if is_yes "$proc_partitions"; then
744 : 'Making device nodes'
745 cat /proc/partitions | (
746 # ignore first two lines: header, empty line
749 while read major minor blocks dev rest; do
752 [ -e $node ] || mknod $node b $major $minor
759 initrd_gen_setrootdev() {
760 debug "Adding rootfs finding based on kernel cmdline root= option support."
762 debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
764 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
765 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
767 if [ -z "$rootnr" ]; then
768 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
770 if [ -n "$rootnr" ]; then
771 echo "$rootnr" > /proc/sys/kernel/real-root-dev
777 initrd_gen_initramfs_switchroot() {
779 if [ "$rootdev" = "/dev/nfs" ]; then
780 echo "rootfs on NFS root=/dev/nfs"
782 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
785 # parse 'root=xxx' kernel commandline
786 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
788 # from lilo-23.2/readme/README:
789 # root=<device> changes the root device. This overrides settings that may
790 # have been made in the boot image and on the LILO command line. <device> is
791 # either the hexadecimal device number or the full path name of the device,
794 # * The device names are hard-coded in the kernel. Therefore, only the
795 # "standard" names are supported and some less common devices may not be
796 # recognized. In those cases, only numbers can be used.
799 eval "$(busybox awk -v root="$ROOT" '
801 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
802 num_pattern = "[0-9a-f]" num_pattern_short;
803 dev_pattern = "[hms][a-z][a-z]([0-9])+";
807 # see if we have /dev/hdX or hdX, we can just take partition name
808 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
810 sub("^/dev/", "", partition);
814 if (root ~ "^" num_pattern_short "$") {
815 # change "303" => "0x0303"
817 } else if (root ~ "^" num_pattern "$") {
818 # change "0303" => "0x0303"
822 maj = sprintf("%d", "0x" substr(root, 3, 2));
823 min = sprintf("%d", "0x" substr(root, 5, 2));
827 partition && $4 == partition { maj = $1; min = $2; }
828 $1 == maj && $2 == min { partition = $4; }
831 if (maj >= 0 && min >= 0) {
832 printf("maj=%s; min=%s;\n", maj, min);
835 printf("device=/dev/%s;\n", partition);
840 if [ -z "$device" ]; then
844 if [ "$device" -a ! -b $device ]; then
845 mknod $device b $maj $min
848 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
850 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
852 if [ -z "$init" -o ! -x "/newroot$init" ]; then
858 busybox_applet switch_root
860 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
861 exec switch_root /newroot $init ${1:+"$@"}
863 echo "Error! initramfs should not reach this place."
864 echo "It probably means you've got old version of busybox, with broken"
865 echo "initramfs support. Trying to boot anyway, but won't promise anything."
867 exec chroot /newroot $init ${1:+"$@"}
869 echo "Failed to chroot!"
872 # we need /init being real file, not symlink, otherwise the initramfs will
873 # not be ran by pid 1 which is required for switch_root
874 mv $DESTDIR/linuxrc $DESTDIR/init
875 ln -s init $DESTDIR/linuxrc
878 # find if $symbol exists in System.map $mapfile
882 if [ ! -f $mapfile ]; then
883 # missing mapfile (not a pld kernel?)
887 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
890 # find best compressor (or forced one) for initrd
893 # fastest initrd decompression speed is first
894 local compressors='lzo gzip xz lzma bzip2'
896 # a specified one, take it
897 if ! is_yes "$mode"; then
901 debug "finding compressor: $compressors (via $mode)"
902 # check for compressor validity
903 local c prog map=/boot/System.map-$kernel
904 for c in $compressors; do
927 # any existing sym will work
932 die "Unknown compressor $c"
935 if sym_exists $map $sym && [ -x $prog ]; then
941 debug "using gzip for compressor (fallback)"
945 # compresses kernel image image
946 # in function so we could retry with other compressor on failure
948 local compressor="$1" IMAGE="$2" target="$3" tmp
949 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
951 case "$compressor" in
953 # don't use -9 here since kernel won't understand it
954 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
957 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
960 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
963 gzip -9 < "$IMAGE" > "$tmp" || return $?
966 lzop -9 < "$IMAGE" > "$tmp" || return $?
969 cat < "$IMAGE" > "$tmp" || return $?
973 mv -f "$tmp" "$target"
976 if [ -r /etc/sysconfig/geninitrd ]; then
977 . /etc/sysconfig/geninitrd
980 if [ ! -f /proc/mounts ]; then
981 warn "/proc filesystem not mounted, may cause wrong results or failure."
984 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
986 while [ $# -gt 0 ]; do
996 modulefile=${1#--modules-conf=}
1005 --without-bootsplash)
1017 --without-fbcondecor)
1026 --with-suspend2 | --with-tuxonice)
1029 --without-suspend2 | --without-tuxonice)
1033 LVMTOOLSVERSION=${1#--lvmversion=}
1035 --lvmtoolsversion=*)
1036 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1038 --lvmtoolsversion|--lvmversion)
1051 --without-multipath)
1055 USE_MULTIPATH=${1#--with-multipath=}
1064 BASICMODULES="$BASICMODULES ${1#--with=}"
1067 BASICMODULES="$BASICMODULES $2"
1071 echo "$PROGRAM: version $VERSION"
1082 COMPRESS="${1#--compress=}"
1091 STRIP="${1#--strip=}"
1104 PREMODS="$PREMODS ${1#--preload=}"
1107 PREMODS="$PREMODS $2"
1111 die "--fs option is obsoleted. Use --initrdfs instead"
1114 INITRDFS=${1#--initrdfs=}
1127 if [ -z "$target" ]; then
1129 elif [ -z "$kernel" ]; then
1141 if [ -z "$target" -o -z "$kernel" ]; then
1147 if [ "$(id -u)" != 0 ]; then
1148 die "You need to be root to generate initrd"
1151 if [ -d /lib64 -a -d /usr/lib64 ]; then
1157 initrd_dir=/usr/$_lib/initrd
1158 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1159 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1161 debug "# $GENINITRD_RCSID (geninitrd)"
1162 debug "Using _lib: $_lib"
1163 debug "Using initrd_dir: $initrd_dir"
1165 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1167 # we setup mods after parsing command line args
1168 geninitrd_setup_mods
1170 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1171 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1174 if [ -z "$INITRDFS" ]; then
1175 if [ -n "$FS" ]; then
1176 # FS= can came only via /etc/sysconfig/geninitrd likely?
1177 die "FS configuration option is obsoleted. Use INITRDFS instead"
1181 if [ "$kernel_version" -ge "002005" ]; then
1182 INITRDFS="initramfs"
1190 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1193 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1196 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1199 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1200 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1203 die "Filesystem $INITRDFS on initrd is not supported"
1207 if [ -L "$target" ]; then
1208 target=$(readlink -f "$target")
1211 if [ -n "$img_vers" ]; then
1212 target="$target-$kernel"
1215 if [ -z "$force" -a -f "$target" ]; then
1216 die "$target already exists."
1219 if [ ! -d "/lib/modules/$kernel" ]; then
1220 die "/lib/modules/$kernel is not a directory."
1223 if [ "$kernel_version" -ge "002005" ]; then
1229 for n in $PREMODS; do
1233 if [ "$FBMODULE" ]; then
1234 find_module "$FBMODULE"
1237 # autodetect USB keyboards
1240 # allow forcing loading SCSI and/or IDE modules
1241 # XXX: where ADDSCSI cames from? drop?
1242 if is_yes "$ADDSCSI"; then
1246 # autodetect SATA modules
1249 # XXX: where ADDIDE cames from? drop?
1250 if is_yes "$ADDIDE"; then
1254 if is_yes "$USE_SUSPEND"; then
1255 find_modules_suspend
1258 find_root "$fstab" || exit
1259 debug "Using $rootdev as device for rootfs"
1261 find_modules_for_devpath "$rootdev"
1263 # if USE_MULTIPATH is path to device, scan that too
1264 # this is to bootstrap multipath setup into initrd.
1265 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1266 find_modules_multipath $USE_MULTIPATH
1269 find_module "-$rootFs"
1271 for n in $BASICMODULES; do
1275 if is_yes "$USE_TUXONICE"; then
1279 find_modules_fbsplash
1281 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1282 debug "No modules are needed -- not building initrd image."
1286 debug "Building initrd..."
1287 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1288 RCFILE="$DESTDIR/linuxrc"
1290 chmod a+rx "$RCFILE"
1291 ln -s linuxrc $DESTDIR/init
1293 # create dirs that we really need
1294 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1296 modules_install "$MODULES"
1298 # mknod'ing the devices instead of copying them works both with and
1300 mknod "$DESTDIR/dev/console" c 5 1
1301 mknod "$DESTDIR/dev/null" c 1 3
1302 mknod "$DESTDIR/dev/zero" c 1 5
1303 mknod "$DESTDIR/dev/random" c 1 8
1304 mknod "$DESTDIR/dev/urandom" c 1 9
1306 inst_exec $busybox /bin/busybox
1307 ln -s busybox $DESTDIR/bin/sh
1308 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1309 ln -s busybox $DESTDIR/bin/initrd-busybox
1313 # initrd generated by:
1319 # builtin defaults from geninitrd
1323 add_linuxrc <<-'EOF'
1324 read CMDLINE < /proc/cmdline
1326 for arg in $CMDLINE; do
1327 if [ "${arg}" = "debuginitrd" ]; then
1330 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1331 DEBUGINITRD=${arg##debuginitrd=}
1333 if [ "${arg##root=}" != "${arg}" ]; then
1336 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1337 ROOTFSFLAGS=${arg##rootfsflags=}
1339 if [ "${arg##init=}" != "${arg}" ]; then
1344 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1345 if [ "$DEBUGINITRD" = "sh" ]; then
1348 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1349 add_linuxrc <<-'EOF'
1350 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1353 add_linuxrc <<-'EOF'
1357 add_linuxrc <<-'EOF'
1365 if [ "$DEBUGINITRD" ]; then
1370 modules_add_linuxrc $MODULES
1372 # TODO: rewrite for busybox
1373 #if [ -n "$loopDev" ]; then
1374 # if [ ! -d /initrd ]; then
1378 # cp -a "$loopDev" "$DESTDIR/dev"
1379 # cp -a "$rootdev" "$DESTDIR/dev"
1380 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1381 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1382 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1383 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1386 if is_yes "$USE_UDEV"; then
1390 find_modules_uvesafb
1395 initrd_gen_multipath
1398 if is_yes "$have_nfs"; then
1404 initrd_gen_setrootdev
1410 # additional devs always needed
1411 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1413 initrd_gen_stop_udevd
1414 initrd_gen_stop_uvesafb
1417 add_linuxrc <<-'EOF'
1421 for i in $(export -p); do
1422 i=${i#declare -x } # ksh/bash
1423 i=${i#export } # busybox
1434 [ -z "$i" ] && continue
1437 ROOT|PATH|HOME|TERM)
1448 if [ "$INITRDFS" = "initramfs" ]; then
1449 initrd_gen_initramfs_switchroot
1455 initrd_gen_fbcondecor
1457 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1459 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1461 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1462 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1464 debug "Creating $INITRDFS image $IMAGE"
1467 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1468 # NOTE: ext2 label is max 16 chars
1469 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1470 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1472 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1473 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1474 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1475 # We don't need this directory, so let's save space
1476 rm -rf "$tmpmnt"/lost+found
1478 debug "Copy recursively $DESTDIR -> $tmpmnt"
1479 cp -a $DESTDIR/* $tmpmnt
1485 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1488 mkcramfs "$DESTDIR" "$IMAGE"
1491 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1494 die "Filesystem $INITRDFS not supported by $PROGRAM"
1497 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1498 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1499 CONFIG_BLK_DEV_RAM_SIZE=4096
1500 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1503 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1504 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1507 if ! is_no "$COMPRESS"; then
1508 compressor=$(find_compressor "$COMPRESS")
1509 debug "Compressing $target with $compressor"
1511 # TODO: the image name (specified from kernel.spec) already contains
1512 # extension, which is .gz most of the time.
1513 compress_image "$compressor" "$IMAGE" "$target" || {
1514 if [ $compressor != gzip ]; then
1515 warn "Could not compress with $compressor, retrying with gzip"
1516 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1518 die "Could not compress image with $compressor"
1522 cp -a "$IMAGE" "$target"
1525 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1526 initrd_gen_bootsplash "$target"
1528 rm -rf "$DESTDIR" "$IMAGE"
1530 # vim:ts=4:sw=4:noet:fdm=marker