7 # based on mkinitrd from RedHat Linux
10 RCSID='$Revision$ $Date$'
11 R=${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
30 # device node for rootfs from fstab
40 # is /tmp mounted on tmpfs
43 # are /dev nodes already created from /proc/devices info?
47 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
48 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
49 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
50 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
51 echo " [--with-bootsplash] [--without-bootsplash]"
52 echo " [--with-fbsplash] [--without-fbsplash]"
53 echo " [--with-fbcondecor] [--without-fbcondecor]"
54 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
55 echo " [--with-suspend] [--without-suspend]"
56 echo " [--with-tuxonice] [--without-tuxonice]"
57 echo " [--without-dmraid]"
58 echo " [--with-multipath=DEVPATH] [--without-multipath]"
59 echo " [--without-blkid] [--without-luks]"
60 echo " <initrd-image> <kernel-version>"
65 for kdir in /lib/modules/*; do
66 [ -d $kdir ] || continue
68 echo " $PROGRAM -f --initrdfs=rom /boot/initrd-$kver.gz $kver"
82 [ -n "$verbose" ] && msg "$*" >&2
85 # aborts program abnormally
92 # find program from specified paths
98 debug "find_tool: found $x"
102 debug "find_tool: did not found any of: $@"
106 # loads geninitrd modules
107 geninitrd_load_mods() {
110 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
111 die "$mod geninitrd module can't be loaded"
113 . /lib/geninitrd/mod-$mod.sh
115 if type setup_mod_$mod > /dev/null; then
116 # add to list which need init
117 GENINITRD_MODS="$GENINITRD_MODS $mod"
122 # setup geninitrd modules
123 geninitrd_setup_mods() {
126 for mod in $GENINITRD_MODS; do
131 # append text to /linuxrc
132 # takes STDIN as input
137 # generate code to mount /dev on tmpfs and create initial nodes
138 # can be called multiple times. /dev is cleaned up (umounted) automatically at
141 if [ "$INITRDFS" = "initramfs" ]; then
142 # initramfs is read-write filesystem, no need for tmpfs
146 # we already generated tmpfs code; return
147 if is_yes "$dev_mounted"; then
153 busybox_applet mount mknod mkdir
156 mount -o mode=0755 -t tmpfs none /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/urandom c 1 9
166 # generate code to mount /proc on initrd
167 # can be called multiple times
169 if is_yes "$proc_mounted"; then
174 if [ "$INITRDFS" = "initramfs" ]; then
175 # /proc is mounted with initramfs 2.6.22.14 kernel
176 # XXX: remove when it is clear why proc was already mounted
177 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
179 echo "mount -t proc none /proc" | add_linuxrc
183 # generate code to mount /sys on initrd
184 # can be called multiple times
186 if is_yes "$sys_mounted"; then
191 echo "mount -t sysfs none /sys" | add_linuxrc
194 # generate code to mount /tmp on initrd
195 # can be called multiple times
197 if [ "$INITRDFS" = "initramfs" ]; then
198 # initramfs is read-write filesystem, no need for tmpfs
202 if is_yes "$tmp_mounted"; then
207 echo "mount -t tmpfs none /tmp" | add_linuxrc
210 # unmount all mountpoints mounted by geninitrd
214 : Last shell before umounting all and giving control over to real init.
218 if is_yes "$dev_mounted"; then
219 echo 'umount /dev' | add_linuxrc
222 if is_yes "$sys_mounted"; then
223 echo 'umount /sys' | add_linuxrc
226 if is_yes "$tmp_mounted"; then
227 echo 'umount /tmp' | add_linuxrc
230 if is_yes "$proc_mounted"; then
231 echo 'umount /proc' | add_linuxrc
237 # Checks if busybox has support for APPLET(s)
238 # Exits from geninitrd if the support is not present.
240 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
244 if [ -z "$busybox_functions" ]; then
245 local tmp=$($busybox 2>&1)
247 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
248 if [[ "$tmp" = *applet\ not\ found* ]]; then
250 ln -s $busybox $t/busybox
251 local tmp=$($t/busybox 2>&1)
255 busybox_functions=$(echo "$tmp" | \
256 sed -ne '/Currently defined functions:/,$p' | \
257 xargs | sed -e 's,.*Currently defined functions: ,,'
263 eval have='$'busybox_have_$applet
264 if [ -z "$have" ]; then
265 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
266 if [ "$have" = 0 ]; then
267 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
270 eval busybox_have_$applet=$have
273 if [ $err = 1 ]; then
278 # extract-ikconfig - Extract the .config file from a kernel image
280 # The obscure use of the "tr" filter is to work around older versions of
281 # "grep" that report the byte offset of the line instead of the pattern.
283 # (c) 2009, Dick Streefland <dick@streefland.net>
284 # Licensed under the terms of the GNU General Public License.
286 # Ripped and adjusted for geninitrd from linux-2.6.34/scripts/extract-ikconfig
288 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
289 if [ -z "$kofile" ]; then
295 gzip -dc "$kofile" > $img
302 local cf1='IKCFG_ST\037\213\010'
303 local cf2='0123456789'
306 if pos=$(tr "$cf1\n$cf2" "\n$cf2=" < "$img" | grep -abo "^$cf2"); then
308 tail -c+$(($pos+8)) "$img" | gzip -dcq
313 # Finds module dependencies
317 # Outputs full path to module and it's dependencies
322 # if module is prefixed with dash, we should ignore errors if the module
324 if [ ${module#-} != $module ]; then
329 # This works when user has module-init-tools installed even on 2.4 kernels
331 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
334 if [ $skiperrors = 1 ]; then
339 if ! is_no "$EXIT_IF_MISSING"; then
340 die "$module: module not found for $kernel kernel"
343 warn "$module: module not found for $kernel kernel"
344 warn "If $module isn't compiled in kernel then this initrd may not start your system."
348 while read insmod modpath options; do
349 [ "$insmod" = "insmod" ] && echo $modpath
356 # no firmware support in 2.4 kernels
357 if [ "$kernel_version_long" -lt "002005048" ]; then
360 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
365 local mod depmod module=$1
367 depmod=$(find_depmod $module) || exit 1
368 for mod in $depmod; do
369 mod=${mod#/lib/modules/$kernel/}
371 # add each module only once
373 for m in $MODULES; do
374 [ $m = $mod ] && have=1
376 if [ $have = 0 ]; then
377 MODULES="$MODULES $mod"
382 # install a file to temporary mount image.
383 # it will operate recursively (copying directories)
384 # and will symlink destinations if source is symlink.
386 if [ $# -lt 2 ]; then
387 die 'Usage: inst <file> [<file>] <destination>'
390 local src i=0 c=$(($# - 1))
391 while [ $i -lt $c ]; do
398 parentDir=$(dirname $DESTDIR$dest)
399 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
400 debug "+ cp $* $DESTDIR$dest"
401 cp -HR "$@" "$DESTDIR$dest"
406 die 'Usage: inst_d <destination> <destination>'
409 install -d "$DESTDIR$dir"
413 # install executable and it's shared libraries
415 if [ $# -lt 2 ]; then
416 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
418 local src i=0 c=$(($# - 1))
419 while [ $i -lt $c ]; do
429 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
431 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
433 inst_exec $lib /$_lib
437 # hack for uclibc linked binaries requiring this fixed path
438 # XXX: shouldn't rpath be used here instead so th
439 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
440 local lib=$DESTDIR/$_lib/libc.so.0
441 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
442 local libdir=$(cd $(dirname "$lib"); pwd)
443 if [ ! -e $DESTDIR$libdir ]; then
444 libdir=$(dirname "$libdir")
446 debug "+ ln -s /$_lib $DESTDIR$libdir"
447 ln -s /$_lib $DESTDIR$libdir
452 # output modules.conf / modprobe.conf
454 echo "$modprobe_conf_cache"
458 # defaults to modprobe -c if not told otherwise, this means include statements
460 cache_modprobe_conf() {
461 if [ "$kernel_version" -lt "002005" ]; then
462 modulefile=/etc/modules.conf
463 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
464 modulefile=/etc/conf.modules
468 if [ -n "$modulefile" ]; then
469 debug "Using $modulefile for modules config"
470 modprobe_conf_cache=$(cat $modulefile)
472 debug "Using modprobe -c to get modules config"
473 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
477 # find modules for $devpath
478 find_modules_for_devpath() {
480 if [ -z "$devpath" ]; then
481 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
484 if [[ "$devpath" = /dev/dm-* ]]; then
485 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
486 devpath=$(dm_longname "$devpath")
489 if [ -L "$devpath" ] && ! is_lvm "$devpath"; then
490 # sanitize things like:
491 # /dev/block/104:2 -> /dev/cciss/c0d0p2
492 devpath=$(readlink -f "$devpath")
495 debug "Finding modules for device path $devpath"
497 if is_luks "$devpath"; then
498 find_modules_luks "$devpath"
502 if is_nfs "$devpath"; then
503 find_modules_nfs "$devpath"
507 if is_md "$devpath"; then
508 find_modules_md "$devpath"
512 if is_multipath "$devpath"; then
513 if find_modules_multipath "$devpath"; then
520 if is_dmraid "$devpath"; then
521 if find_modules_dmraid "$devpath"; then
527 if is_scsi "$devpath"; then
528 find_modules_scsi "$devpath"
532 if is_ide "$devpath"; then
533 find_modules_ide "$devpath"
537 if [[ "$devpath" == /dev/rd/* ]]; then
543 if [[ "$devpath" == /dev/ida/* ]]; then
544 find_module "cpqarray"
545 rootdev_add=/dev/ida/
549 if [[ "$devpath" == /dev/cciss/* ]]; then
551 rootdev_add=/dev/cciss/
555 if [[ "$devpath" == /dev/ataraid/* ]]; then
557 find_module "ataraid"
558 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
559 if [ -n "$ataraidmodules" ]; then
560 # FIXME: think about modules compiled in kernel
561 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
563 for n in $ataraidmodules; do
566 rootdev_add=/dev/ataraid/
570 # check to see if we need to set up a loopback filesystem
571 if [[ "$devpath" == /dev/loop* ]]; then
572 die "Sorry, root on loop device isn't supported."
573 # TODO: rewrite for bsp and make nfs ready
574 if [ ! -x /sbin/losetup ]; then
575 die "losetup is missing"
577 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
578 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
579 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"
582 line="`awk '/'$key'/ { print $0; }' $fstab`"
583 loopDev="$(echo $line | awk '{print $3}')"
584 loopFs="$(echo $line | awk '{print $4}')"
585 loopFile="$(echo $line | awk '{print $5}')"
587 BASICMODULES="$BASICMODULES -loop"
588 find_module "-$loopFs"
589 BASICMODULES="$BASICMODULES -${loopFs}"
593 if is_lvm "$devpath"; then
594 find_modules_lvm "$devpath"
599 firmware_install_module() {
601 local firmware_files="$2"
603 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
604 # firmware not yet installed
605 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
607 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
609 echo 1 > /sys$DEVPATH/loading
610 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
611 echo 0 > /sys$DEVPATH/loading
614 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
617 for firmware in $firmware_files; do
618 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
619 FIRMWAREDIR=${firmware%/*}
620 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
621 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
622 elif [ -f "/lib/firmware/$firmware" ]; then
623 FIRMWAREDIR=${firmware%/*}
624 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
625 inst /lib/firmware/$firmware /lib/firmware/$firmware
627 die "firmware file /lib/firmware/$firmware nor /lib/firmware/$kernel/$firmware found."
632 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
639 for mod in $modules; do
641 inst_d "/lib/modules/$kernel/$MODULEDIR"
642 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
643 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
647 modules_add_linuxrc() {
651 # module path without optional compression
655 local module=${modpath##*/}; module=${module%$modext}
656 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
657 local genericname=$(echo $module | tr - _)
658 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
659 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
661 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
662 options="scan=sync $options"
665 if [ -n "$verbose" ]; then
667 if [ "$options" ]; then
668 s="$s with options [$options]"
670 if [ "$usleep" ]; then
671 s="$s and $usleep usleep"
673 debug "Loading module [$module]$s"
676 if [ -n "$firmware" ]; then
677 firmware_install_module "$module" "$firmware"
679 for file in $(find_firmware "$module"); do
680 firmware_install_module "$module" "$file"
684 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
685 if [ -n "$usleep" ]; then
686 echo "usleep $usleep" | add_linuxrc
688 if [ "$module" = "scsi_wait_scan" ]; then
689 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
690 echo "rmmod scsi_wait_scan" | add_linuxrc
697 # Generates /dev nodes based on /proc/partitions information.
698 # Needs /proc mounted.
699 # Can be called multiple times.
700 initrd_gen_devices() {
701 if is_yes "$proc_partitions"; then
708 : 'Making device nodes'
709 cat /proc/partitions | (
710 # ignore first two lines: header, empty line
713 while read major minor blocks dev rest; do
716 [ -e $node ] || mknod $node b $major $minor
723 initrd_gen_setrootdev() {
724 debug "Adding rootfs finding based on kernel cmdline root= option support."
726 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
727 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
728 if [ -n "$rootnr" ]; then
729 echo "$rootnr" > /proc/sys/kernel/real-root-dev
735 initrd_gen_initramfs_switchroot() {
737 if [ "$rootdev" = "/dev/nfs" ]; then
738 echo "rootfs on NFS root=/dev/nfs"
740 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
743 # parse 'root=xxx' kernel commandline
744 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
746 device=/dev/no_partition_found
747 eval "$(busybox awk -v c="$ROOT" '
749 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
750 num_pattern = "[0-9a-f]" num_pattern_short;
751 dev_pattern = "[hms][a-z][a-z]([0-9])+";
752 partition = "no_partition_found";
756 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
757 if (c ~ "^" num_pattern "$") {
758 maj = sprintf("%s",substr(c,1,2));
759 min = sprintf("%s",substr(c,3));
761 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
762 if (c ~ "^" dev_pattern "$") partition = c;
765 $4 ~ partition { maj = $1; min = $2; }
766 $1 ~ maj && $2 ~ min { partition = $4; }
769 if (maj >= 0 && min >= 0) {
770 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
774 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
775 mknod $device b $maj $min
785 if [ "$device" = '/dev/no_partition_found' ]; then
789 mount -t $rootfs -r $device /newroot
790 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
791 if [ -z "$init" -o ! -x "/newroot$init" ]; then
797 busybox_applet switch_root
799 exec switch_root /newroot $init ${1:+"$@"}
801 echo "Error! initramfs should not reach this place."
802 echo "It probably means you've got old version of busybox, with broken"
803 echo "initramfs support. Trying to boot anyway, but won't promise anything."
805 exec chroot /newroot $init ${1:+"$@"}
807 echo "Failed to chroot!"
809 # we need /init being real file, not symlink, otherwise the initramfs will
810 # not be ran by pid 1 which is required for switch_root
811 mv $DESTDIR/linuxrc $DESTDIR/init
812 ln -s init $DESTDIR/linuxrc
815 # find if $symbol exists in System.map $mapfile
819 if [ ! -f $mapfile ]; then
820 # missing mapfile (not a pld kernel?)
824 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
827 # find best compressor (or forced one) for initrd
830 # the best compressor list
831 local compressors='xz lzma bzip2 gzip lzo'
833 # a specified one, take it
834 if ! is_yes "$mode"; then
838 debug "finding compressor: $compressors (via $mode)"
839 # check for compressor validity
840 local c prog map=/boot/System.map-$kernel
841 for c in $compressors; do
864 die "Unknown compressor $c"
867 if sym_exists $map $sym && [ -x $prog ]; then
873 debug "using gzip for compressor (fallback)"
877 # compresses kernel image image
878 # in function so we could retry with other compressor on failure
880 local compressor="$1" IMAGE="$2" target="$3" tmp
881 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
883 case "$compressor" in
885 # don't use -9 here since kernel won't understand it
886 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
889 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
892 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
895 gzip -9 < "$IMAGE" > "$tmp" || return $?
898 lzop -9 < "$IMAGE" > "$tmp" || return $?
902 mv -f "$tmp" "$target"
905 if [ -r /etc/sysconfig/geninitrd ]; then
906 . /etc/sysconfig/geninitrd
909 if [ ! -f /proc/mounts ]; then
910 warn "/proc filesystem not mounted, may cause wrong results or failure."
913 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi
915 while [ $# -gt 0 ]; do
925 modulefile=${1#--modules-conf=}
934 --without-bootsplash)
946 --without-fbcondecor)
955 --with-suspend2 | --with-tuxonice)
958 --without-suspend2 | --without-tuxonice)
962 LVMTOOLSVERSION=${1#--lvmversion=}
965 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
967 --lvmtoolsversion|--lvmversion)
984 USE_MULTIPATH=${1#--with-multipath=}
993 BASICMODULES="$BASICMODULES ${1#--with=}"
996 BASICMODULES="$BASICMODULES $2"
1000 echo "$PROGRAM: version $VERSION"
1010 COMPRESS="${1#--compress=}"
1022 PREMODS="$PREMODS ${1#--preload=}"
1025 PREMODS="$PREMODS $2"
1029 die "--fs option is obsoleted. Use --initrdfs instead"
1032 INITRDFS=${1#--initrdfs=}
1045 if [ -z "$target" ]; then
1047 elif [ -z "$kernel" ]; then
1059 if [ -z "$target" -o -z "$kernel" ]; then
1065 if [ "$(id -u)" != 0 ]; then
1066 die "You need to be root to generate initrd"
1069 if [ -d /lib64 -a -d /usr/lib64 ]; then
1075 initrd_dir=/usr/$_lib/initrd
1076 kernel_version=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d",$1,$2)}')
1077 kernel_version_long=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}')
1080 debug "Using _lib: $_lib"
1081 debug "Using initrd_dir: $initrd_dir"
1083 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1085 # we setup mods after parsing command line args
1086 geninitrd_setup_mods
1088 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1089 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1092 if [ -z "$INITRDFS" ]; then
1093 if [ -n "$FS" ]; then
1094 # FS= can came only via /etc/sysconfig/geninitrd likely?
1095 die "FS configuration option is obsoleted. Use INITRDFS instead"
1099 if [ "$kernel_version" -ge "002005" ]; then
1100 INITRDFS="initramfs"
1108 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1111 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1114 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1117 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1118 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1121 die "Filesystem $INITRDFS on initrd is not supported"
1125 if [ -L "$target" ]; then
1126 target=$(readlink -f "$target")
1129 if [ -n "$img_vers" ]; then
1130 target="$target-$kernel"
1133 if [ -z "$force" -a -f "$target" ]; then
1134 die "$target already exists."
1137 if [ ! -d "/lib/modules/$kernel" ]; then
1138 die "/lib/modules/$kernel is not a directory."
1141 if [ "$kernel_version" -ge "002005" ]; then
1147 for n in $PREMODS; do
1151 if [ "$FBMODULE" ]; then
1152 find_module "$FBMODULE"
1155 # allow forcing loading SCSI and/or IDE modules
1156 # XXX: where ADDSCSI cames from? drop?
1157 if is_yes "$ADDSCSI"; then
1161 # autodetect SATA modules
1164 # XXX: where ADDIDE cames from? drop?
1165 if is_yes "$ADDIDE"; then
1169 if is_yes "$USE_SUSPEND"; then
1170 find_modules_suspend
1173 find_root "$fstab" || exit
1174 debug "Using $rootdev as device for rootfs"
1176 find_modules_for_devpath "$rootdev"
1178 # if USE_MULTIPATH is path to device, scan that too
1179 # this is to bootstrap multipath setup into initrd.
1180 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1181 find_modules_multipath $USE_MULTIPATH
1184 find_module "-$rootFs"
1186 for n in $BASICMODULES; do
1190 if is_yes "$USE_TUXONICE"; then
1194 find_modules_fbsplash
1196 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1197 debug "No modules are needed -- not building initrd image."
1201 debug "Building initrd..."
1202 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1203 RCFILE="$DESTDIR/linuxrc"
1205 chmod a+rx "$RCFILE"
1206 ln -s linuxrc $DESTDIR/init
1208 # create dirs that we really need
1209 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1211 modules_install "$MODULES"
1213 # mknod'ing the devices instead of copying them works both with and
1215 mknod "$DESTDIR/dev/console" c 5 1
1216 mknod "$DESTDIR/dev/null" c 1 3
1217 mknod "$DESTDIR/dev/zero" c 1 5
1218 mknod "$DESTDIR/dev/urandom" c 1 9
1220 inst_exec $busybox /bin/busybox
1221 ln -s busybox $DESTDIR/bin/sh
1222 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1223 ln -s busybox $DESTDIR/bin/initrd-busybox
1227 # initrd generated by:
1232 add_linuxrc <<-'EOF'
1233 read CMDLINE < /proc/cmdline; export CMDLINE
1235 for arg in $CMDLINE; do
1236 if [ "${arg}" = "debuginitrd" ]; then
1239 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1240 DEBUGINITRD=${arg##debuginitrd=}
1242 if [ "${arg##root=}" != "${arg}" ]; then
1247 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1248 if [ "$DEBUGINITRD" = "sh" ]; then
1251 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1252 add_linuxrc <<-'EOF'
1253 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1256 add_linuxrc <<-'EOF'
1260 add_linuxrc <<-'EOF'
1268 if [ "$DEBUGINITRD" ]; then
1273 modules_add_linuxrc $MODULES
1275 # TODO: rewrite for busybox
1276 #if [ -n "$loopDev" ]; then
1277 # if [ ! -d /initrd ]; then
1281 # cp -a "$loopDev" "$DESTDIR/dev"
1282 # cp -a "$rootdev" "$DESTDIR/dev"
1283 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1284 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1285 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1286 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1289 if is_yes "$USE_UDEV"; then
1293 find_modules_uvesafb
1296 if is_yes "$have_luks"; then
1300 if is_yes "$have_dmraid"; then
1304 if is_yes "$have_multipath"; then
1305 initrd_gen_multipath
1308 if is_yes "$USE_BLKID"; then
1312 if is_yes "$have_nfs"; then
1314 elif is_yes "$have_md"; then
1316 if is_yes "$have_lvm"; then
1319 initrd_gen_setrootdev
1321 elif is_yes "$have_lvm"; then
1324 initrd_gen_setrootdev
1327 if is_yes "$USE_TUXONICE"; then
1331 if is_yes "$USE_SUSPEND"; then
1335 # additional devs always needed
1336 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1338 if is_yes "$USE_UDEV"; then
1339 initrd_gen_stop_udevd
1342 if [ "$INITRDFS" = "initramfs" ]; then
1343 initrd_gen_initramfs_switchroot
1348 if is_yes "$FB_SPLASH"; then
1352 if is_yes "$FB_CON_DECOR"; then
1353 initrd_gen_fbcondecor
1356 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1358 debug "Creating $INITRDFS image $IMAGE"
1361 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1362 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
1363 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1365 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1366 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1367 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
1368 # We don't need this directory, so let's save space
1369 rm -rf "$tmpmnt"/lost+found
1371 debug "Copy recursively $DESTDIR -> $tmpmnt"
1372 cp -a $DESTDIR/* $tmpmnt
1378 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel initrd"
1381 mkcramfs "$DESTDIR" "$IMAGE"
1384 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1387 die "Filesystem $INITRDFS not supported by $PROGRAM"
1390 CONFIG_BLK_DEV_RAM_SIZE=$(extract-ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1391 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1392 CONFIG_BLK_DEV_RAM_SIZE=4096
1395 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1396 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1397 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1398 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1401 if ! is_no "$COMPRESS"; then
1402 compressor=$(find_compressor "$COMPRESS")
1403 debug "Compressing $target with $compressor"
1405 # TODO: the image name (specified from kernel.spec) already contains
1406 # extension, which is .gz most of the time.
1407 compress_image "$compressor" "$IMAGE" "$target" || {
1408 if [ $compressor != gzip ]; then
1409 warn "Could not compress with $compressor, retrying with gzip"
1410 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1412 die "Could not compress image with $compressor"
1416 cp -a "$IMAGE" "$target"
1419 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1420 if is_yes "$BOOT_SPLASH"; then
1421 initrd_gen_bootsplash "$target"
1424 rm -rf "$DESTDIR" "$IMAGE"
1426 # vim:ts=4:sw=4:noet:fdm=marker