7 # based on mkinitrd from RedHat Linux
10 GENINITRD_RCSID='$Revision$ $Date:: $'
11 R=${GENINITRD_RCSID#* *}; VERSION=${R%% *}
14 . /etc/rc.d/init.d/functions
15 . /lib/geninitrd/functions
16 . /etc/sysconfig/system
18 # list of geninitrd modules which need setup routine after commandline args parsing
31 # device node for rootfs from fstab
41 # is /tmp mounted on tmpfs
44 # are /dev nodes already created from /proc/devices info?
48 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
49 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
50 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
51 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
52 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
53 echo " [--with-bootsplash] [--without-bootsplash]"
54 echo " [--with-fbsplash] [--without-fbsplash]"
55 echo " [--with-fbcondecor] [--without-fbcondecor]"
56 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
57 echo " [--with-suspend] [--without-suspend]"
58 echo " [--with-tuxonice] [--without-tuxonice]"
59 echo " [--without-dmraid]"
60 echo " [--with-multipath=DEVPATH] [--without-multipath]"
61 echo " [--without-blkid] [--without-luks]"
62 echo " <initrd-image> <kernel-version>"
66 local kdir kver dir=${target:-/boot}
67 for kdir in /lib/modules/*; do
68 [ -d $kdir ] || continue
70 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
83 [ -n "$verbose" ] && msg "$*" >&2
86 # aborts program abnormally
93 # find program from specified paths
99 debug "find_tool: found $x"
103 debug "find_tool: did not found any of: $@"
107 # loads geninitrd modules
108 geninitrd_load_mods() {
111 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
112 die "$mod geninitrd module can't be loaded"
114 . /lib/geninitrd/mod-$mod.sh
116 GENINITRD_MODS="$GENINITRD_MODS $mod"
120 # setup geninitrd modules
121 geninitrd_setup_mods() {
124 for mod in $GENINITRD_MODS; do
125 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
126 debug "# $rcsid (mod-$mod)"
128 # some mods want init
129 if type setup_mod_$mod > /dev/null; then
135 # append text to /linuxrc
136 # takes STDIN as input
141 # generate code to mount /dev on tmpfs and create initial nodes
142 # can be called multiple times. /dev is cleaned up (umounted) automatically at
145 # we already generated tmpfs code; return
146 if is_yes "$dev_mounted"; then
152 busybox_applet mount mknod mkdir
155 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
156 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
157 mknod /dev/console c 5 1
158 mknod /dev/null c 1 3
159 mknod /dev/zero c 1 5
160 mknod /dev/random c 1 8
161 mknod /dev/snapshot c 10 231
162 mknod /dev/urandom c 1 9
163 mknod /dev/ptmx c 5 2
164 mknod /dev/kmsg c 1 11
171 # generate code to mount /proc on initrd
172 # can be called multiple times
174 if is_yes "$proc_mounted"; then
179 if [ "$INITRDFS" = "initramfs" ]; then
180 # /proc is mounted with initramfs 2.6.22.14 kernel
181 # XXX: remove when it is clear why proc was already mounted
182 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
184 echo "mount -t proc none /proc" | add_linuxrc
188 # generate code to mount /sys on initrd
189 # can be called multiple times
191 if is_yes "$sys_mounted"; then
196 echo "mount -t sysfs none /sys" | add_linuxrc
199 # generate code to mount /tmp on initrd
200 # can be called multiple times
202 if [ "$INITRDFS" = "initramfs" ]; then
203 # initramfs is read-write filesystem, no need for tmpfs
207 if is_yes "$tmp_mounted"; then
212 echo "mount -t tmpfs none /tmp" | add_linuxrc
215 # generate code to mount /run on initrd
216 # can be called multiple times
218 if is_yes "$run_mounted"; then
223 echo "mount -t tmpfs run /run" | add_linuxrc
226 # unmount all mountpoints mounted by geninitrd
230 : Last shell before umounting all and giving control over to real init.
234 if is_yes "$run_mounted"; then
235 echo 'mount --bind /run /newroot/run' | add_linuxrc
236 echo 'umount /run' | add_linuxrc
239 if is_yes "$dev_mounted"; then
240 echo 'umount /dev' | add_linuxrc
243 if is_yes "$sys_mounted"; then
244 echo 'umount /sys' | add_linuxrc
247 if is_yes "$tmp_mounted"; then
248 echo 'umount /tmp' | add_linuxrc
251 if is_yes "$proc_mounted"; then
252 echo 'umount /proc' | add_linuxrc
258 # Checks if busybox has support for APPLET(s)
259 # Exits from geninitrd if the support is not present.
261 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
265 if [ -z "$busybox_functions" ]; then
266 local tmp=$($busybox 2>&1)
268 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
269 if [[ "$tmp" = *applet\ not\ found* ]]; then
271 ln -s $busybox $t/busybox
272 local tmp=$($t/busybox 2>&1)
276 busybox_functions=$(echo "$tmp" | \
277 sed -ne '/Currently defined functions:/,$p' | \
278 xargs | sed -e 's,.*Currently defined functions: ,,'
284 eval have='$'busybox_have_$applet
285 if [ -z "$have" ]; then
286 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
287 if [ "$have" = 0 ]; then
288 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
291 eval busybox_have_$applet=$have
294 if [ $err = 1 ]; then
299 # Extract the .config file from a kernel image
300 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
302 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
303 if [ -n "$kofile" ]; then
304 /lib/geninitrd/extract-ikconfig $kofile
308 # see if config available as separate file
309 if [ -f /boot/config-$kernel ]; then
310 cat /boot/config-$kernel
314 # finally try vmlinuz itself
315 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
318 # Finds module dependencies
322 # Outputs full path to module and it's dependencies
327 # if module is prefixed with dash, we should ignore errors if the module
329 if [ ${module#-} != $module ]; then
334 # This works when user has module-init-tools installed even on 2.4 kernels
336 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
339 if [ $skiperrors = 1 ]; then
344 if ! is_no "$EXIT_IF_MISSING"; then
345 die "$module: module not found for $kernel kernel"
348 warn "$module: module not found for $kernel kernel"
349 warn "If $module isn't compiled in kernel then this initrd may not start your system."
353 while read insmod modpath options; do
354 [ "$insmod" = "insmod" ] && echo $modpath
362 # no firmware support in 2.4 kernels
363 if [ "$kernel_version_long" -lt "002005048" ]; then
366 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
371 local mod depmod module=$1
373 depmod=$(find_depmod $module) || exit 1
374 for mod in $depmod; do
375 mod=${mod#/lib/modules/$kernel/}
377 # add each module only once
379 for m in $MODULES; do
380 [ $m = $mod ] && have=1
382 if [ $have = 0 ]; then
383 MODULES="$MODULES $mod"
388 # install a file to temporary mount image.
389 # it will operate recursively (copying directories)
390 # and will symlink destinations if source is symlink.
392 if [ $# -lt 2 ]; then
393 die 'Usage: inst <file> [<file>] <destination>'
396 local src i=0 c=$(($# - 1))
397 while [ $i -lt $c ]; do
404 local parentDir=$(dirname $DESTDIR$dest)
405 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
406 debug "+ cp $* $DESTDIR$dest"
407 cp -HR "$@" "$DESTDIR$dest"
412 die 'Usage: inst_d <destination> <destination>'
415 install -d "$DESTDIR$dir"
419 # install executable and it's shared libraries
421 if [ $# -lt 2 ]; then
422 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
424 local src i=0 c=$(($# - 1))
425 while [ $i -lt $c ]; do
437 if [ "$obj" != "/lib/ld-linux.so.2" ] && [ "$obj" != "/lib64/ld-linux-x86-64.so.2" ]; then
438 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
442 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
444 inst_exec $lib /$_lib
448 # hack for uclibc linked binaries requiring this fixed path
449 # XXX: shouldn't rpath be used here instead so th
450 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
451 local lib=$DESTDIR/$_lib/libc.so.0
452 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
453 local libdir=$(cd $(dirname "$lib"); pwd)
454 if [ ! -e $DESTDIR$libdir ]; then
455 libdir=$(dirname "$libdir")
457 debug "+ ln -s /$_lib $DESTDIR$libdir"
458 ln -s /$_lib $DESTDIR$libdir
463 # output modules.conf / modprobe.conf
465 echo "$modprobe_conf_cache"
469 # defaults to modprobe -c if not told otherwise, this means include statements
471 cache_modprobe_conf() {
472 if [ "$kernel_version" -lt "002005" ]; then
473 modulefile=/etc/modules.conf
474 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
475 modulefile=/etc/conf.modules
479 if [ -n "$modulefile" ]; then
480 debug "Using $modulefile for modules config"
481 modprobe_conf_cache=$(cat $modulefile)
483 debug "Using modprobe -c to get modules config"
484 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
488 # find modules for $devpath
489 find_modules_for_devpath() {
491 if [ -z "$devpath" ]; then
492 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
495 if [[ "$devpath" = /dev/dm-* ]]; then
496 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
497 devpath=$(dm_node "$devpath")
500 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
501 # sanitize things like:
502 # /dev/block/104:2 -> /dev/cciss/c0d0p2
503 devpath=$(readlink -f "$devpath")
506 debug "Finding modules for device path $devpath"
508 if is_luks "$devpath"; then
509 find_modules_luks "$devpath"
513 if is_nfs "$devpath"; then
514 find_modules_nfs "$devpath"
518 if is_md "$devpath"; then
519 find_modules_md "$devpath"
523 if is_multipath "$devpath"; then
524 if find_modules_multipath "$devpath"; then
531 if is_dmraid "$devpath"; then
532 if find_modules_dmraid "$devpath"; then
538 if is_scsi "$devpath"; then
539 find_modules_scsi "$devpath"
543 if is_ide "$devpath"; then
544 find_modules_ide "$devpath"
548 if [[ "$devpath" == /dev/rd/* ]]; then
554 if [[ "$devpath" == /dev/ida/* ]]; then
555 find_module "cpqarray"
556 rootdev_add=/dev/ida/
560 if [[ "$devpath" == /dev/cciss/* ]]; then
562 rootdev_add=/dev/cciss/
566 if [[ "$devpath" == /dev/ataraid/* ]]; then
568 find_module "ataraid"
569 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
570 if [ -n "$ataraidmodules" ]; then
571 # FIXME: think about modules compiled in kernel
572 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
574 for n in $ataraidmodules; do
577 rootdev_add=/dev/ataraid/
581 # check to see if we need to set up a loopback filesystem
582 if [[ "$devpath" == /dev/loop* ]]; then
583 die "Sorry, root on loop device isn't supported."
584 # TODO: rewrite for bsp and make nfs ready
585 if [ ! -x /sbin/losetup ]; then
586 die "losetup is missing"
588 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
589 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
590 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"
593 line="`awk '/'$key'/ { print $0; }' $fstab`"
594 loopDev="$(echo $line | awk '{print $3}')"
595 loopFs="$(echo $line | awk '{print $4}')"
596 loopFile="$(echo $line | awk '{print $5}')"
598 BASICMODULES="$BASICMODULES -loop"
599 find_module "-$loopFs"
600 BASICMODULES="$BASICMODULES -${loopFs}"
604 if is_lvm "$devpath"; then
605 find_modules_lvm "$devpath"
610 firmware_install_module() {
612 local firmware_files="$2"
614 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
615 # firmware not yet installed
616 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
618 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
620 echo 1 > /sys$DEVPATH/loading
621 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
622 echo 0 > /sys$DEVPATH/loading
625 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
628 for firmware in $firmware_files; do
629 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
630 FIRMWAREDIR=${firmware%/*}
631 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
632 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
633 elif [ -f "/lib/firmware/$firmware" ]; then
634 FIRMWAREDIR=${firmware%/*}
635 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
636 inst /lib/firmware/$firmware /lib/firmware/$firmware
638 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
643 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
650 for mod in $modules; do
652 inst_d "/lib/modules/$kernel/$MODULEDIR"
653 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
654 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
655 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
656 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
661 modules_add_linuxrc() {
665 # module path without optional compression
669 local module=${modpath##*/}; module=${module%$modext}
670 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
671 local genericname=$(echo $module | tr - _)
672 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
673 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
675 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
676 options="scan=sync $options"
679 if [ -n "$verbose" ]; then
681 if [ "$options" ]; then
682 s="$s with options [$options]"
684 if [ "$usleep" ]; then
685 s="$s and $usleep usleep"
687 debug "Loading module [$module]$s"
690 if [ -n "$firmware" ]; then
691 firmware_install_module "$module" "$firmware"
693 for file in $(find_firmware "$module"); do
694 firmware_install_module "$module" "$file"
698 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
699 if [ -n "$usleep" ]; then
700 echo "usleep $usleep" | add_linuxrc
702 if [ "$module" = "scsi_wait_scan" ]; then
703 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
704 echo "rmmod scsi_wait_scan" | add_linuxrc
711 # Generates /dev nodes based on /proc/partitions information.
712 # Needs /proc mounted.
713 # Can be called multiple times.
714 initrd_gen_devices() {
715 if is_yes "$proc_partitions"; then
722 : 'Making device nodes'
723 cat /proc/partitions | (
724 # ignore first two lines: header, empty line
727 while read major minor blocks dev rest; do
730 [ -e $node ] || mknod $node b $major $minor
737 initrd_gen_setrootdev() {
738 debug "Adding rootfs finding based on kernel cmdline root= option support."
741 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
742 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
744 if [ -z "$rootnr" ]; then
745 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
747 if [ -n "$rootnr" ]; then
748 echo "$rootnr" > /proc/sys/kernel/real-root-dev
754 initrd_gen_initramfs_switchroot() {
756 if [ "$rootdev" = "/dev/nfs" ]; then
757 echo "rootfs on NFS root=/dev/nfs"
759 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
762 # parse 'root=xxx' kernel commandline
763 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
765 device=/dev/no_partition_found
766 eval "$(busybox awk -v c="$ROOT" '
768 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
769 num_pattern = "[0-9a-f]" num_pattern_short;
770 dev_pattern = "[hms][a-z][a-z]([0-9])+";
771 partition = "no_partition_found";
775 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
776 if (c ~ "^" num_pattern "$") {
777 maj = sprintf("%s",substr(c,1,2));
778 min = sprintf("%s",substr(c,3));
780 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
781 if (c ~ "^" dev_pattern "$") partition = c;
784 $4 ~ partition { maj = $1; min = $2; }
785 $1 ~ maj && $2 ~ min { partition = $4; }
788 if (maj >= 0 && min >= 0) {
789 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
793 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
794 mknod $device b $maj $min
804 if [ "$device" = '/dev/no_partition_found' ]; then
808 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
810 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
811 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
812 if [ -z "$init" -o ! -x "/newroot$init" ]; then
818 busybox_applet switch_root
820 exec switch_root /newroot $init ${1:+"$@"}
822 echo "Error! initramfs should not reach this place."
823 echo "It probably means you've got old version of busybox, with broken"
824 echo "initramfs support. Trying to boot anyway, but won't promise anything."
826 exec chroot /newroot $init ${1:+"$@"}
828 echo "Failed to chroot!"
831 # we need /init being real file, not symlink, otherwise the initramfs will
832 # not be ran by pid 1 which is required for switch_root
833 mv $DESTDIR/linuxrc $DESTDIR/init
834 ln -s init $DESTDIR/linuxrc
837 # find if $symbol exists in System.map $mapfile
841 if [ ! -f $mapfile ]; then
842 # missing mapfile (not a pld kernel?)
846 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
849 # find best compressor (or forced one) for initrd
852 # fastest initrd decompression speed is first
853 local compressors='lzo gzip xz lzma bzip2'
855 # a specified one, take it
856 if ! is_yes "$mode"; then
860 debug "finding compressor: $compressors (via $mode)"
861 # check for compressor validity
862 local c prog map=/boot/System.map-$kernel
863 for c in $compressors; do
886 # any existing sym will work
891 die "Unknown compressor $c"
894 if sym_exists $map $sym && [ -x $prog ]; then
900 debug "using gzip for compressor (fallback)"
904 # compresses kernel image image
905 # in function so we could retry with other compressor on failure
907 local compressor="$1" IMAGE="$2" target="$3" tmp
908 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
910 case "$compressor" in
912 # don't use -9 here since kernel won't understand it
913 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
916 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
919 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
922 gzip -9 < "$IMAGE" > "$tmp" || return $?
925 lzop -9 < "$IMAGE" > "$tmp" || return $?
928 cat < "$IMAGE" > "$tmp" || return $?
932 mv -f "$tmp" "$target"
935 if [ -r /etc/sysconfig/geninitrd ]; then
936 . /etc/sysconfig/geninitrd
939 if [ ! -f /proc/mounts ]; then
940 warn "/proc filesystem not mounted, may cause wrong results or failure."
943 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
945 while [ $# -gt 0 ]; do
955 modulefile=${1#--modules-conf=}
964 --without-bootsplash)
976 --without-fbcondecor)
985 --with-suspend2 | --with-tuxonice)
988 --without-suspend2 | --without-tuxonice)
992 LVMTOOLSVERSION=${1#--lvmversion=}
995 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
997 --lvmtoolsversion|--lvmversion)
1010 --without-multipath)
1014 USE_MULTIPATH=${1#--with-multipath=}
1023 BASICMODULES="$BASICMODULES ${1#--with=}"
1026 BASICMODULES="$BASICMODULES $2"
1030 echo "$PROGRAM: version $VERSION"
1040 COMPRESS="${1#--compress=}"
1049 STRIP="${1#--strip=}"
1062 PREMODS="$PREMODS ${1#--preload=}"
1065 PREMODS="$PREMODS $2"
1069 die "--fs option is obsoleted. Use --initrdfs instead"
1072 INITRDFS=${1#--initrdfs=}
1085 if [ -z "$target" ]; then
1087 elif [ -z "$kernel" ]; then
1099 if [ -z "$target" -o -z "$kernel" ]; then
1105 if [ "$(id -u)" != 0 ]; then
1106 die "You need to be root to generate initrd"
1109 if [ -d /lib64 -a -d /usr/lib64 ]; then
1115 initrd_dir=/usr/$_lib/initrd
1116 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1117 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1119 debug "# $GENINITRD_RCSID (geninitrd)"
1120 debug "Using _lib: $_lib"
1121 debug "Using initrd_dir: $initrd_dir"
1123 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1125 # we setup mods after parsing command line args
1126 geninitrd_setup_mods
1128 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1129 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1132 if [ -z "$INITRDFS" ]; then
1133 if [ -n "$FS" ]; then
1134 # FS= can came only via /etc/sysconfig/geninitrd likely?
1135 die "FS configuration option is obsoleted. Use INITRDFS instead"
1139 if [ "$kernel_version" -ge "002005" ]; then
1140 INITRDFS="initramfs"
1148 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1151 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1154 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1157 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1158 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1161 die "Filesystem $INITRDFS on initrd is not supported"
1165 if [ -L "$target" ]; then
1166 target=$(readlink -f "$target")
1169 if [ -n "$img_vers" ]; then
1170 target="$target-$kernel"
1173 if [ -z "$force" -a -f "$target" ]; then
1174 die "$target already exists."
1177 if [ ! -d "/lib/modules/$kernel" ]; then
1178 die "/lib/modules/$kernel is not a directory."
1181 if [ "$kernel_version" -ge "002005" ]; then
1187 for n in $PREMODS; do
1191 if [ "$FBMODULE" ]; then
1192 find_module "$FBMODULE"
1195 # autodetect USB keyboards
1198 # allow forcing loading SCSI and/or IDE modules
1199 # XXX: where ADDSCSI cames from? drop?
1200 if is_yes "$ADDSCSI"; then
1204 # autodetect SATA modules
1207 # XXX: where ADDIDE cames from? drop?
1208 if is_yes "$ADDIDE"; then
1212 if is_yes "$USE_SUSPEND"; then
1213 find_modules_suspend
1216 find_root "$fstab" || exit
1217 debug "Using $rootdev as device for rootfs"
1219 find_modules_for_devpath "$rootdev"
1221 # if USE_MULTIPATH is path to device, scan that too
1222 # this is to bootstrap multipath setup into initrd.
1223 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1224 find_modules_multipath $USE_MULTIPATH
1227 find_module "-$rootFs"
1229 for n in $BASICMODULES; do
1233 if is_yes "$USE_TUXONICE"; then
1237 find_modules_fbsplash
1239 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1240 debug "No modules are needed -- not building initrd image."
1244 debug "Building initrd..."
1245 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1246 RCFILE="$DESTDIR/linuxrc"
1248 chmod a+rx "$RCFILE"
1249 ln -s linuxrc $DESTDIR/init
1251 # create dirs that we really need
1252 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1254 modules_install "$MODULES"
1256 # mknod'ing the devices instead of copying them works both with and
1258 mknod "$DESTDIR/dev/console" c 5 1
1259 mknod "$DESTDIR/dev/null" c 1 3
1260 mknod "$DESTDIR/dev/zero" c 1 5
1261 mknod "$DESTDIR/dev/random" c 1 8
1262 mknod "$DESTDIR/dev/urandom" c 1 9
1264 inst_exec $busybox /bin/busybox
1265 ln -s busybox $DESTDIR/bin/sh
1266 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1267 ln -s busybox $DESTDIR/bin/initrd-busybox
1271 # initrd generated by:
1276 add_linuxrc <<-'EOF'
1277 read CMDLINE < /proc/cmdline; export CMDLINE
1279 for arg in $CMDLINE; do
1280 if [ "${arg}" = "debuginitrd" ]; then
1283 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1284 DEBUGINITRD=${arg##debuginitrd=}
1286 if [ "${arg##root=}" != "${arg}" ]; then
1289 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1290 ROOTFSFLAGS=${arg##rootfsflags=}
1294 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1295 if [ "$DEBUGINITRD" = "sh" ]; then
1298 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1299 add_linuxrc <<-'EOF'
1300 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1303 add_linuxrc <<-'EOF'
1307 add_linuxrc <<-'EOF'
1315 if [ "$DEBUGINITRD" ]; then
1320 modules_add_linuxrc $MODULES
1322 # TODO: rewrite for busybox
1323 #if [ -n "$loopDev" ]; then
1324 # if [ ! -d /initrd ]; then
1328 # cp -a "$loopDev" "$DESTDIR/dev"
1329 # cp -a "$rootdev" "$DESTDIR/dev"
1330 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1331 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1332 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1333 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1336 if is_yes "$USE_UDEV"; then
1340 find_modules_uvesafb
1345 initrd_gen_multipath
1348 if is_yes "$have_nfs"; then
1354 initrd_gen_setrootdev
1360 # additional devs always needed
1361 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1363 initrd_gen_stop_udevd
1364 initrd_gen_stop_uvesafb
1366 if [ "$INITRDFS" = "initramfs" ]; then
1367 initrd_gen_initramfs_switchroot
1373 initrd_gen_fbcondecor
1375 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1377 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1378 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1380 debug "Creating $INITRDFS image $IMAGE"
1383 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1384 # NOTE: ext2 label is max 16 chars
1385 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1386 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1388 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1389 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1390 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1391 # We don't need this directory, so let's save space
1392 rm -rf "$tmpmnt"/lost+found
1394 debug "Copy recursively $DESTDIR -> $tmpmnt"
1395 cp -a $DESTDIR/* $tmpmnt
1401 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1404 mkcramfs "$DESTDIR" "$IMAGE"
1407 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1410 die "Filesystem $INITRDFS not supported by $PROGRAM"
1413 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1414 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1415 CONFIG_BLK_DEV_RAM_SIZE=4096
1418 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1419 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1422 if ! is_no "$COMPRESS"; then
1423 compressor=$(find_compressor "$COMPRESS")
1424 debug "Compressing $target with $compressor"
1426 # TODO: the image name (specified from kernel.spec) already contains
1427 # extension, which is .gz most of the time.
1428 compress_image "$compressor" "$IMAGE" "$target" || {
1429 if [ $compressor != gzip ]; then
1430 warn "Could not compress with $compressor, retrying with gzip"
1431 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1433 die "Could not compress image with $compressor"
1437 cp -a "$IMAGE" "$target"
1440 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1441 initrd_gen_bootsplash "$target"
1443 rm -rf "$DESTDIR" "$IMAGE"
1445 # vim:ts=4:sw=4:noet:fdm=marker