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
562 rootdev_add=/dev/cciss/
564 # load hpsa for future kernels, cciss for backwards compat
565 if [ "$kernel_version_long" -ge "003000000" ]; then
566 find_module "hpsa" "-cciss"
567 find_modules_scsi "$devpath"
575 if [[ "$devpath" == /dev/ataraid/* ]]; then
577 find_module "ataraid"
578 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
579 if [ -n "$ataraidmodules" ]; then
580 # FIXME: think about modules compiled in kernel
581 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
583 for n in $ataraidmodules; do
586 rootdev_add=/dev/ataraid/
590 # check to see if we need to set up a loopback filesystem
591 if [[ "$devpath" == /dev/loop* ]]; then
592 die "Sorry, root on loop device isn't supported."
593 # TODO: rewrite for bsp and make nfs ready
594 if [ ! -x /sbin/losetup ]; then
595 die "losetup is missing"
597 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
598 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
599 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"
602 line="`awk '/'$key'/ { print $0; }' $fstab`"
603 loopDev="$(echo $line | awk '{print $3}')"
604 loopFs="$(echo $line | awk '{print $4}')"
605 loopFile="$(echo $line | awk '{print $5}')"
607 BASICMODULES="$BASICMODULES -loop"
608 find_module "-$loopFs"
609 BASICMODULES="$BASICMODULES -${loopFs}"
613 if is_lvm "$devpath"; then
614 find_modules_lvm "$devpath"
619 firmware_install_module() {
621 local firmware_files="$2"
623 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
624 # firmware not yet installed
625 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
627 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
629 echo 1 > /sys$DEVPATH/loading
630 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
631 echo 0 > /sys$DEVPATH/loading
634 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
636 # setup firmware loader agent
637 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
640 for firmware in $firmware_files; do
641 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
642 FIRMWAREDIR=${firmware%/*}
643 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
644 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
645 elif [ -f "/lib/firmware/$firmware" ]; then
646 FIRMWAREDIR=${firmware%/*}
647 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
648 inst /lib/firmware/$firmware /lib/firmware/$firmware
650 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
661 for mod in $modules; do
663 inst_d "/lib/modules/$kernel/$MODULEDIR"
664 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
665 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
666 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
667 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
672 modules_add_linuxrc() {
676 # module path without optional compression
680 local module=${modpath##*/}; module=${module%$modext}
681 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
682 local genericname=$(echo $module | tr - _)
683 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
684 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
686 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
687 options="scan=sync $options"
690 if [ -n "$verbose" ]; then
692 if [ "$options" ]; then
693 s="$s with options [$options]"
695 if [ "$usleep" ]; then
696 s="$s and $usleep usleep"
698 debug "Loading module [$module]$s"
701 if [ -n "$firmware" ]; then
702 firmware_install_module "$module" "$firmware"
704 for file in $(find_firmware "$module"); do
705 firmware_install_module "$module" "$file"
709 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
710 if [ -n "$usleep" ]; then
711 echo "usleep $usleep" | add_linuxrc
713 if [ "$module" = "scsi_wait_scan" ]; then
714 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
715 echo "rmmod scsi_wait_scan" | add_linuxrc
722 # Generates /dev nodes based on /proc/partitions information.
723 # Needs /proc mounted.
724 # Can be called multiple times.
725 initrd_gen_devices() {
726 if is_yes "$proc_partitions"; then
733 : 'Making device nodes'
734 cat /proc/partitions | (
735 # ignore first two lines: header, empty line
738 while read major minor blocks dev rest; do
741 [ -e $node ] || mknod $node b $major $minor
748 initrd_gen_setrootdev() {
749 debug "Adding rootfs finding based on kernel cmdline root= option support."
752 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
753 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
755 if [ -z "$rootnr" ]; then
756 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
758 if [ -n "$rootnr" ]; then
759 echo "$rootnr" > /proc/sys/kernel/real-root-dev
765 initrd_gen_initramfs_switchroot() {
767 if [ "$rootdev" = "/dev/nfs" ]; then
768 echo "rootfs on NFS root=/dev/nfs"
770 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
773 # parse 'root=xxx' kernel commandline
774 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
776 device=/dev/no_partition_found
777 eval "$(busybox awk -v c="$ROOT" '
779 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
780 num_pattern = "[0-9a-f]" num_pattern_short;
781 dev_pattern = "[hms][a-z][a-z]([0-9])+";
782 partition = "no_partition_found";
786 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
787 if (c ~ "^" num_pattern "$") {
788 maj = sprintf("%s",substr(c,1,2));
789 min = sprintf("%s",substr(c,3));
791 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
792 if (c ~ "^" dev_pattern "$") partition = c;
795 $4 == partition { maj = $1; min = $2; }
796 $1 == maj && $2 == min { partition = $4; }
799 if (maj >= 0 && min >= 0) {
800 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
804 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
805 mknod $device b $maj $min
815 if [ "$device" = '/dev/no_partition_found' ]; then
819 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
821 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
822 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
823 if [ -z "$init" -o ! -x "/newroot$init" ]; then
829 busybox_applet switch_root
831 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1 > /dev/null 2>&1
832 exec switch_root /newroot $init ${1:+"$@"}
834 echo "Error! initramfs should not reach this place."
835 echo "It probably means you've got old version of busybox, with broken"
836 echo "initramfs support. Trying to boot anyway, but won't promise anything."
838 exec chroot /newroot $init ${1:+"$@"}
840 echo "Failed to chroot!"
843 # we need /init being real file, not symlink, otherwise the initramfs will
844 # not be ran by pid 1 which is required for switch_root
845 mv $DESTDIR/linuxrc $DESTDIR/init
846 ln -s init $DESTDIR/linuxrc
849 # find if $symbol exists in System.map $mapfile
853 if [ ! -f $mapfile ]; then
854 # missing mapfile (not a pld kernel?)
858 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
861 # find best compressor (or forced one) for initrd
864 # fastest initrd decompression speed is first
865 local compressors='lzo gzip xz lzma bzip2'
867 # a specified one, take it
868 if ! is_yes "$mode"; then
872 debug "finding compressor: $compressors (via $mode)"
873 # check for compressor validity
874 local c prog map=/boot/System.map-$kernel
875 for c in $compressors; do
898 # any existing sym will work
903 die "Unknown compressor $c"
906 if sym_exists $map $sym && [ -x $prog ]; then
912 debug "using gzip for compressor (fallback)"
916 # compresses kernel image image
917 # in function so we could retry with other compressor on failure
919 local compressor="$1" IMAGE="$2" target="$3" tmp
920 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
922 case "$compressor" in
924 # don't use -9 here since kernel won't understand it
925 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
928 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
931 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
934 gzip -9 < "$IMAGE" > "$tmp" || return $?
937 lzop -9 < "$IMAGE" > "$tmp" || return $?
940 cat < "$IMAGE" > "$tmp" || return $?
944 mv -f "$tmp" "$target"
947 if [ -r /etc/sysconfig/geninitrd ]; then
948 . /etc/sysconfig/geninitrd
951 if [ ! -f /proc/mounts ]; then
952 warn "/proc filesystem not mounted, may cause wrong results or failure."
955 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
957 while [ $# -gt 0 ]; do
967 modulefile=${1#--modules-conf=}
976 --without-bootsplash)
988 --without-fbcondecor)
997 --with-suspend2 | --with-tuxonice)
1000 --without-suspend2 | --without-tuxonice)
1004 LVMTOOLSVERSION=${1#--lvmversion=}
1006 --lvmtoolsversion=*)
1007 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1009 --lvmtoolsversion|--lvmversion)
1022 --without-multipath)
1026 USE_MULTIPATH=${1#--with-multipath=}
1035 BASICMODULES="$BASICMODULES ${1#--with=}"
1038 BASICMODULES="$BASICMODULES $2"
1042 echo "$PROGRAM: version $VERSION"
1052 COMPRESS="${1#--compress=}"
1061 STRIP="${1#--strip=}"
1074 PREMODS="$PREMODS ${1#--preload=}"
1077 PREMODS="$PREMODS $2"
1081 die "--fs option is obsoleted. Use --initrdfs instead"
1084 INITRDFS=${1#--initrdfs=}
1097 if [ -z "$target" ]; then
1099 elif [ -z "$kernel" ]; then
1111 if [ -z "$target" -o -z "$kernel" ]; then
1117 if [ "$(id -u)" != 0 ]; then
1118 die "You need to be root to generate initrd"
1121 if [ -d /lib64 -a -d /usr/lib64 ]; then
1127 initrd_dir=/usr/$_lib/initrd
1128 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1129 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1131 debug "# $GENINITRD_RCSID (geninitrd)"
1132 debug "Using _lib: $_lib"
1133 debug "Using initrd_dir: $initrd_dir"
1135 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1137 # we setup mods after parsing command line args
1138 geninitrd_setup_mods
1140 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1141 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1144 if [ -z "$INITRDFS" ]; then
1145 if [ -n "$FS" ]; then
1146 # FS= can came only via /etc/sysconfig/geninitrd likely?
1147 die "FS configuration option is obsoleted. Use INITRDFS instead"
1151 if [ "$kernel_version" -ge "002005" ]; then
1152 INITRDFS="initramfs"
1160 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1163 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1166 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1169 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1170 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1173 die "Filesystem $INITRDFS on initrd is not supported"
1177 if [ -L "$target" ]; then
1178 target=$(readlink -f "$target")
1181 if [ -n "$img_vers" ]; then
1182 target="$target-$kernel"
1185 if [ -z "$force" -a -f "$target" ]; then
1186 die "$target already exists."
1189 if [ ! -d "/lib/modules/$kernel" ]; then
1190 die "/lib/modules/$kernel is not a directory."
1193 if [ "$kernel_version" -ge "002005" ]; then
1199 for n in $PREMODS; do
1203 if [ "$FBMODULE" ]; then
1204 find_module "$FBMODULE"
1207 # autodetect USB keyboards
1210 # allow forcing loading SCSI and/or IDE modules
1211 # XXX: where ADDSCSI cames from? drop?
1212 if is_yes "$ADDSCSI"; then
1216 # autodetect SATA modules
1219 # XXX: where ADDIDE cames from? drop?
1220 if is_yes "$ADDIDE"; then
1224 if is_yes "$USE_SUSPEND"; then
1225 find_modules_suspend
1228 find_root "$fstab" || exit
1229 debug "Using $rootdev as device for rootfs"
1231 find_modules_for_devpath "$rootdev"
1233 # if USE_MULTIPATH is path to device, scan that too
1234 # this is to bootstrap multipath setup into initrd.
1235 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1236 find_modules_multipath $USE_MULTIPATH
1239 find_module "-$rootFs"
1241 for n in $BASICMODULES; do
1245 if is_yes "$USE_TUXONICE"; then
1249 find_modules_fbsplash
1251 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1252 debug "No modules are needed -- not building initrd image."
1256 debug "Building initrd..."
1257 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1258 RCFILE="$DESTDIR/linuxrc"
1260 chmod a+rx "$RCFILE"
1261 ln -s linuxrc $DESTDIR/init
1263 # create dirs that we really need
1264 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1266 modules_install "$MODULES"
1268 # mknod'ing the devices instead of copying them works both with and
1270 mknod "$DESTDIR/dev/console" c 5 1
1271 mknod "$DESTDIR/dev/null" c 1 3
1272 mknod "$DESTDIR/dev/zero" c 1 5
1273 mknod "$DESTDIR/dev/random" c 1 8
1274 mknod "$DESTDIR/dev/urandom" c 1 9
1276 inst_exec $busybox /bin/busybox
1277 ln -s busybox $DESTDIR/bin/sh
1278 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1279 ln -s busybox $DESTDIR/bin/initrd-busybox
1283 # initrd generated by:
1288 add_linuxrc <<-'EOF'
1289 read CMDLINE < /proc/cmdline; export CMDLINE
1291 for arg in $CMDLINE; do
1292 if [ "${arg}" = "debuginitrd" ]; then
1295 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1296 DEBUGINITRD=${arg##debuginitrd=}
1298 if [ "${arg##root=}" != "${arg}" ]; then
1301 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1302 ROOTFSFLAGS=${arg##rootfsflags=}
1306 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1307 if [ "$DEBUGINITRD" = "sh" ]; then
1310 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1311 add_linuxrc <<-'EOF'
1312 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1315 add_linuxrc <<-'EOF'
1319 add_linuxrc <<-'EOF'
1327 if [ "$DEBUGINITRD" ]; then
1332 modules_add_linuxrc $MODULES
1334 # TODO: rewrite for busybox
1335 #if [ -n "$loopDev" ]; then
1336 # if [ ! -d /initrd ]; then
1340 # cp -a "$loopDev" "$DESTDIR/dev"
1341 # cp -a "$rootdev" "$DESTDIR/dev"
1342 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1343 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1344 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1345 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1348 if is_yes "$USE_UDEV"; then
1352 find_modules_uvesafb
1357 initrd_gen_multipath
1360 if is_yes "$have_nfs"; then
1366 initrd_gen_setrootdev
1372 # additional devs always needed
1373 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1375 initrd_gen_stop_udevd
1376 initrd_gen_stop_uvesafb
1378 if [ "$INITRDFS" = "initramfs" ]; then
1379 initrd_gen_initramfs_switchroot
1385 initrd_gen_fbcondecor
1387 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1389 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1390 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1392 debug "Creating $INITRDFS image $IMAGE"
1395 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1396 # NOTE: ext2 label is max 16 chars
1397 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1398 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1400 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1401 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1402 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1403 # We don't need this directory, so let's save space
1404 rm -rf "$tmpmnt"/lost+found
1406 debug "Copy recursively $DESTDIR -> $tmpmnt"
1407 cp -a $DESTDIR/* $tmpmnt
1413 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1416 mkcramfs "$DESTDIR" "$IMAGE"
1419 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1422 die "Filesystem $INITRDFS not supported by $PROGRAM"
1425 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1426 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1427 CONFIG_BLK_DEV_RAM_SIZE=4096
1428 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1431 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1432 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1435 if ! is_no "$COMPRESS"; then
1436 compressor=$(find_compressor "$COMPRESS")
1437 debug "Compressing $target with $compressor"
1439 # TODO: the image name (specified from kernel.spec) already contains
1440 # extension, which is .gz most of the time.
1441 compress_image "$compressor" "$IMAGE" "$target" || {
1442 if [ $compressor != gzip ]; then
1443 warn "Could not compress with $compressor, retrying with gzip"
1444 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1446 die "Could not compress image with $compressor"
1450 cp -a "$IMAGE" "$target"
1453 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1454 initrd_gen_bootsplash "$target"
1456 rm -rf "$DESTDIR" "$IMAGE"
1458 # vim:ts=4:sw=4:noet:fdm=marker