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 | awk '!/^[\t ]*#/ { print }')
484 debug "Using modprobe -c to get modules config"
485 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
489 # find modules for $devpath
490 find_modules_for_devpath() {
492 if [ -z "$devpath" ]; then
493 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
496 if [[ "$devpath" = /dev/dm-* ]]; then
497 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
498 devpath=$(dm_node "$devpath")
501 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
502 # sanitize things like:
503 # /dev/block/104:2 -> /dev/cciss/c0d0p2
504 devpath=$(readlink -f "$devpath")
507 debug "Finding modules for device path $devpath"
509 if is_luks "$devpath"; then
510 find_modules_luks "$devpath"
514 if is_nfs "$devpath"; then
515 find_modules_nfs "$devpath"
519 if is_md "$devpath"; then
520 find_modules_md "$devpath"
524 if is_multipath "$devpath"; then
525 if find_modules_multipath "$devpath"; then
532 if is_dmraid "$devpath"; then
533 if find_modules_dmraid "$devpath"; then
539 if is_scsi "$devpath"; then
540 find_modules_scsi "$devpath"
544 if is_ide "$devpath"; then
545 find_modules_ide "$devpath"
549 if [[ "$devpath" == /dev/rd/* ]]; then
555 if [[ "$devpath" == /dev/ida/* ]]; then
556 find_module "cpqarray"
557 rootdev_add=/dev/ida/
561 if [[ "$devpath" == /dev/cciss/* ]]; then
563 rootdev_add=/dev/cciss/
567 if [[ "$devpath" == /dev/ataraid/* ]]; then
569 find_module "ataraid"
570 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
571 if [ -n "$ataraidmodules" ]; then
572 # FIXME: think about modules compiled in kernel
573 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
575 for n in $ataraidmodules; do
578 rootdev_add=/dev/ataraid/
582 # check to see if we need to set up a loopback filesystem
583 if [[ "$devpath" == /dev/loop* ]]; then
584 die "Sorry, root on loop device isn't supported."
585 # TODO: rewrite for bsp and make nfs ready
586 if [ ! -x /sbin/losetup ]; then
587 die "losetup is missing"
589 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
590 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
591 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"
594 line="`awk '/'$key'/ { print $0; }' $fstab`"
595 loopDev="$(echo $line | awk '{print $3}')"
596 loopFs="$(echo $line | awk '{print $4}')"
597 loopFile="$(echo $line | awk '{print $5}')"
599 BASICMODULES="$BASICMODULES -loop"
600 find_module "-$loopFs"
601 BASICMODULES="$BASICMODULES -${loopFs}"
605 if is_lvm "$devpath"; then
606 find_modules_lvm "$devpath"
611 firmware_install_module() {
613 local firmware_files="$2"
615 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
616 # firmware not yet installed
617 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
619 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
621 echo 1 > /sys$DEVPATH/loading
622 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
623 echo 0 > /sys$DEVPATH/loading
626 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
629 for firmware in $firmware_files; do
630 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
631 FIRMWAREDIR=${firmware%/*}
632 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
633 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
634 elif [ -f "/lib/firmware/$firmware" ]; then
635 FIRMWAREDIR=${firmware%/*}
636 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
637 inst /lib/firmware/$firmware /lib/firmware/$firmware
639 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
644 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
651 for mod in $modules; do
653 inst_d "/lib/modules/$kernel/$MODULEDIR"
654 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
655 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
656 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
657 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
662 modules_add_linuxrc() {
666 # module path without optional compression
670 local module=${modpath##*/}; module=${module%$modext}
671 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
672 local genericname=$(echo $module | tr - _)
673 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
674 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
676 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
677 options="scan=sync $options"
680 if [ -n "$verbose" ]; then
682 if [ "$options" ]; then
683 s="$s with options [$options]"
685 if [ "$usleep" ]; then
686 s="$s and $usleep usleep"
688 debug "Loading module [$module]$s"
691 if [ -n "$firmware" ]; then
692 firmware_install_module "$module" "$firmware"
694 for file in $(find_firmware "$module"); do
695 firmware_install_module "$module" "$file"
699 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
700 if [ -n "$usleep" ]; then
701 echo "usleep $usleep" | add_linuxrc
703 if [ "$module" = "scsi_wait_scan" ]; then
704 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
705 echo "rmmod scsi_wait_scan" | add_linuxrc
712 # Generates /dev nodes based on /proc/partitions information.
713 # Needs /proc mounted.
714 # Can be called multiple times.
715 initrd_gen_devices() {
716 if is_yes "$proc_partitions"; then
723 : 'Making device nodes'
724 cat /proc/partitions | (
725 # ignore first two lines: header, empty line
728 while read major minor blocks dev rest; do
731 [ -e $node ] || mknod $node b $major $minor
738 initrd_gen_setrootdev() {
739 debug "Adding rootfs finding based on kernel cmdline root= option support."
742 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
743 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
745 if [ -z "$rootnr" ]; then
746 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
748 if [ -n "$rootnr" ]; then
749 echo "$rootnr" > /proc/sys/kernel/real-root-dev
755 initrd_gen_initramfs_switchroot() {
757 if [ "$rootdev" = "/dev/nfs" ]; then
758 echo "rootfs on NFS root=/dev/nfs"
760 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
763 # parse 'root=xxx' kernel commandline
764 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
766 device=/dev/no_partition_found
767 eval "$(busybox awk -v c="$ROOT" '
769 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
770 num_pattern = "[0-9a-f]" num_pattern_short;
771 dev_pattern = "[hms][a-z][a-z]([0-9])+";
772 partition = "no_partition_found";
776 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
777 if (c ~ "^" num_pattern "$") {
778 maj = sprintf("%s",substr(c,1,2));
779 min = sprintf("%s",substr(c,3));
781 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
782 if (c ~ "^" dev_pattern "$") partition = c;
785 $4 ~ partition { maj = $1; min = $2; }
786 $1 ~ maj && $2 ~ min { partition = $4; }
789 if (maj >= 0 && min >= 0) {
790 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
794 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
795 mknod $device b $maj $min
805 if [ "$device" = '/dev/no_partition_found' ]; then
809 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
811 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
812 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
813 if [ -z "$init" -o ! -x "/newroot$init" ]; then
819 busybox_applet switch_root
821 exec switch_root /newroot $init ${1:+"$@"}
823 echo "Error! initramfs should not reach this place."
824 echo "It probably means you've got old version of busybox, with broken"
825 echo "initramfs support. Trying to boot anyway, but won't promise anything."
827 exec chroot /newroot $init ${1:+"$@"}
829 echo "Failed to chroot!"
832 # we need /init being real file, not symlink, otherwise the initramfs will
833 # not be ran by pid 1 which is required for switch_root
834 mv $DESTDIR/linuxrc $DESTDIR/init
835 ln -s init $DESTDIR/linuxrc
838 # find if $symbol exists in System.map $mapfile
842 if [ ! -f $mapfile ]; then
843 # missing mapfile (not a pld kernel?)
847 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
850 # find best compressor (or forced one) for initrd
853 # fastest initrd decompression speed is first
854 local compressors='lzo gzip xz lzma bzip2'
856 # a specified one, take it
857 if ! is_yes "$mode"; then
861 debug "finding compressor: $compressors (via $mode)"
862 # check for compressor validity
863 local c prog map=/boot/System.map-$kernel
864 for c in $compressors; do
887 # any existing sym will work
892 die "Unknown compressor $c"
895 if sym_exists $map $sym && [ -x $prog ]; then
901 debug "using gzip for compressor (fallback)"
905 # compresses kernel image image
906 # in function so we could retry with other compressor on failure
908 local compressor="$1" IMAGE="$2" target="$3" tmp
909 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
911 case "$compressor" in
913 # don't use -9 here since kernel won't understand it
914 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
917 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
920 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
923 gzip -9 < "$IMAGE" > "$tmp" || return $?
926 lzop -9 < "$IMAGE" > "$tmp" || return $?
929 cat < "$IMAGE" > "$tmp" || return $?
933 mv -f "$tmp" "$target"
936 if [ -r /etc/sysconfig/geninitrd ]; then
937 . /etc/sysconfig/geninitrd
940 if [ ! -f /proc/mounts ]; then
941 warn "/proc filesystem not mounted, may cause wrong results or failure."
944 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
946 while [ $# -gt 0 ]; do
956 modulefile=${1#--modules-conf=}
965 --without-bootsplash)
977 --without-fbcondecor)
986 --with-suspend2 | --with-tuxonice)
989 --without-suspend2 | --without-tuxonice)
993 LVMTOOLSVERSION=${1#--lvmversion=}
996 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
998 --lvmtoolsversion|--lvmversion)
1011 --without-multipath)
1015 USE_MULTIPATH=${1#--with-multipath=}
1024 BASICMODULES="$BASICMODULES ${1#--with=}"
1027 BASICMODULES="$BASICMODULES $2"
1031 echo "$PROGRAM: version $VERSION"
1041 COMPRESS="${1#--compress=}"
1050 STRIP="${1#--strip=}"
1063 PREMODS="$PREMODS ${1#--preload=}"
1066 PREMODS="$PREMODS $2"
1070 die "--fs option is obsoleted. Use --initrdfs instead"
1073 INITRDFS=${1#--initrdfs=}
1086 if [ -z "$target" ]; then
1088 elif [ -z "$kernel" ]; then
1100 if [ -z "$target" -o -z "$kernel" ]; then
1106 if [ "$(id -u)" != 0 ]; then
1107 die "You need to be root to generate initrd"
1110 if [ -d /lib64 -a -d /usr/lib64 ]; then
1116 initrd_dir=/usr/$_lib/initrd
1117 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1118 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1120 debug "# $GENINITRD_RCSID (geninitrd)"
1121 debug "Using _lib: $_lib"
1122 debug "Using initrd_dir: $initrd_dir"
1124 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1126 # we setup mods after parsing command line args
1127 geninitrd_setup_mods
1129 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1130 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1133 if [ -z "$INITRDFS" ]; then
1134 if [ -n "$FS" ]; then
1135 # FS= can came only via /etc/sysconfig/geninitrd likely?
1136 die "FS configuration option is obsoleted. Use INITRDFS instead"
1140 if [ "$kernel_version" -ge "002005" ]; then
1141 INITRDFS="initramfs"
1149 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1152 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1155 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1158 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1159 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1162 die "Filesystem $INITRDFS on initrd is not supported"
1166 if [ -L "$target" ]; then
1167 target=$(readlink -f "$target")
1170 if [ -n "$img_vers" ]; then
1171 target="$target-$kernel"
1174 if [ -z "$force" -a -f "$target" ]; then
1175 die "$target already exists."
1178 if [ ! -d "/lib/modules/$kernel" ]; then
1179 die "/lib/modules/$kernel is not a directory."
1182 if [ "$kernel_version" -ge "002005" ]; then
1188 for n in $PREMODS; do
1192 if [ "$FBMODULE" ]; then
1193 find_module "$FBMODULE"
1196 # autodetect USB keyboards
1199 # allow forcing loading SCSI and/or IDE modules
1200 # XXX: where ADDSCSI cames from? drop?
1201 if is_yes "$ADDSCSI"; then
1205 # autodetect SATA modules
1208 # XXX: where ADDIDE cames from? drop?
1209 if is_yes "$ADDIDE"; then
1213 if is_yes "$USE_SUSPEND"; then
1214 find_modules_suspend
1217 find_root "$fstab" || exit
1218 debug "Using $rootdev as device for rootfs"
1220 find_modules_for_devpath "$rootdev"
1222 # if USE_MULTIPATH is path to device, scan that too
1223 # this is to bootstrap multipath setup into initrd.
1224 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1225 find_modules_multipath $USE_MULTIPATH
1228 find_module "-$rootFs"
1230 for n in $BASICMODULES; do
1234 if is_yes "$USE_TUXONICE"; then
1238 find_modules_fbsplash
1240 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1241 debug "No modules are needed -- not building initrd image."
1245 debug "Building initrd..."
1246 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1247 RCFILE="$DESTDIR/linuxrc"
1249 chmod a+rx "$RCFILE"
1250 ln -s linuxrc $DESTDIR/init
1252 # create dirs that we really need
1253 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1255 modules_install "$MODULES"
1257 # mknod'ing the devices instead of copying them works both with and
1259 mknod "$DESTDIR/dev/console" c 5 1
1260 mknod "$DESTDIR/dev/null" c 1 3
1261 mknod "$DESTDIR/dev/zero" c 1 5
1262 mknod "$DESTDIR/dev/random" c 1 8
1263 mknod "$DESTDIR/dev/urandom" c 1 9
1265 inst_exec $busybox /bin/busybox
1266 ln -s busybox $DESTDIR/bin/sh
1267 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1268 ln -s busybox $DESTDIR/bin/initrd-busybox
1272 # initrd generated by:
1277 add_linuxrc <<-'EOF'
1278 read CMDLINE < /proc/cmdline; export CMDLINE
1280 for arg in $CMDLINE; do
1281 if [ "${arg}" = "debuginitrd" ]; then
1284 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1285 DEBUGINITRD=${arg##debuginitrd=}
1287 if [ "${arg##root=}" != "${arg}" ]; then
1290 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1291 ROOTFSFLAGS=${arg##rootfsflags=}
1295 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1296 if [ "$DEBUGINITRD" = "sh" ]; then
1299 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1300 add_linuxrc <<-'EOF'
1301 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1304 add_linuxrc <<-'EOF'
1308 add_linuxrc <<-'EOF'
1316 if [ "$DEBUGINITRD" ]; then
1321 modules_add_linuxrc $MODULES
1323 # TODO: rewrite for busybox
1324 #if [ -n "$loopDev" ]; then
1325 # if [ ! -d /initrd ]; then
1329 # cp -a "$loopDev" "$DESTDIR/dev"
1330 # cp -a "$rootdev" "$DESTDIR/dev"
1331 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1332 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1333 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1334 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1337 if is_yes "$USE_UDEV"; then
1341 find_modules_uvesafb
1346 initrd_gen_multipath
1349 if is_yes "$have_nfs"; then
1355 initrd_gen_setrootdev
1361 # additional devs always needed
1362 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1364 initrd_gen_stop_udevd
1365 initrd_gen_stop_uvesafb
1367 if [ "$INITRDFS" = "initramfs" ]; then
1368 initrd_gen_initramfs_switchroot
1374 initrd_gen_fbcondecor
1376 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1378 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1379 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1381 debug "Creating $INITRDFS image $IMAGE"
1384 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1385 # NOTE: ext2 label is max 16 chars
1386 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1387 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1389 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1390 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1391 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1392 # We don't need this directory, so let's save space
1393 rm -rf "$tmpmnt"/lost+found
1395 debug "Copy recursively $DESTDIR -> $tmpmnt"
1396 cp -a $DESTDIR/* $tmpmnt
1402 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1405 mkcramfs "$DESTDIR" "$IMAGE"
1408 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1411 die "Filesystem $INITRDFS not supported by $PROGRAM"
1414 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1415 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1416 CONFIG_BLK_DEV_RAM_SIZE=4096
1419 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1420 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1423 if ! is_no "$COMPRESS"; then
1424 compressor=$(find_compressor "$COMPRESS")
1425 debug "Compressing $target with $compressor"
1427 # TODO: the image name (specified from kernel.spec) already contains
1428 # extension, which is .gz most of the time.
1429 compress_image "$compressor" "$IMAGE" "$target" || {
1430 if [ $compressor != gzip ]; then
1431 warn "Could not compress with $compressor, retrying with gzip"
1432 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1434 die "Could not compress image with $compressor"
1438 cp -a "$IMAGE" "$target"
1441 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1442 initrd_gen_bootsplash "$target"
1444 rm -rf "$DESTDIR" "$IMAGE"
1446 # vim:ts=4:sw=4:noet:fdm=marker