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 "$*" >&2
86 # aborts program abnormally
93 # find program from specified paths
99 debug "find_tool: found $x"
103 debug "find_tool: did not found any of: $@"
107 # loads geninitrd modules
108 geninitrd_load_mods() {
111 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
112 die "$mod geninitrd module can't be loaded"
114 . /lib/geninitrd/mod-$mod.sh
116 GENINITRD_MODS="$GENINITRD_MODS $mod"
120 # setup geninitrd modules
121 geninitrd_setup_mods() {
124 for mod in $GENINITRD_MODS; do
125 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
126 debug "# $rcsid (mod-$mod)"
128 # some mods want init
129 if type setup_mod_$mod > /dev/null; then
135 # append text to /linuxrc
136 # takes STDIN as input
141 # generate code to mount /dev on tmpfs and create initial nodes
142 # can be called multiple times. /dev is cleaned up (umounted) automatically at
145 # 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 # NOTE: module init tools uses "options", kmod uses "option"
476 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 ~ "option" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
481 # defaults to modprobe -c if not told otherwise, this means include statements
483 cache_modprobe_conf() {
484 if [ "$kernel_version" -lt "002005" ]; then
485 modulefile=/etc/modules.conf
486 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
487 modulefile=/etc/conf.modules
491 if [ -n "$modulefile" ]; then
492 debug "Using $modulefile for modules config"
493 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
496 debug "Using modprobe -c to get modules config"
497 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
501 # find modules for $devpath
502 find_modules_for_devpath() {
504 if [ -z "$devpath" ]; then
505 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
508 if [[ "$devpath" = /dev/dm-* ]]; then
509 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
510 devpath=$(dm_node "$devpath")
513 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
514 # sanitize things like:
515 # /dev/block/104:2 -> /dev/cciss/c0d0p2
516 devpath=$(readlink -f "$devpath")
519 debug "Finding modules for device path $devpath"
521 if is_luks "$devpath"; then
522 find_modules_luks "$devpath"
526 if is_nfs "$devpath"; then
527 find_modules_nfs "$devpath"
531 if is_md "$devpath"; then
532 find_modules_md "$devpath"
536 if is_multipath "$devpath"; then
537 if find_modules_multipath "$devpath"; then
544 if is_dmraid "$devpath"; then
545 if find_modules_dmraid "$devpath"; then
551 if is_scsi "$devpath"; then
552 find_modules_scsi "$devpath"
556 if is_ide "$devpath"; then
557 find_modules_ide "$devpath"
561 if [[ "$devpath" == /dev/rd/* ]]; then
567 if [[ "$devpath" == /dev/ida/* ]]; then
568 find_module "cpqarray"
569 rootdev_add=/dev/ida/
573 if [[ "$devpath" == /dev/cciss/* ]]; then
574 rootdev_add=/dev/cciss/
576 # load hpsa for future kernels, cciss for backwards compat
577 if [ "$kernel_version_long" -ge "003000000" ]; then
578 find_module "hpsa" "-cciss"
579 find_modules_scsi "$devpath"
587 if [[ "$devpath" == /dev/ataraid/* ]]; then
589 find_module "ataraid"
590 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
591 if [ -n "$ataraidmodules" ]; then
592 # FIXME: think about modules compiled in kernel
593 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
595 for n in $ataraidmodules; do
598 rootdev_add=/dev/ataraid/
602 # check to see if we need to set up a loopback filesystem
603 if [[ "$devpath" == /dev/loop* ]]; then
604 die "Sorry, root on loop device isn't supported."
605 # TODO: rewrite for bsp and make nfs ready
606 if [ ! -x /sbin/losetup ]; then
607 die "losetup is missing"
609 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
610 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
611 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"
614 line="`awk '/'$key'/ { print $0; }' $fstab`"
615 loopDev="$(echo $line | awk '{print $3}')"
616 loopFs="$(echo $line | awk '{print $4}')"
617 loopFile="$(echo $line | awk '{print $5}')"
619 BASICMODULES="$BASICMODULES -loop"
620 find_module "-$loopFs"
621 BASICMODULES="$BASICMODULES -${loopFs}"
625 if is_lvm "$devpath"; then
626 find_modules_lvm "$devpath"
631 firmware_install_module() {
633 local firmware_files="$2"
635 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
636 # firmware not yet installed
637 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
639 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
641 echo 1 > /sys$DEVPATH/loading
642 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
643 echo 0 > /sys$DEVPATH/loading
646 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
648 # setup firmware loader agent
649 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
652 for firmware in $firmware_files; do
653 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
654 FIRMWAREDIR=${firmware%/*}
655 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
656 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
657 elif [ -f "/lib/firmware/$firmware" ]; then
658 FIRMWAREDIR=${firmware%/*}
659 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
660 inst /lib/firmware/$firmware /lib/firmware/$firmware
662 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
673 for mod in $modules; do
675 inst_d "/lib/modules/$kernel/$MODULEDIR"
676 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
677 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
678 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
679 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
684 modules_add_linuxrc() {
688 # module path without optional compression
692 local module=${modpath##*/}; module=${module%$modext}
693 local options=$(modprobe_options "$module")
694 local genericname=$(echo $module | tr - _)
695 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
696 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
698 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
699 options="scan=sync $options"
702 if [ -n "$verbose" ]; then
704 if [ "$options" ]; then
705 s="$s with options [$options]"
707 if [ "$usleep" ]; then
708 s="$s and $usleep usleep"
710 debug "Loading module [$module]$s"
713 if [ -n "$firmware" ]; then
714 firmware_install_module "$module" "$firmware"
716 for file in $(find_firmware "$module"); do
717 firmware_install_module "$module" "$file"
721 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
722 if [ -n "$usleep" ]; then
723 echo "usleep $usleep" | add_linuxrc
725 if [ "$module" = "scsi_wait_scan" ]; then
726 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
727 echo "rmmod scsi_wait_scan" | add_linuxrc
734 # Generates /dev nodes based on /proc/partitions information.
735 # Needs /proc mounted.
736 # Can be called multiple times.
737 initrd_gen_devices() {
738 if is_yes "$proc_partitions"; then
745 : 'Making device nodes'
746 cat /proc/partitions | (
747 # ignore first two lines: header, empty line
750 while read major minor blocks dev rest; do
753 [ -e $node ] || mknod $node b $major $minor
760 initrd_gen_setrootdev() {
761 debug "Adding rootfs finding based on kernel cmdline root= option support."
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 device=/dev/no_partition_found
789 eval "$(busybox awk -v c="$ROOT" '
791 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
792 num_pattern = "[0-9a-f]" num_pattern_short;
793 dev_pattern = "[hms][a-z][a-z]([0-9])+";
794 partition = "no_partition_found";
798 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
799 if (c ~ "^" num_pattern "$") {
800 maj = sprintf("%s",substr(c,1,2));
801 min = sprintf("%s",substr(c,3));
803 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
804 if (c ~ "^" dev_pattern "$") partition = c;
807 $4 == partition { maj = $1; min = $2; }
808 $1 == maj && $2 == min { partition = $4; }
811 if (maj >= 0 && min >= 0) {
812 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
816 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
817 mknod $device b $maj $min
820 if [ "$device" = '/dev/no_partition_found' ]; then
824 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
826 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
828 if [ -z "$init" -o ! -x "/newroot$init" ]; then
834 busybox_applet switch_root
836 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
837 exec switch_root /newroot $init ${1:+"$@"}
839 echo "Error! initramfs should not reach this place."
840 echo "It probably means you've got old version of busybox, with broken"
841 echo "initramfs support. Trying to boot anyway, but won't promise anything."
843 exec chroot /newroot $init ${1:+"$@"}
845 echo "Failed to chroot!"
848 # we need /init being real file, not symlink, otherwise the initramfs will
849 # not be ran by pid 1 which is required for switch_root
850 mv $DESTDIR/linuxrc $DESTDIR/init
851 ln -s init $DESTDIR/linuxrc
854 # find if $symbol exists in System.map $mapfile
858 if [ ! -f $mapfile ]; then
859 # missing mapfile (not a pld kernel?)
863 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
866 # find best compressor (or forced one) for initrd
869 # fastest initrd decompression speed is first
870 local compressors='lzo gzip xz lzma bzip2'
872 # a specified one, take it
873 if ! is_yes "$mode"; then
877 debug "finding compressor: $compressors (via $mode)"
878 # check for compressor validity
879 local c prog map=/boot/System.map-$kernel
880 for c in $compressors; do
903 # any existing sym will work
908 die "Unknown compressor $c"
911 if sym_exists $map $sym && [ -x $prog ]; then
917 debug "using gzip for compressor (fallback)"
921 # compresses kernel image image
922 # in function so we could retry with other compressor on failure
924 local compressor="$1" IMAGE="$2" target="$3" tmp
925 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
927 case "$compressor" in
929 # don't use -9 here since kernel won't understand it
930 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
933 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
936 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
939 gzip -9 < "$IMAGE" > "$tmp" || return $?
942 lzop -9 < "$IMAGE" > "$tmp" || return $?
945 cat < "$IMAGE" > "$tmp" || return $?
949 mv -f "$tmp" "$target"
952 if [ -r /etc/sysconfig/geninitrd ]; then
953 . /etc/sysconfig/geninitrd
956 if [ ! -f /proc/mounts ]; then
957 warn "/proc filesystem not mounted, may cause wrong results or failure."
960 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
962 while [ $# -gt 0 ]; do
972 modulefile=${1#--modules-conf=}
981 --without-bootsplash)
993 --without-fbcondecor)
1002 --with-suspend2 | --with-tuxonice)
1005 --without-suspend2 | --without-tuxonice)
1009 LVMTOOLSVERSION=${1#--lvmversion=}
1011 --lvmtoolsversion=*)
1012 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1014 --lvmtoolsversion|--lvmversion)
1027 --without-multipath)
1031 USE_MULTIPATH=${1#--with-multipath=}
1040 BASICMODULES="$BASICMODULES ${1#--with=}"
1043 BASICMODULES="$BASICMODULES $2"
1047 echo "$PROGRAM: version $VERSION"
1057 COMPRESS="${1#--compress=}"
1066 STRIP="${1#--strip=}"
1079 PREMODS="$PREMODS ${1#--preload=}"
1082 PREMODS="$PREMODS $2"
1086 die "--fs option is obsoleted. Use --initrdfs instead"
1089 INITRDFS=${1#--initrdfs=}
1102 if [ -z "$target" ]; then
1104 elif [ -z "$kernel" ]; then
1116 if [ -z "$target" -o -z "$kernel" ]; then
1122 if [ "$(id -u)" != 0 ]; then
1123 die "You need to be root to generate initrd"
1126 if [ -d /lib64 -a -d /usr/lib64 ]; then
1132 initrd_dir=/usr/$_lib/initrd
1133 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1134 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1136 debug "# $GENINITRD_RCSID (geninitrd)"
1137 debug "Using _lib: $_lib"
1138 debug "Using initrd_dir: $initrd_dir"
1140 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1142 # we setup mods after parsing command line args
1143 geninitrd_setup_mods
1145 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1146 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1149 if [ -z "$INITRDFS" ]; then
1150 if [ -n "$FS" ]; then
1151 # FS= can came only via /etc/sysconfig/geninitrd likely?
1152 die "FS configuration option is obsoleted. Use INITRDFS instead"
1156 if [ "$kernel_version" -ge "002005" ]; then
1157 INITRDFS="initramfs"
1165 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1168 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1171 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1174 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1175 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1178 die "Filesystem $INITRDFS on initrd is not supported"
1182 if [ -L "$target" ]; then
1183 target=$(readlink -f "$target")
1186 if [ -n "$img_vers" ]; then
1187 target="$target-$kernel"
1190 if [ -z "$force" -a -f "$target" ]; then
1191 die "$target already exists."
1194 if [ ! -d "/lib/modules/$kernel" ]; then
1195 die "/lib/modules/$kernel is not a directory."
1198 if [ "$kernel_version" -ge "002005" ]; then
1204 for n in $PREMODS; do
1208 if [ "$FBMODULE" ]; then
1209 find_module "$FBMODULE"
1212 # autodetect USB keyboards
1215 # allow forcing loading SCSI and/or IDE modules
1216 # XXX: where ADDSCSI cames from? drop?
1217 if is_yes "$ADDSCSI"; then
1221 # autodetect SATA modules
1224 # XXX: where ADDIDE cames from? drop?
1225 if is_yes "$ADDIDE"; then
1229 if is_yes "$USE_SUSPEND"; then
1230 find_modules_suspend
1233 find_root "$fstab" || exit
1234 debug "Using $rootdev as device for rootfs"
1236 find_modules_for_devpath "$rootdev"
1238 # if USE_MULTIPATH is path to device, scan that too
1239 # this is to bootstrap multipath setup into initrd.
1240 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1241 find_modules_multipath $USE_MULTIPATH
1244 find_module "-$rootFs"
1246 for n in $BASICMODULES; do
1250 if is_yes "$USE_TUXONICE"; then
1254 find_modules_fbsplash
1256 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1257 debug "No modules are needed -- not building initrd image."
1261 debug "Building initrd..."
1262 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1263 RCFILE="$DESTDIR/linuxrc"
1265 chmod a+rx "$RCFILE"
1266 ln -s linuxrc $DESTDIR/init
1268 # create dirs that we really need
1269 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1271 modules_install "$MODULES"
1273 # mknod'ing the devices instead of copying them works both with and
1275 mknod "$DESTDIR/dev/console" c 5 1
1276 mknod "$DESTDIR/dev/null" c 1 3
1277 mknod "$DESTDIR/dev/zero" c 1 5
1278 mknod "$DESTDIR/dev/random" c 1 8
1279 mknod "$DESTDIR/dev/urandom" c 1 9
1281 inst_exec $busybox /bin/busybox
1282 ln -s busybox $DESTDIR/bin/sh
1283 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1284 ln -s busybox $DESTDIR/bin/initrd-busybox
1288 # initrd generated by:
1294 # builtin defaults from geninitrd
1298 add_linuxrc <<-'EOF'
1299 read CMDLINE < /proc/cmdline
1301 for arg in $CMDLINE; do
1302 if [ "${arg}" = "debuginitrd" ]; then
1305 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1306 DEBUGINITRD=${arg##debuginitrd=}
1308 if [ "${arg##root=}" != "${arg}" ]; then
1311 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1312 ROOTFSFLAGS=${arg##rootfsflags=}
1314 if [ "${arg##init=}" != "${arg}" ]; then
1319 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1320 if [ "$DEBUGINITRD" = "sh" ]; then
1323 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1324 add_linuxrc <<-'EOF'
1325 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1328 add_linuxrc <<-'EOF'
1332 add_linuxrc <<-'EOF'
1340 if [ "$DEBUGINITRD" ]; then
1345 modules_add_linuxrc $MODULES
1347 # TODO: rewrite for busybox
1348 #if [ -n "$loopDev" ]; then
1349 # if [ ! -d /initrd ]; then
1353 # cp -a "$loopDev" "$DESTDIR/dev"
1354 # cp -a "$rootdev" "$DESTDIR/dev"
1355 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1356 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1357 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1358 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1361 if is_yes "$USE_UDEV"; then
1365 find_modules_uvesafb
1370 initrd_gen_multipath
1373 if is_yes "$have_nfs"; then
1379 initrd_gen_setrootdev
1385 # additional devs always needed
1386 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1388 initrd_gen_stop_udevd
1389 initrd_gen_stop_uvesafb
1392 add_linuxrc <<-'EOF'
1396 for i in $(export -p); do
1397 i=${i#declare -x } # ksh/bash
1398 i=${i#export } # busybox
1409 [ -z "$i" ] && continue
1412 ROOT|PATH|HOME|TERM)
1423 if [ "$INITRDFS" = "initramfs" ]; then
1424 initrd_gen_initramfs_switchroot
1430 initrd_gen_fbcondecor
1432 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1434 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1435 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1437 debug "Creating $INITRDFS image $IMAGE"
1440 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1441 # NOTE: ext2 label is max 16 chars
1442 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1443 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1445 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1446 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1447 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1448 # We don't need this directory, so let's save space
1449 rm -rf "$tmpmnt"/lost+found
1451 debug "Copy recursively $DESTDIR -> $tmpmnt"
1452 cp -a $DESTDIR/* $tmpmnt
1458 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1461 mkcramfs "$DESTDIR" "$IMAGE"
1464 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1467 die "Filesystem $INITRDFS not supported by $PROGRAM"
1470 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1471 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1472 CONFIG_BLK_DEV_RAM_SIZE=4096
1473 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1476 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1477 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1480 if ! is_no "$COMPRESS"; then
1481 compressor=$(find_compressor "$COMPRESS")
1482 debug "Compressing $target with $compressor"
1484 # TODO: the image name (specified from kernel.spec) already contains
1485 # extension, which is .gz most of the time.
1486 compress_image "$compressor" "$IMAGE" "$target" || {
1487 if [ $compressor != gzip ]; then
1488 warn "Could not compress with $compressor, retrying with gzip"
1489 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1491 die "Could not compress image with $compressor"
1495 cp -a "$IMAGE" "$target"
1498 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1499 initrd_gen_bootsplash "$target"
1501 rm -rf "$DESTDIR" "$IMAGE"
1503 # vim:ts=4:sw=4:noet:fdm=marker