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
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 GENINITRD_MODS="$GENINITRD_MODS $mod"
119 # setup geninitrd modules
120 geninitrd_setup_mods() {
123 for mod in $GENINITRD_MODS; do
124 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
125 debug "# $rcsid (mod-$mod)"
127 # some mods want init
128 if type setup_mod_$mod > /dev/null; then
134 # append text to /linuxrc
135 # takes STDIN as input
140 # generate code to mount /dev on tmpfs and create initial nodes
141 # can be called multiple times. /dev is cleaned up (umounted) automatically at
144 if [ "$INITRDFS" = "initramfs" ]; then
145 # initramfs is read-write filesystem, no need for tmpfs
149 # we already generated tmpfs code; return
150 if is_yes "$dev_mounted"; then
156 busybox_applet mount mknod mkdir
159 mount -o mode=0755 -t tmpfs none /dev
160 mknod /dev/console c 5 1
161 mknod /dev/null c 1 3
162 mknod /dev/zero c 1 5
163 mknod /dev/random c 1 8
164 mknod /dev/urandom c 1 9
170 # generate code to mount /proc on initrd
171 # can be called multiple times
173 if is_yes "$proc_mounted"; then
178 if [ "$INITRDFS" = "initramfs" ]; then
179 # /proc is mounted with initramfs 2.6.22.14 kernel
180 # XXX: remove when it is clear why proc was already mounted
181 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
183 echo "mount -t proc none /proc" | add_linuxrc
187 # generate code to mount /sys on initrd
188 # can be called multiple times
190 if is_yes "$sys_mounted"; then
195 echo "mount -t sysfs none /sys" | add_linuxrc
198 # generate code to mount /tmp on initrd
199 # can be called multiple times
201 if [ "$INITRDFS" = "initramfs" ]; then
202 # initramfs is read-write filesystem, no need for tmpfs
206 if is_yes "$tmp_mounted"; then
211 echo "mount -t tmpfs none /tmp" | add_linuxrc
214 # unmount all mountpoints mounted by geninitrd
218 : Last shell before umounting all and giving control over to real init.
222 if is_yes "$dev_mounted"; then
223 echo 'umount /dev' | add_linuxrc
226 if is_yes "$sys_mounted"; then
227 echo 'umount /sys' | add_linuxrc
230 if is_yes "$tmp_mounted"; then
231 echo 'umount /tmp' | add_linuxrc
234 if is_yes "$proc_mounted"; then
235 echo 'umount /proc' | add_linuxrc
241 # Checks if busybox has support for APPLET(s)
242 # Exits from geninitrd if the support is not present.
244 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
248 if [ -z "$busybox_functions" ]; then
249 local tmp=$($busybox 2>&1)
251 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
252 if [[ "$tmp" = *applet\ not\ found* ]]; then
254 ln -s $busybox $t/busybox
255 local tmp=$($t/busybox 2>&1)
259 busybox_functions=$(echo "$tmp" | \
260 sed -ne '/Currently defined functions:/,$p' | \
261 xargs | sed -e 's,.*Currently defined functions: ,,'
267 eval have='$'busybox_have_$applet
268 if [ -z "$have" ]; then
269 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
270 if [ "$have" = 0 ]; then
271 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
274 eval busybox_have_$applet=$have
277 if [ $err = 1 ]; then
282 # Extract the .config file from a kernel image
283 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
285 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
286 if [ -n "$kofile" ]; then
287 /lib/geninitrd/extract-ikconfig $kofile
290 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
294 # Finds module dependencies
298 # Outputs full path to module and it's dependencies
303 # if module is prefixed with dash, we should ignore errors if the module
305 if [ ${module#-} != $module ]; then
310 # This works when user has module-init-tools installed even on 2.4 kernels
312 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
315 if [ $skiperrors = 1 ]; then
320 if ! is_no "$EXIT_IF_MISSING"; then
321 die "$module: module not found for $kernel kernel"
324 warn "$module: module not found for $kernel kernel"
325 warn "If $module isn't compiled in kernel then this initrd may not start your system."
329 while read insmod modpath options; do
330 [ "$insmod" = "insmod" ] && echo $modpath
337 # no firmware support in 2.4 kernels
338 if [ "$kernel_version_long" -lt "002005048" ]; then
341 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
346 local mod depmod module=$1
348 depmod=$(find_depmod $module) || exit 1
349 for mod in $depmod; do
350 mod=${mod#/lib/modules/$kernel/}
352 # add each module only once
354 for m in $MODULES; do
355 [ $m = $mod ] && have=1
357 if [ $have = 0 ]; then
358 MODULES="$MODULES $mod"
363 # install a file to temporary mount image.
364 # it will operate recursively (copying directories)
365 # and will symlink destinations if source is symlink.
367 if [ $# -lt 2 ]; then
368 die 'Usage: inst <file> [<file>] <destination>'
371 local src i=0 c=$(($# - 1))
372 while [ $i -lt $c ]; do
379 local parentDir=$(dirname $DESTDIR$dest)
380 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
381 debug "+ cp $* $DESTDIR$dest"
382 cp -HR "$@" "$DESTDIR$dest"
387 die 'Usage: inst_d <destination> <destination>'
390 install -d "$DESTDIR$dir"
394 # install executable and it's shared libraries
396 if [ $# -lt 2 ]; then
397 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
399 local src i=0 c=$(($# - 1))
400 while [ $i -lt $c ]; do
410 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
412 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
414 inst_exec $lib /$_lib
418 # hack for uclibc linked binaries requiring this fixed path
419 # XXX: shouldn't rpath be used here instead so th
420 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
421 local lib=$DESTDIR/$_lib/libc.so.0
422 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
423 local libdir=$(cd $(dirname "$lib"); pwd)
424 if [ ! -e $DESTDIR$libdir ]; then
425 libdir=$(dirname "$libdir")
427 debug "+ ln -s /$_lib $DESTDIR$libdir"
428 ln -s /$_lib $DESTDIR$libdir
433 # output modules.conf / modprobe.conf
435 echo "$modprobe_conf_cache"
439 # defaults to modprobe -c if not told otherwise, this means include statements
441 cache_modprobe_conf() {
442 if [ "$kernel_version" -lt "002005" ]; then
443 modulefile=/etc/modules.conf
444 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
445 modulefile=/etc/conf.modules
449 if [ -n "$modulefile" ]; then
450 debug "Using $modulefile for modules config"
451 modprobe_conf_cache=$(cat $modulefile)
453 debug "Using modprobe -c to get modules config"
454 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
458 # find modules for $devpath
459 find_modules_for_devpath() {
461 if [ -z "$devpath" ]; then
462 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
465 if [[ "$devpath" = /dev/dm-* ]]; then
466 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
467 devpath=$(dm_node "$devpath")
470 if [ -L "$devpath" ] && ! is_lvm "$devpath"; then
471 # sanitize things like:
472 # /dev/block/104:2 -> /dev/cciss/c0d0p2
473 devpath=$(readlink -f "$devpath")
476 debug "Finding modules for device path $devpath"
478 if is_luks "$devpath"; then
479 find_modules_luks "$devpath"
483 if is_nfs "$devpath"; then
484 find_modules_nfs "$devpath"
488 if is_md "$devpath"; then
489 find_modules_md "$devpath"
493 if is_multipath "$devpath"; then
494 if find_modules_multipath "$devpath"; then
501 if is_dmraid "$devpath"; then
502 if find_modules_dmraid "$devpath"; then
508 if is_scsi "$devpath"; then
509 find_modules_scsi "$devpath"
513 if is_ide "$devpath"; then
514 find_modules_ide "$devpath"
518 if [[ "$devpath" == /dev/rd/* ]]; then
524 if [[ "$devpath" == /dev/ida/* ]]; then
525 find_module "cpqarray"
526 rootdev_add=/dev/ida/
530 if [[ "$devpath" == /dev/cciss/* ]]; then
532 rootdev_add=/dev/cciss/
536 if [[ "$devpath" == /dev/ataraid/* ]]; then
538 find_module "ataraid"
539 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
540 if [ -n "$ataraidmodules" ]; then
541 # FIXME: think about modules compiled in kernel
542 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
544 for n in $ataraidmodules; do
547 rootdev_add=/dev/ataraid/
551 # check to see if we need to set up a loopback filesystem
552 if [[ "$devpath" == /dev/loop* ]]; then
553 die "Sorry, root on loop device isn't supported."
554 # TODO: rewrite for bsp and make nfs ready
555 if [ ! -x /sbin/losetup ]; then
556 die "losetup is missing"
558 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
559 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
560 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"
563 line="`awk '/'$key'/ { print $0; }' $fstab`"
564 loopDev="$(echo $line | awk '{print $3}')"
565 loopFs="$(echo $line | awk '{print $4}')"
566 loopFile="$(echo $line | awk '{print $5}')"
568 BASICMODULES="$BASICMODULES -loop"
569 find_module "-$loopFs"
570 BASICMODULES="$BASICMODULES -${loopFs}"
574 if is_lvm "$devpath"; then
575 find_modules_lvm "$devpath"
580 firmware_install_module() {
582 local firmware_files="$2"
584 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
585 # firmware not yet installed
586 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
588 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
590 echo 1 > /sys$DEVPATH/loading
591 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
592 echo 0 > /sys$DEVPATH/loading
595 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
598 for firmware in $firmware_files; do
599 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
600 FIRMWAREDIR=${firmware%/*}
601 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
602 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
603 elif [ -f "/lib/firmware/$firmware" ]; then
604 FIRMWAREDIR=${firmware%/*}
605 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
606 inst /lib/firmware/$firmware /lib/firmware/$firmware
608 die "firmware file /lib/firmware/$firmware nor /lib/firmware/$kernel/$firmware found."
613 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
620 for mod in $modules; do
622 inst_d "/lib/modules/$kernel/$MODULEDIR"
623 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
624 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
628 modules_add_linuxrc() {
632 # module path without optional compression
636 local module=${modpath##*/}; module=${module%$modext}
637 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
638 local genericname=$(echo $module | tr - _)
639 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
640 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
642 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
643 options="scan=sync $options"
646 if [ -n "$verbose" ]; then
648 if [ "$options" ]; then
649 s="$s with options [$options]"
651 if [ "$usleep" ]; then
652 s="$s and $usleep usleep"
654 debug "Loading module [$module]$s"
657 if [ -n "$firmware" ]; then
658 firmware_install_module "$module" "$firmware"
660 for file in $(find_firmware "$module"); do
661 firmware_install_module "$module" "$file"
665 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
666 if [ -n "$usleep" ]; then
667 echo "usleep $usleep" | add_linuxrc
669 if [ "$module" = "scsi_wait_scan" ]; then
670 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
671 echo "rmmod scsi_wait_scan" | add_linuxrc
678 # Generates /dev nodes based on /proc/partitions information.
679 # Needs /proc mounted.
680 # Can be called multiple times.
681 initrd_gen_devices() {
682 if is_yes "$proc_partitions"; then
689 : 'Making device nodes'
690 cat /proc/partitions | (
691 # ignore first two lines: header, empty line
694 while read major minor blocks dev rest; do
697 [ -e $node ] || mknod $node b $major $minor
704 initrd_gen_setrootdev() {
705 debug "Adding rootfs finding based on kernel cmdline root= option support."
708 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
709 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
711 if [ -z "$rootnr" ]; then
712 rootnr="$(busybox ls -lL ${ROOT} | awk '{if (/^b/) { print 256 * $3 + $4; }}')"
714 if [ -n "$rootnr" ]; then
715 echo "$rootnr" > /proc/sys/kernel/real-root-dev
721 initrd_gen_initramfs_switchroot() {
723 if [ "$rootdev" = "/dev/nfs" ]; then
724 echo "rootfs on NFS root=/dev/nfs"
726 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
729 # parse 'root=xxx' kernel commandline
730 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
732 device=/dev/no_partition_found
733 eval "$(busybox awk -v c="$ROOT" '
735 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
736 num_pattern = "[0-9a-f]" num_pattern_short;
737 dev_pattern = "[hms][a-z][a-z]([0-9])+";
738 partition = "no_partition_found";
742 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
743 if (c ~ "^" num_pattern "$") {
744 maj = sprintf("%s",substr(c,1,2));
745 min = sprintf("%s",substr(c,3));
747 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
748 if (c ~ "^" dev_pattern "$") partition = c;
751 $4 ~ partition { maj = $1; min = $2; }
752 $1 ~ maj && $2 ~ min { partition = $4; }
755 if (maj >= 0 && min >= 0) {
756 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
760 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
761 mknod $device b $maj $min
771 if [ "$device" = '/dev/no_partition_found' ]; then
775 [ -n "$ROOTFSFLAG" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
777 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot
778 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
779 if [ -z "$init" -o ! -x "/newroot$init" ]; then
785 busybox_applet switch_root
787 exec switch_root /newroot $init ${1:+"$@"}
789 echo "Error! initramfs should not reach this place."
790 echo "It probably means you've got old version of busybox, with broken"
791 echo "initramfs support. Trying to boot anyway, but won't promise anything."
793 exec chroot /newroot $init ${1:+"$@"}
795 echo "Failed to chroot!"
798 # we need /init being real file, not symlink, otherwise the initramfs will
799 # not be ran by pid 1 which is required for switch_root
800 mv $DESTDIR/linuxrc $DESTDIR/init
801 ln -s init $DESTDIR/linuxrc
804 # find if $symbol exists in System.map $mapfile
808 if [ ! -f $mapfile ]; then
809 # missing mapfile (not a pld kernel?)
813 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
816 # find best compressor (or forced one) for initrd
819 # fastest initrd decompression speed is first
820 local compressors='lzo gzip xz lzma bzip2'
822 # a specified one, take it
823 if ! is_yes "$mode"; then
827 debug "finding compressor: $compressors (via $mode)"
828 # check for compressor validity
829 local c prog map=/boot/System.map-$kernel
830 for c in $compressors; do
853 # any existing sym will work
858 die "Unknown compressor $c"
861 if sym_exists $map $sym && [ -x $prog ]; then
867 debug "using gzip for compressor (fallback)"
871 # compresses kernel image image
872 # in function so we could retry with other compressor on failure
874 local compressor="$1" IMAGE="$2" target="$3" tmp
875 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
877 case "$compressor" in
879 # don't use -9 here since kernel won't understand it
880 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
883 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
886 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
889 gzip -9 < "$IMAGE" > "$tmp" || return $?
892 lzop -9 < "$IMAGE" > "$tmp" || return $?
895 cat < "$IMAGE" > "$tmp" || return $?
899 mv -f "$tmp" "$target"
902 if [ -r /etc/sysconfig/geninitrd ]; then
903 . /etc/sysconfig/geninitrd
906 if [ ! -f /proc/mounts ]; then
907 warn "/proc filesystem not mounted, may cause wrong results or failure."
910 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi
912 while [ $# -gt 0 ]; do
922 modulefile=${1#--modules-conf=}
931 --without-bootsplash)
943 --without-fbcondecor)
952 --with-suspend2 | --with-tuxonice)
955 --without-suspend2 | --without-tuxonice)
959 LVMTOOLSVERSION=${1#--lvmversion=}
962 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
964 --lvmtoolsversion|--lvmversion)
981 USE_MULTIPATH=${1#--with-multipath=}
990 BASICMODULES="$BASICMODULES ${1#--with=}"
993 BASICMODULES="$BASICMODULES $2"
997 echo "$PROGRAM: version $VERSION"
1007 COMPRESS="${1#--compress=}"
1019 PREMODS="$PREMODS ${1#--preload=}"
1022 PREMODS="$PREMODS $2"
1026 die "--fs option is obsoleted. Use --initrdfs instead"
1029 INITRDFS=${1#--initrdfs=}
1042 if [ -z "$target" ]; then
1044 elif [ -z "$kernel" ]; then
1056 if [ -z "$target" -o -z "$kernel" ]; then
1062 if [ "$(id -u)" != 0 ]; then
1063 die "You need to be root to generate initrd"
1066 if [ -d /lib64 -a -d /usr/lib64 ]; then
1072 initrd_dir=/usr/$_lib/initrd
1073 kernel_version=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d",$1,$2)}')
1074 kernel_version_long=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}')
1076 debug "# $GENINITRD_RCSID (geninitrd)"
1077 debug "Using _lib: $_lib"
1078 debug "Using initrd_dir: $initrd_dir"
1080 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1082 # we setup mods after parsing command line args
1083 geninitrd_setup_mods
1085 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1086 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1089 if [ -z "$INITRDFS" ]; then
1090 if [ -n "$FS" ]; then
1091 # FS= can came only via /etc/sysconfig/geninitrd likely?
1092 die "FS configuration option is obsoleted. Use INITRDFS instead"
1096 if [ "$kernel_version" -ge "002005" ]; then
1097 INITRDFS="initramfs"
1105 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1108 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1111 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1114 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1115 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1118 die "Filesystem $INITRDFS on initrd is not supported"
1122 if [ -L "$target" ]; then
1123 target=$(readlink -f "$target")
1126 if [ -n "$img_vers" ]; then
1127 target="$target-$kernel"
1130 if [ -z "$force" -a -f "$target" ]; then
1131 die "$target already exists."
1134 if [ ! -d "/lib/modules/$kernel" ]; then
1135 die "/lib/modules/$kernel is not a directory."
1138 if [ "$kernel_version" -ge "002005" ]; then
1144 for n in $PREMODS; do
1148 if [ "$FBMODULE" ]; then
1149 find_module "$FBMODULE"
1152 # allow forcing loading SCSI and/or IDE modules
1153 # XXX: where ADDSCSI cames from? drop?
1154 if is_yes "$ADDSCSI"; then
1158 # autodetect SATA modules
1161 # XXX: where ADDIDE cames from? drop?
1162 if is_yes "$ADDIDE"; then
1166 if is_yes "$USE_SUSPEND"; then
1167 find_modules_suspend
1170 find_root "$fstab" || exit
1171 debug "Using $rootdev as device for rootfs"
1173 find_modules_for_devpath "$rootdev"
1175 # if USE_MULTIPATH is path to device, scan that too
1176 # this is to bootstrap multipath setup into initrd.
1177 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1178 find_modules_multipath $USE_MULTIPATH
1181 find_module "-$rootFs"
1183 for n in $BASICMODULES; do
1187 if is_yes "$USE_TUXONICE"; then
1191 find_modules_fbsplash
1193 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1194 debug "No modules are needed -- not building initrd image."
1198 debug "Building initrd..."
1199 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1200 RCFILE="$DESTDIR/linuxrc"
1202 chmod a+rx "$RCFILE"
1203 ln -s linuxrc $DESTDIR/init
1205 # create dirs that we really need
1206 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1208 modules_install "$MODULES"
1210 # mknod'ing the devices instead of copying them works both with and
1212 mknod "$DESTDIR/dev/console" c 5 1
1213 mknod "$DESTDIR/dev/null" c 1 3
1214 mknod "$DESTDIR/dev/zero" c 1 5
1215 mknod "$DESTDIR/dev/random" c 1 8
1216 mknod "$DESTDIR/dev/urandom" c 1 9
1218 inst_exec $busybox /bin/busybox
1219 ln -s busybox $DESTDIR/bin/sh
1220 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1221 ln -s busybox $DESTDIR/bin/initrd-busybox
1225 # initrd generated by:
1230 add_linuxrc <<-'EOF'
1231 read CMDLINE < /proc/cmdline; export CMDLINE
1233 for arg in $CMDLINE; do
1234 if [ "${arg}" = "debuginitrd" ]; then
1237 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1238 DEBUGINITRD=${arg##debuginitrd=}
1240 if [ "${arg##root=}" != "${arg}" ]; then
1243 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1244 ROOTFSFLAGS=${arg##rootfsflags=}
1248 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1249 if [ "$DEBUGINITRD" = "sh" ]; then
1252 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1253 add_linuxrc <<-'EOF'
1254 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1257 add_linuxrc <<-'EOF'
1261 add_linuxrc <<-'EOF'
1269 if [ "$DEBUGINITRD" ]; then
1274 modules_add_linuxrc $MODULES
1276 # TODO: rewrite for busybox
1277 #if [ -n "$loopDev" ]; then
1278 # if [ ! -d /initrd ]; then
1282 # cp -a "$loopDev" "$DESTDIR/dev"
1283 # cp -a "$rootdev" "$DESTDIR/dev"
1284 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1285 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1286 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1287 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1290 if is_yes "$USE_UDEV"; then
1294 find_modules_uvesafb
1299 initrd_gen_multipath
1302 if is_yes "$have_nfs"; then
1308 initrd_gen_setrootdev
1314 # additional devs always needed
1315 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1317 initrd_gen_stop_udevd
1319 if [ "$INITRDFS" = "initramfs" ]; then
1320 initrd_gen_initramfs_switchroot
1326 initrd_gen_fbcondecor
1328 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1330 debug "Creating $INITRDFS image $IMAGE"
1333 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1334 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
1335 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1337 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1338 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1339 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
1340 # We don't need this directory, so let's save space
1341 rm -rf "$tmpmnt"/lost+found
1343 debug "Copy recursively $DESTDIR -> $tmpmnt"
1344 cp -a $DESTDIR/* $tmpmnt
1350 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel initrd"
1353 mkcramfs "$DESTDIR" "$IMAGE"
1356 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1359 die "Filesystem $INITRDFS not supported by $PROGRAM"
1362 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1363 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1364 CONFIG_BLK_DEV_RAM_SIZE=4096
1367 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1368 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1369 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1370 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1373 if ! is_no "$COMPRESS"; then
1374 compressor=$(find_compressor "$COMPRESS")
1375 debug "Compressing $target with $compressor"
1377 # TODO: the image name (specified from kernel.spec) already contains
1378 # extension, which is .gz most of the time.
1379 compress_image "$compressor" "$IMAGE" "$target" || {
1380 if [ $compressor != gzip ]; then
1381 warn "Could not compress with $compressor, retrying with gzip"
1382 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1384 die "Could not compress image with $compressor"
1388 cp -a "$IMAGE" "$target"
1391 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1392 initrd_gen_bootsplash "$target"
1394 rm -rf "$DESTDIR" "$IMAGE"
1396 # vim:ts=4:sw=4:noet:fdm=marker