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!"
790 # we need /init being real file, not symlink, otherwise the initramfs will
791 # not be ran by pid 1 which is required for switch_root
792 mv $DESTDIR/linuxrc $DESTDIR/init
793 ln -s init $DESTDIR/linuxrc
796 # find if $symbol exists in System.map $mapfile
800 if [ ! -f $mapfile ]; then
801 # missing mapfile (not a pld kernel?)
805 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
808 # find best compressor (or forced one) for initrd
811 # fastest initrd decompression speed is first
812 local compressors='lzo gzip xz lzma bzip2'
814 # a specified one, take it
815 if ! is_yes "$mode"; then
819 debug "finding compressor: $compressors (via $mode)"
820 # check for compressor validity
821 local c prog map=/boot/System.map-$kernel
822 for c in $compressors; do
845 # any existing sym will work
850 die "Unknown compressor $c"
853 if sym_exists $map $sym && [ -x $prog ]; then
859 debug "using gzip for compressor (fallback)"
863 # compresses kernel image image
864 # in function so we could retry with other compressor on failure
866 local compressor="$1" IMAGE="$2" target="$3" tmp
867 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
869 case "$compressor" in
871 # don't use -9 here since kernel won't understand it
872 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
875 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
878 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
881 gzip -9 < "$IMAGE" > "$tmp" || return $?
884 lzop -9 < "$IMAGE" > "$tmp" || return $?
887 cat < "$IMAGE" > "$tmp" || return $?
891 mv -f "$tmp" "$target"
894 if [ -r /etc/sysconfig/geninitrd ]; then
895 . /etc/sysconfig/geninitrd
898 if [ ! -f /proc/mounts ]; then
899 warn "/proc filesystem not mounted, may cause wrong results or failure."
902 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi
904 while [ $# -gt 0 ]; do
914 modulefile=${1#--modules-conf=}
923 --without-bootsplash)
935 --without-fbcondecor)
944 --with-suspend2 | --with-tuxonice)
947 --without-suspend2 | --without-tuxonice)
951 LVMTOOLSVERSION=${1#--lvmversion=}
954 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
956 --lvmtoolsversion|--lvmversion)
973 USE_MULTIPATH=${1#--with-multipath=}
982 BASICMODULES="$BASICMODULES ${1#--with=}"
985 BASICMODULES="$BASICMODULES $2"
989 echo "$PROGRAM: version $VERSION"
999 COMPRESS="${1#--compress=}"
1011 PREMODS="$PREMODS ${1#--preload=}"
1014 PREMODS="$PREMODS $2"
1018 die "--fs option is obsoleted. Use --initrdfs instead"
1021 INITRDFS=${1#--initrdfs=}
1034 if [ -z "$target" ]; then
1036 elif [ -z "$kernel" ]; then
1048 if [ -z "$target" -o -z "$kernel" ]; then
1054 if [ "$(id -u)" != 0 ]; then
1055 die "You need to be root to generate initrd"
1058 if [ -d /lib64 -a -d /usr/lib64 ]; then
1064 initrd_dir=/usr/$_lib/initrd
1065 kernel_version=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d",$1,$2)}')
1066 kernel_version_long=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}')
1069 debug "Using _lib: $_lib"
1070 debug "Using initrd_dir: $initrd_dir"
1072 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1074 # we setup mods after parsing command line args
1075 geninitrd_setup_mods
1077 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1078 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1081 if [ -z "$INITRDFS" ]; then
1082 if [ -n "$FS" ]; then
1083 # FS= can came only via /etc/sysconfig/geninitrd likely?
1084 die "FS configuration option is obsoleted. Use INITRDFS instead"
1088 if [ "$kernel_version" -ge "002005" ]; then
1089 INITRDFS="initramfs"
1097 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1100 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1103 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1106 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1107 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1110 die "Filesystem $INITRDFS on initrd is not supported"
1114 if [ -L "$target" ]; then
1115 target=$(readlink -f "$target")
1118 if [ -n "$img_vers" ]; then
1119 target="$target-$kernel"
1122 if [ -z "$force" -a -f "$target" ]; then
1123 die "$target already exists."
1126 if [ ! -d "/lib/modules/$kernel" ]; then
1127 die "/lib/modules/$kernel is not a directory."
1130 if [ "$kernel_version" -ge "002005" ]; then
1136 for n in $PREMODS; do
1140 if [ "$FBMODULE" ]; then
1141 find_module "$FBMODULE"
1144 # allow forcing loading SCSI and/or IDE modules
1145 # XXX: where ADDSCSI cames from? drop?
1146 if is_yes "$ADDSCSI"; then
1150 # autodetect SATA modules
1153 # XXX: where ADDIDE cames from? drop?
1154 if is_yes "$ADDIDE"; then
1158 if is_yes "$USE_SUSPEND"; then
1159 find_modules_suspend
1162 find_root "$fstab" || exit
1163 debug "Using $rootdev as device for rootfs"
1165 find_modules_for_devpath "$rootdev"
1167 # if USE_MULTIPATH is path to device, scan that too
1168 # this is to bootstrap multipath setup into initrd.
1169 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1170 find_modules_multipath $USE_MULTIPATH
1173 find_module "-$rootFs"
1175 for n in $BASICMODULES; do
1179 if is_yes "$USE_TUXONICE"; then
1183 find_modules_fbsplash
1185 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1186 debug "No modules are needed -- not building initrd image."
1190 debug "Building initrd..."
1191 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1192 RCFILE="$DESTDIR/linuxrc"
1194 chmod a+rx "$RCFILE"
1195 ln -s linuxrc $DESTDIR/init
1197 # create dirs that we really need
1198 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1200 modules_install "$MODULES"
1202 # mknod'ing the devices instead of copying them works both with and
1204 mknod "$DESTDIR/dev/console" c 5 1
1205 mknod "$DESTDIR/dev/null" c 1 3
1206 mknod "$DESTDIR/dev/zero" c 1 5
1207 mknod "$DESTDIR/dev/random" c 1 8
1208 mknod "$DESTDIR/dev/urandom" c 1 9
1210 inst_exec $busybox /bin/busybox
1211 ln -s busybox $DESTDIR/bin/sh
1212 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1213 ln -s busybox $DESTDIR/bin/initrd-busybox
1217 # initrd generated by:
1222 add_linuxrc <<-'EOF'
1223 read CMDLINE < /proc/cmdline; export CMDLINE
1225 for arg in $CMDLINE; do
1226 if [ "${arg}" = "debuginitrd" ]; then
1229 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1230 DEBUGINITRD=${arg##debuginitrd=}
1232 if [ "${arg##root=}" != "${arg}" ]; then
1235 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1236 ROOTFSFLAGS=${arg##rootfsflags=}
1240 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1241 if [ "$DEBUGINITRD" = "sh" ]; then
1244 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1245 add_linuxrc <<-'EOF'
1246 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1249 add_linuxrc <<-'EOF'
1253 add_linuxrc <<-'EOF'
1261 if [ "$DEBUGINITRD" ]; then
1266 modules_add_linuxrc $MODULES
1268 # TODO: rewrite for busybox
1269 #if [ -n "$loopDev" ]; then
1270 # if [ ! -d /initrd ]; then
1274 # cp -a "$loopDev" "$DESTDIR/dev"
1275 # cp -a "$rootdev" "$DESTDIR/dev"
1276 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1277 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1278 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1279 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1282 if is_yes "$USE_UDEV"; then
1286 find_modules_uvesafb
1291 initrd_gen_multipath
1294 if is_yes "$have_nfs"; then
1300 initrd_gen_setrootdev
1306 # additional devs always needed
1307 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1309 initrd_gen_stop_udevd
1311 if [ "$INITRDFS" = "initramfs" ]; then
1312 initrd_gen_initramfs_switchroot
1318 initrd_gen_fbcondecor
1320 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1322 debug "Creating $INITRDFS image $IMAGE"
1325 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1326 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
1327 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1329 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1330 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1331 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
1332 # We don't need this directory, so let's save space
1333 rm -rf "$tmpmnt"/lost+found
1335 debug "Copy recursively $DESTDIR -> $tmpmnt"
1336 cp -a $DESTDIR/* $tmpmnt
1342 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel initrd"
1345 mkcramfs "$DESTDIR" "$IMAGE"
1348 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1351 die "Filesystem $INITRDFS not supported by $PROGRAM"
1354 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1355 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1356 CONFIG_BLK_DEV_RAM_SIZE=4096
1359 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1360 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1361 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1362 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1365 if ! is_no "$COMPRESS"; then
1366 compressor=$(find_compressor "$COMPRESS")
1367 debug "Compressing $target with $compressor"
1369 # TODO: the image name (specified from kernel.spec) already contains
1370 # extension, which is .gz most of the time.
1371 compress_image "$compressor" "$IMAGE" "$target" || {
1372 if [ $compressor != gzip ]; then
1373 warn "Could not compress with $compressor, retrying with gzip"
1374 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1376 die "Could not compress image with $compressor"
1380 cp -a "$IMAGE" "$target"
1383 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1384 initrd_gen_bootsplash "$target"
1386 rm -rf "$DESTDIR" "$IMAGE"
1388 # vim:ts=4:sw=4:noet:fdm=marker