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/random c 1 8
161 mknod /dev/urandom c 1 9
167 # generate code to mount /proc on initrd
168 # can be called multiple times
170 if is_yes "$proc_mounted"; then
175 if [ "$INITRDFS" = "initramfs" ]; then
176 # /proc is mounted with initramfs 2.6.22.14 kernel
177 # XXX: remove when it is clear why proc was already mounted
178 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
180 echo "mount -t proc none /proc" | add_linuxrc
184 # generate code to mount /sys on initrd
185 # can be called multiple times
187 if is_yes "$sys_mounted"; then
192 echo "mount -t sysfs none /sys" | add_linuxrc
195 # generate code to mount /tmp on initrd
196 # can be called multiple times
198 if [ "$INITRDFS" = "initramfs" ]; then
199 # initramfs is read-write filesystem, no need for tmpfs
203 if is_yes "$tmp_mounted"; then
208 echo "mount -t tmpfs none /tmp" | add_linuxrc
211 # unmount all mountpoints mounted by geninitrd
215 : Last shell before umounting all and giving control over to real init.
219 if is_yes "$dev_mounted"; then
220 echo 'umount /dev' | add_linuxrc
223 if is_yes "$sys_mounted"; then
224 echo 'umount /sys' | add_linuxrc
227 if is_yes "$tmp_mounted"; then
228 echo 'umount /tmp' | add_linuxrc
231 if is_yes "$proc_mounted"; then
232 echo 'umount /proc' | add_linuxrc
238 # Checks if busybox has support for APPLET(s)
239 # Exits from geninitrd if the support is not present.
241 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
245 if [ -z "$busybox_functions" ]; then
246 local tmp=$($busybox 2>&1)
248 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
249 if [[ "$tmp" = *applet\ not\ found* ]]; then
251 ln -s $busybox $t/busybox
252 local tmp=$($t/busybox 2>&1)
256 busybox_functions=$(echo "$tmp" | \
257 sed -ne '/Currently defined functions:/,$p' | \
258 xargs | sed -e 's,.*Currently defined functions: ,,'
264 eval have='$'busybox_have_$applet
265 if [ -z "$have" ]; then
266 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
267 if [ "$have" = 0 ]; then
268 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
271 eval busybox_have_$applet=$have
274 if [ $err = 1 ]; then
279 # Extract the .config file from a kernel image
280 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
282 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
283 if [ -n "$kofile" ]; then
284 /lib/geninitrd/extract-ikconfig $kofile
287 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
291 # Finds module dependencies
295 # Outputs full path to module and it's dependencies
300 # if module is prefixed with dash, we should ignore errors if the module
302 if [ ${module#-} != $module ]; then
307 # This works when user has module-init-tools installed even on 2.4 kernels
309 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
312 if [ $skiperrors = 1 ]; then
317 if ! is_no "$EXIT_IF_MISSING"; then
318 die "$module: module not found for $kernel kernel"
321 warn "$module: module not found for $kernel kernel"
322 warn "If $module isn't compiled in kernel then this initrd may not start your system."
326 while read insmod modpath options; do
327 [ "$insmod" = "insmod" ] && echo $modpath
334 # no firmware support in 2.4 kernels
335 if [ "$kernel_version_long" -lt "002005048" ]; then
338 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
343 local mod depmod module=$1
345 depmod=$(find_depmod $module) || exit 1
346 for mod in $depmod; do
347 mod=${mod#/lib/modules/$kernel/}
349 # add each module only once
351 for m in $MODULES; do
352 [ $m = $mod ] && have=1
354 if [ $have = 0 ]; then
355 MODULES="$MODULES $mod"
360 # install a file to temporary mount image.
361 # it will operate recursively (copying directories)
362 # and will symlink destinations if source is symlink.
364 if [ $# -lt 2 ]; then
365 die 'Usage: inst <file> [<file>] <destination>'
368 local src i=0 c=$(($# - 1))
369 while [ $i -lt $c ]; do
376 local parentDir=$(dirname $DESTDIR$dest)
377 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
378 debug "+ cp $* $DESTDIR$dest"
379 cp -HR "$@" "$DESTDIR$dest"
384 die 'Usage: inst_d <destination> <destination>'
387 install -d "$DESTDIR$dir"
391 # install executable and it's shared libraries
393 if [ $# -lt 2 ]; then
394 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
396 local src i=0 c=$(($# - 1))
397 while [ $i -lt $c ]; do
407 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
409 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
411 inst_exec $lib /$_lib
415 # hack for uclibc linked binaries requiring this fixed path
416 # XXX: shouldn't rpath be used here instead so th
417 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
418 local lib=$DESTDIR/$_lib/libc.so.0
419 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
420 local libdir=$(cd $(dirname "$lib"); pwd)
421 if [ ! -e $DESTDIR$libdir ]; then
422 libdir=$(dirname "$libdir")
424 debug "+ ln -s /$_lib $DESTDIR$libdir"
425 ln -s /$_lib $DESTDIR$libdir
430 # output modules.conf / modprobe.conf
432 echo "$modprobe_conf_cache"
436 # defaults to modprobe -c if not told otherwise, this means include statements
438 cache_modprobe_conf() {
439 if [ "$kernel_version" -lt "002005" ]; then
440 modulefile=/etc/modules.conf
441 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
442 modulefile=/etc/conf.modules
446 if [ -n "$modulefile" ]; then
447 debug "Using $modulefile for modules config"
448 modprobe_conf_cache=$(cat $modulefile)
450 debug "Using modprobe -c to get modules config"
451 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
455 # find modules for $devpath
456 find_modules_for_devpath() {
458 if [ -z "$devpath" ]; then
459 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
462 if [[ "$devpath" = /dev/dm-* ]]; then
463 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
464 devpath=$(dm_node "$devpath")
467 if [ -L "$devpath" ] && ! is_lvm "$devpath"; then
468 # sanitize things like:
469 # /dev/block/104:2 -> /dev/cciss/c0d0p2
470 devpath=$(readlink -f "$devpath")
473 debug "Finding modules for device path $devpath"
475 if is_luks "$devpath"; then
476 find_modules_luks "$devpath"
480 if is_nfs "$devpath"; then
481 find_modules_nfs "$devpath"
485 if is_md "$devpath"; then
486 find_modules_md "$devpath"
490 if is_multipath "$devpath"; then
491 if find_modules_multipath "$devpath"; then
498 if is_dmraid "$devpath"; then
499 if find_modules_dmraid "$devpath"; then
505 if is_scsi "$devpath"; then
506 find_modules_scsi "$devpath"
510 if is_ide "$devpath"; then
511 find_modules_ide "$devpath"
515 if [[ "$devpath" == /dev/rd/* ]]; then
521 if [[ "$devpath" == /dev/ida/* ]]; then
522 find_module "cpqarray"
523 rootdev_add=/dev/ida/
527 if [[ "$devpath" == /dev/cciss/* ]]; then
529 rootdev_add=/dev/cciss/
533 if [[ "$devpath" == /dev/ataraid/* ]]; then
535 find_module "ataraid"
536 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
537 if [ -n "$ataraidmodules" ]; then
538 # FIXME: think about modules compiled in kernel
539 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
541 for n in $ataraidmodules; do
544 rootdev_add=/dev/ataraid/
548 # check to see if we need to set up a loopback filesystem
549 if [[ "$devpath" == /dev/loop* ]]; then
550 die "Sorry, root on loop device isn't supported."
551 # TODO: rewrite for bsp and make nfs ready
552 if [ ! -x /sbin/losetup ]; then
553 die "losetup is missing"
555 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
556 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
557 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"
560 line="`awk '/'$key'/ { print $0; }' $fstab`"
561 loopDev="$(echo $line | awk '{print $3}')"
562 loopFs="$(echo $line | awk '{print $4}')"
563 loopFile="$(echo $line | awk '{print $5}')"
565 BASICMODULES="$BASICMODULES -loop"
566 find_module "-$loopFs"
567 BASICMODULES="$BASICMODULES -${loopFs}"
571 if is_lvm "$devpath"; then
572 find_modules_lvm "$devpath"
577 firmware_install_module() {
579 local firmware_files="$2"
581 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
582 # firmware not yet installed
583 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
585 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
587 echo 1 > /sys$DEVPATH/loading
588 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
589 echo 0 > /sys$DEVPATH/loading
592 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
595 for firmware in $firmware_files; do
596 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
597 FIRMWAREDIR=${firmware%/*}
598 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
599 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
600 elif [ -f "/lib/firmware/$firmware" ]; then
601 FIRMWAREDIR=${firmware%/*}
602 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
603 inst /lib/firmware/$firmware /lib/firmware/$firmware
605 die "firmware file /lib/firmware/$firmware nor /lib/firmware/$kernel/$firmware found."
610 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
617 for mod in $modules; do
619 inst_d "/lib/modules/$kernel/$MODULEDIR"
620 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
621 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
625 modules_add_linuxrc() {
629 # module path without optional compression
633 local module=${modpath##*/}; module=${module%$modext}
634 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
635 local genericname=$(echo $module | tr - _)
636 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
637 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
639 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
640 options="scan=sync $options"
643 if [ -n "$verbose" ]; then
645 if [ "$options" ]; then
646 s="$s with options [$options]"
648 if [ "$usleep" ]; then
649 s="$s and $usleep usleep"
651 debug "Loading module [$module]$s"
654 if [ -n "$firmware" ]; then
655 firmware_install_module "$module" "$firmware"
657 for file in $(find_firmware "$module"); do
658 firmware_install_module "$module" "$file"
662 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
663 if [ -n "$usleep" ]; then
664 echo "usleep $usleep" | add_linuxrc
666 if [ "$module" = "scsi_wait_scan" ]; then
667 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
668 echo "rmmod scsi_wait_scan" | add_linuxrc
675 # Generates /dev nodes based on /proc/partitions information.
676 # Needs /proc mounted.
677 # Can be called multiple times.
678 initrd_gen_devices() {
679 if is_yes "$proc_partitions"; then
686 : 'Making device nodes'
687 cat /proc/partitions | (
688 # ignore first two lines: header, empty line
691 while read major minor blocks dev rest; do
694 [ -e $node ] || mknod $node b $major $minor
701 initrd_gen_setrootdev() {
702 debug "Adding rootfs finding based on kernel cmdline root= option support."
704 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
705 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
706 if [ -n "$rootnr" ]; then
707 echo "$rootnr" > /proc/sys/kernel/real-root-dev
713 initrd_gen_initramfs_switchroot() {
715 if [ "$rootdev" = "/dev/nfs" ]; then
716 echo "rootfs on NFS root=/dev/nfs"
718 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
721 # parse 'root=xxx' kernel commandline
722 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
724 device=/dev/no_partition_found
725 eval "$(busybox awk -v c="$ROOT" '
727 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
728 num_pattern = "[0-9a-f]" num_pattern_short;
729 dev_pattern = "[hms][a-z][a-z]([0-9])+";
730 partition = "no_partition_found";
734 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
735 if (c ~ "^" num_pattern "$") {
736 maj = sprintf("%s",substr(c,1,2));
737 min = sprintf("%s",substr(c,3));
739 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
740 if (c ~ "^" dev_pattern "$") partition = c;
743 $4 ~ partition { maj = $1; min = $2; }
744 $1 ~ maj && $2 ~ min { partition = $4; }
747 if (maj >= 0 && min >= 0) {
748 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
752 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
753 mknod $device b $maj $min
763 if [ "$device" = '/dev/no_partition_found' ]; then
767 [ -n "$ROOTFSFLAG" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
769 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot
770 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
771 if [ -z "$init" -o ! -x "/newroot$init" ]; then
777 busybox_applet switch_root
779 exec switch_root /newroot $init ${1:+"$@"}
781 echo "Error! initramfs should not reach this place."
782 echo "It probably means you've got old version of busybox, with broken"
783 echo "initramfs support. Trying to boot anyway, but won't promise anything."
785 exec chroot /newroot $init ${1:+"$@"}
787 echo "Failed to chroot!"
789 # we need /init being real file, not symlink, otherwise the initramfs will
790 # not be ran by pid 1 which is required for switch_root
791 mv $DESTDIR/linuxrc $DESTDIR/init
792 ln -s init $DESTDIR/linuxrc
795 # find if $symbol exists in System.map $mapfile
799 if [ ! -f $mapfile ]; then
800 # missing mapfile (not a pld kernel?)
804 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
807 # find best compressor (or forced one) for initrd
810 # fastest initrd decompression speed is first
811 local compressors='lzo gzip xz lzma bzip2'
813 # a specified one, take it
814 if ! is_yes "$mode"; then
818 debug "finding compressor: $compressors (via $mode)"
819 # check for compressor validity
820 local c prog map=/boot/System.map-$kernel
821 for c in $compressors; do
844 # any existing sym will work
849 die "Unknown compressor $c"
852 if sym_exists $map $sym && [ -x $prog ]; then
858 debug "using gzip for compressor (fallback)"
862 # compresses kernel image image
863 # in function so we could retry with other compressor on failure
865 local compressor="$1" IMAGE="$2" target="$3" tmp
866 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
868 case "$compressor" in
870 # don't use -9 here since kernel won't understand it
871 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
874 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
877 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
880 gzip -9 < "$IMAGE" > "$tmp" || return $?
883 lzop -9 < "$IMAGE" > "$tmp" || return $?
886 cat < "$IMAGE" > "$tmp" || return $?
890 mv -f "$tmp" "$target"
893 if [ -r /etc/sysconfig/geninitrd ]; then
894 . /etc/sysconfig/geninitrd
897 if [ ! -f /proc/mounts ]; then
898 warn "/proc filesystem not mounted, may cause wrong results or failure."
901 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi
903 while [ $# -gt 0 ]; do
913 modulefile=${1#--modules-conf=}
922 --without-bootsplash)
934 --without-fbcondecor)
943 --with-suspend2 | --with-tuxonice)
946 --without-suspend2 | --without-tuxonice)
950 LVMTOOLSVERSION=${1#--lvmversion=}
953 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
955 --lvmtoolsversion|--lvmversion)
972 USE_MULTIPATH=${1#--with-multipath=}
981 BASICMODULES="$BASICMODULES ${1#--with=}"
984 BASICMODULES="$BASICMODULES $2"
988 echo "$PROGRAM: version $VERSION"
998 COMPRESS="${1#--compress=}"
1010 PREMODS="$PREMODS ${1#--preload=}"
1013 PREMODS="$PREMODS $2"
1017 die "--fs option is obsoleted. Use --initrdfs instead"
1020 INITRDFS=${1#--initrdfs=}
1033 if [ -z "$target" ]; then
1035 elif [ -z "$kernel" ]; then
1047 if [ -z "$target" -o -z "$kernel" ]; then
1053 if [ "$(id -u)" != 0 ]; then
1054 die "You need to be root to generate initrd"
1057 if [ -d /lib64 -a -d /usr/lib64 ]; then
1063 initrd_dir=/usr/$_lib/initrd
1064 kernel_version=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d",$1,$2)}')
1065 kernel_version_long=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}')
1068 debug "Using _lib: $_lib"
1069 debug "Using initrd_dir: $initrd_dir"
1071 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1073 # we setup mods after parsing command line args
1074 geninitrd_setup_mods
1076 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1077 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1080 if [ -z "$INITRDFS" ]; then
1081 if [ -n "$FS" ]; then
1082 # FS= can came only via /etc/sysconfig/geninitrd likely?
1083 die "FS configuration option is obsoleted. Use INITRDFS instead"
1087 if [ "$kernel_version" -ge "002005" ]; then
1088 INITRDFS="initramfs"
1096 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1099 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1102 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1105 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1106 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1109 die "Filesystem $INITRDFS on initrd is not supported"
1113 if [ -L "$target" ]; then
1114 target=$(readlink -f "$target")
1117 if [ -n "$img_vers" ]; then
1118 target="$target-$kernel"
1121 if [ -z "$force" -a -f "$target" ]; then
1122 die "$target already exists."
1125 if [ ! -d "/lib/modules/$kernel" ]; then
1126 die "/lib/modules/$kernel is not a directory."
1129 if [ "$kernel_version" -ge "002005" ]; then
1135 for n in $PREMODS; do
1139 if [ "$FBMODULE" ]; then
1140 find_module "$FBMODULE"
1143 # allow forcing loading SCSI and/or IDE modules
1144 # XXX: where ADDSCSI cames from? drop?
1145 if is_yes "$ADDSCSI"; then
1149 # autodetect SATA modules
1152 # XXX: where ADDIDE cames from? drop?
1153 if is_yes "$ADDIDE"; then
1157 if is_yes "$USE_SUSPEND"; then
1158 find_modules_suspend
1161 find_root "$fstab" || exit
1162 debug "Using $rootdev as device for rootfs"
1164 find_modules_for_devpath "$rootdev"
1166 # if USE_MULTIPATH is path to device, scan that too
1167 # this is to bootstrap multipath setup into initrd.
1168 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1169 find_modules_multipath $USE_MULTIPATH
1172 find_module "-$rootFs"
1174 for n in $BASICMODULES; do
1178 if is_yes "$USE_TUXONICE"; then
1182 find_modules_fbsplash
1184 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1185 debug "No modules are needed -- not building initrd image."
1189 debug "Building initrd..."
1190 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1191 RCFILE="$DESTDIR/linuxrc"
1193 chmod a+rx "$RCFILE"
1194 ln -s linuxrc $DESTDIR/init
1196 # create dirs that we really need
1197 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1199 modules_install "$MODULES"
1201 # mknod'ing the devices instead of copying them works both with and
1203 mknod "$DESTDIR/dev/console" c 5 1
1204 mknod "$DESTDIR/dev/null" c 1 3
1205 mknod "$DESTDIR/dev/zero" c 1 5
1206 mknod "$DESTDIR/dev/random" c 1 8
1207 mknod "$DESTDIR/dev/urandom" c 1 9
1209 inst_exec $busybox /bin/busybox
1210 ln -s busybox $DESTDIR/bin/sh
1211 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1212 ln -s busybox $DESTDIR/bin/initrd-busybox
1216 # initrd generated by:
1221 add_linuxrc <<-'EOF'
1222 read CMDLINE < /proc/cmdline; export CMDLINE
1224 for arg in $CMDLINE; do
1225 if [ "${arg}" = "debuginitrd" ]; then
1228 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1229 DEBUGINITRD=${arg##debuginitrd=}
1231 if [ "${arg##root=}" != "${arg}" ]; then
1234 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1235 ROOTFSFLAGS=${arg##rootfsflags=}
1239 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1240 if [ "$DEBUGINITRD" = "sh" ]; then
1243 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1244 add_linuxrc <<-'EOF'
1245 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1248 add_linuxrc <<-'EOF'
1252 add_linuxrc <<-'EOF'
1260 if [ "$DEBUGINITRD" ]; then
1265 modules_add_linuxrc $MODULES
1267 # TODO: rewrite for busybox
1268 #if [ -n "$loopDev" ]; then
1269 # if [ ! -d /initrd ]; then
1273 # cp -a "$loopDev" "$DESTDIR/dev"
1274 # cp -a "$rootdev" "$DESTDIR/dev"
1275 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1276 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1277 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1278 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1281 if is_yes "$USE_UDEV"; then
1285 find_modules_uvesafb
1290 initrd_gen_multipath
1293 if is_yes "$have_nfs"; then
1299 initrd_gen_setrootdev
1305 # additional devs always needed
1306 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1308 initrd_gen_stop_udevd
1310 if [ "$INITRDFS" = "initramfs" ]; then
1311 initrd_gen_initramfs_switchroot
1317 initrd_gen_fbcondecor
1319 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1321 debug "Creating $INITRDFS image $IMAGE"
1324 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1325 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
1326 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1328 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1329 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1330 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
1331 # We don't need this directory, so let's save space
1332 rm -rf "$tmpmnt"/lost+found
1334 debug "Copy recursively $DESTDIR -> $tmpmnt"
1335 cp -a $DESTDIR/* $tmpmnt
1341 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel initrd"
1344 mkcramfs "$DESTDIR" "$IMAGE"
1347 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1350 die "Filesystem $INITRDFS not supported by $PROGRAM"
1353 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1354 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1355 CONFIG_BLK_DEV_RAM_SIZE=4096
1358 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1359 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1360 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1361 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1364 if ! is_no "$COMPRESS"; then
1365 compressor=$(find_compressor "$COMPRESS")
1366 debug "Compressing $target with $compressor"
1368 # TODO: the image name (specified from kernel.spec) already contains
1369 # extension, which is .gz most of the time.
1370 compress_image "$compressor" "$IMAGE" "$target" || {
1371 if [ $compressor != gzip ]; then
1372 warn "Could not compress with $compressor, retrying with gzip"
1373 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1375 die "Could not compress image with $compressor"
1379 cp -a "$IMAGE" "$target"
1382 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1383 initrd_gen_bootsplash "$target"
1385 rm -rf "$DESTDIR" "$IMAGE"
1387 # vim:ts=4:sw=4:noet:fdm=marker