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=rom $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 mount -o mode=0755 -t tmpfs none /dev
156 mknod /dev/console c 5 1
157 mknod /dev/null c 1 3
158 mknod /dev/zero c 1 5
159 mknod /dev/random c 1 8
160 mknod /dev/snapshot c 10 231
161 mknod /dev/urandom c 1 9
167 # generate code to mount /proc on initrd
168 # can be called multiple times
170 if is_yes "$proc_mounted"; then
175 if [ "$INITRDFS" = "initramfs" ]; then
176 # /proc is mounted with initramfs 2.6.22.14 kernel
177 # XXX: remove when it is clear why proc was already mounted
178 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
180 echo "mount -t proc none /proc" | add_linuxrc
184 # generate code to mount /sys on initrd
185 # can be called multiple times
187 if is_yes "$sys_mounted"; then
192 echo "mount -t sysfs none /sys" | add_linuxrc
195 # generate code to mount /tmp on initrd
196 # can be called multiple times
198 if [ "$INITRDFS" = "initramfs" ]; then
199 # initramfs is read-write filesystem, no need for tmpfs
203 if is_yes "$tmp_mounted"; then
208 echo "mount -t tmpfs none /tmp" | add_linuxrc
211 # unmount all mountpoints mounted by geninitrd
215 : Last shell before umounting all and giving control over to real init.
219 if is_yes "$dev_mounted"; then
220 echo 'umount /dev' | add_linuxrc
223 if is_yes "$sys_mounted"; then
224 echo 'umount /sys' | add_linuxrc
227 if is_yes "$tmp_mounted"; then
228 echo 'umount /tmp' | add_linuxrc
231 if is_yes "$proc_mounted"; then
232 echo 'umount /proc' | add_linuxrc
238 # Checks if busybox has support for APPLET(s)
239 # Exits from geninitrd if the support is not present.
241 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
245 if [ -z "$busybox_functions" ]; then
246 local tmp=$($busybox 2>&1)
248 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
249 if [[ "$tmp" = *applet\ not\ found* ]]; then
251 ln -s $busybox $t/busybox
252 local tmp=$($t/busybox 2>&1)
256 busybox_functions=$(echo "$tmp" | \
257 sed -ne '/Currently defined functions:/,$p' | \
258 xargs | sed -e 's,.*Currently defined functions: ,,'
264 eval have='$'busybox_have_$applet
265 if [ -z "$have" ]; then
266 have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
267 if [ "$have" = 0 ]; then
268 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
271 eval busybox_have_$applet=$have
274 if [ $err = 1 ]; then
279 # Extract the .config file from a kernel image
280 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
282 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
283 if [ -n "$kofile" ]; then
284 /lib/geninitrd/extract-ikconfig $kofile
288 # see if config available as separate file
289 if [ -f /boot/config-$kernel ]; then
290 cat /boot/config-$kernel
294 # finally try vmlinuz itself
295 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
298 # Finds module dependencies
302 # Outputs full path to module and it's dependencies
307 # if module is prefixed with dash, we should ignore errors if the module
309 if [ ${module#-} != $module ]; then
314 # This works when user has module-init-tools installed even on 2.4 kernels
316 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
319 if [ $skiperrors = 1 ]; then
324 if ! is_no "$EXIT_IF_MISSING"; then
325 die "$module: module not found for $kernel kernel"
328 warn "$module: module not found for $kernel kernel"
329 warn "If $module isn't compiled in kernel then this initrd may not start your system."
333 while read insmod modpath options; do
334 [ "$insmod" = "insmod" ] && echo $modpath
342 # no firmware support in 2.4 kernels
343 if [ "$kernel_version_long" -lt "002005048" ]; then
346 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
351 local mod depmod module=$1
353 depmod=$(find_depmod $module) || exit 1
354 for mod in $depmod; do
355 mod=${mod#/lib/modules/$kernel/}
357 # add each module only once
359 for m in $MODULES; do
360 [ $m = $mod ] && have=1
362 if [ $have = 0 ]; then
363 MODULES="$MODULES $mod"
368 # install a file to temporary mount image.
369 # it will operate recursively (copying directories)
370 # and will symlink destinations if source is symlink.
372 if [ $# -lt 2 ]; then
373 die 'Usage: inst <file> [<file>] <destination>'
376 local src i=0 c=$(($# - 1))
377 while [ $i -lt $c ]; do
384 local parentDir=$(dirname $DESTDIR$dest)
385 [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
386 debug "+ cp $* $DESTDIR$dest"
387 cp -HR "$@" "$DESTDIR$dest"
392 die 'Usage: inst_d <destination> <destination>'
395 install -d "$DESTDIR$dir"
399 # install executable and it's shared libraries
401 if [ $# -lt 2 ]; then
402 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
404 local src i=0 c=$(($# - 1))
405 while [ $i -lt $c ]; do
415 local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
417 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
419 inst_exec $lib /$_lib
423 # hack for uclibc linked binaries requiring this fixed path
424 # XXX: shouldn't rpath be used here instead so th
425 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
426 local lib=$DESTDIR/$_lib/libc.so.0
427 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
428 local libdir=$(cd $(dirname "$lib"); pwd)
429 if [ ! -e $DESTDIR$libdir ]; then
430 libdir=$(dirname "$libdir")
432 debug "+ ln -s /$_lib $DESTDIR$libdir"
433 ln -s /$_lib $DESTDIR$libdir
438 # output modules.conf / modprobe.conf
440 echo "$modprobe_conf_cache"
444 # defaults to modprobe -c if not told otherwise, this means include statements
446 cache_modprobe_conf() {
447 if [ "$kernel_version" -lt "002005" ]; then
448 modulefile=/etc/modules.conf
449 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
450 modulefile=/etc/conf.modules
454 if [ -n "$modulefile" ]; then
455 debug "Using $modulefile for modules config"
456 modprobe_conf_cache=$(cat $modulefile)
458 debug "Using modprobe -c to get modules config"
459 modprobe_conf_cache=$(modprobe -c --set-version $kernel)
463 # find modules for $devpath
464 find_modules_for_devpath() {
466 if [ -z "$devpath" ]; then
467 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
470 if [[ "$devpath" = /dev/dm-* ]]; then
471 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
472 devpath=$(dm_node "$devpath")
475 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
476 # sanitize things like:
477 # /dev/block/104:2 -> /dev/cciss/c0d0p2
478 devpath=$(readlink -f "$devpath")
481 debug "Finding modules for device path $devpath"
483 if is_luks "$devpath"; then
484 find_modules_luks "$devpath"
488 if is_nfs "$devpath"; then
489 find_modules_nfs "$devpath"
493 if is_md "$devpath"; then
494 find_modules_md "$devpath"
498 if is_multipath "$devpath"; then
499 if find_modules_multipath "$devpath"; then
506 if is_dmraid "$devpath"; then
507 if find_modules_dmraid "$devpath"; then
513 if is_scsi "$devpath"; then
514 find_modules_scsi "$devpath"
518 if is_ide "$devpath"; then
519 find_modules_ide "$devpath"
523 if [[ "$devpath" == /dev/rd/* ]]; then
529 if [[ "$devpath" == /dev/ida/* ]]; then
530 find_module "cpqarray"
531 rootdev_add=/dev/ida/
535 if [[ "$devpath" == /dev/cciss/* ]]; then
537 rootdev_add=/dev/cciss/
541 if [[ "$devpath" == /dev/ataraid/* ]]; then
543 find_module "ataraid"
544 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
545 if [ -n "$ataraidmodules" ]; then
546 # FIXME: think about modules compiled in kernel
547 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
549 for n in $ataraidmodules; do
552 rootdev_add=/dev/ataraid/
556 # check to see if we need to set up a loopback filesystem
557 if [[ "$devpath" == /dev/loop* ]]; then
558 die "Sorry, root on loop device isn't supported."
559 # TODO: rewrite for bsp and make nfs ready
560 if [ ! -x /sbin/losetup ]; then
561 die "losetup is missing"
563 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
564 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
565 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"
568 line="`awk '/'$key'/ { print $0; }' $fstab`"
569 loopDev="$(echo $line | awk '{print $3}')"
570 loopFs="$(echo $line | awk '{print $4}')"
571 loopFile="$(echo $line | awk '{print $5}')"
573 BASICMODULES="$BASICMODULES -loop"
574 find_module "-$loopFs"
575 BASICMODULES="$BASICMODULES -${loopFs}"
579 if is_lvm "$devpath"; then
580 find_modules_lvm "$devpath"
585 firmware_install_module() {
587 local firmware_files="$2"
589 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
590 # firmware not yet installed
591 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
593 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
595 echo 1 > /sys$DEVPATH/loading
596 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
597 echo 0 > /sys$DEVPATH/loading
600 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
603 for firmware in $firmware_files; do
604 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
605 FIRMWAREDIR=${firmware%/*}
606 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
607 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
608 elif [ -f "/lib/firmware/$firmware" ]; then
609 FIRMWAREDIR=${firmware%/*}
610 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
611 inst /lib/firmware/$firmware /lib/firmware/$firmware
613 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
618 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
625 for mod in $modules; do
627 inst_d "/lib/modules/$kernel/$MODULEDIR"
628 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
629 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
630 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
631 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
636 modules_add_linuxrc() {
640 # module path without optional compression
644 local module=${modpath##*/}; module=${module%$modext}
645 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
646 local genericname=$(echo $module | tr - _)
647 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
648 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
650 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
651 options="scan=sync $options"
654 if [ -n "$verbose" ]; then
656 if [ "$options" ]; then
657 s="$s with options [$options]"
659 if [ "$usleep" ]; then
660 s="$s and $usleep usleep"
662 debug "Loading module [$module]$s"
665 if [ -n "$firmware" ]; then
666 firmware_install_module "$module" "$firmware"
668 for file in $(find_firmware "$module"); do
669 firmware_install_module "$module" "$file"
673 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
674 if [ -n "$usleep" ]; then
675 echo "usleep $usleep" | add_linuxrc
677 if [ "$module" = "scsi_wait_scan" ]; then
678 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
679 echo "rmmod scsi_wait_scan" | add_linuxrc
686 # Generates /dev nodes based on /proc/partitions information.
687 # Needs /proc mounted.
688 # Can be called multiple times.
689 initrd_gen_devices() {
690 if is_yes "$proc_partitions"; then
697 : 'Making device nodes'
698 cat /proc/partitions | (
699 # ignore first two lines: header, empty line
702 while read major minor blocks dev rest; do
705 [ -e $node ] || mknod $node b $major $minor
712 initrd_gen_setrootdev() {
713 debug "Adding rootfs finding based on kernel cmdline root= option support."
716 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
717 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
719 if [ -z "$rootnr" ]; then
720 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
722 if [ -n "$rootnr" ]; then
723 echo "$rootnr" > /proc/sys/kernel/real-root-dev
729 initrd_gen_initramfs_switchroot() {
731 if [ "$rootdev" = "/dev/nfs" ]; then
732 echo "rootfs on NFS root=/dev/nfs"
734 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
737 # parse 'root=xxx' kernel commandline
738 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
740 device=/dev/no_partition_found
741 eval "$(busybox awk -v c="$ROOT" '
743 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
744 num_pattern = "[0-9a-f]" num_pattern_short;
745 dev_pattern = "[hms][a-z][a-z]([0-9])+";
746 partition = "no_partition_found";
750 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
751 if (c ~ "^" num_pattern "$") {
752 maj = sprintf("%s",substr(c,1,2));
753 min = sprintf("%s",substr(c,3));
755 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
756 if (c ~ "^" dev_pattern "$") partition = c;
759 $4 ~ partition { maj = $1; min = $2; }
760 $1 ~ maj && $2 ~ min { partition = $4; }
763 if (maj >= 0 && min >= 0) {
764 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
768 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
769 mknod $device b $maj $min
779 if [ "$device" = '/dev/no_partition_found' ]; then
783 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
785 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
786 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
787 if [ -z "$init" -o ! -x "/newroot$init" ]; then
793 busybox_applet switch_root
795 exec switch_root /newroot $init ${1:+"$@"}
797 echo "Error! initramfs should not reach this place."
798 echo "It probably means you've got old version of busybox, with broken"
799 echo "initramfs support. Trying to boot anyway, but won't promise anything."
801 exec chroot /newroot $init ${1:+"$@"}
803 echo "Failed to chroot!"
806 # we need /init being real file, not symlink, otherwise the initramfs will
807 # not be ran by pid 1 which is required for switch_root
808 mv $DESTDIR/linuxrc $DESTDIR/init
809 ln -s init $DESTDIR/linuxrc
812 # find if $symbol exists in System.map $mapfile
816 if [ ! -f $mapfile ]; then
817 # missing mapfile (not a pld kernel?)
821 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
824 # find best compressor (or forced one) for initrd
827 # fastest initrd decompression speed is first
828 local compressors='lzo gzip xz lzma bzip2'
830 # a specified one, take it
831 if ! is_yes "$mode"; then
835 debug "finding compressor: $compressors (via $mode)"
836 # check for compressor validity
837 local c prog map=/boot/System.map-$kernel
838 for c in $compressors; do
861 # any existing sym will work
866 die "Unknown compressor $c"
869 if sym_exists $map $sym && [ -x $prog ]; then
875 debug "using gzip for compressor (fallback)"
879 # compresses kernel image image
880 # in function so we could retry with other compressor on failure
882 local compressor="$1" IMAGE="$2" target="$3" tmp
883 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
885 case "$compressor" in
887 # don't use -9 here since kernel won't understand it
888 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
891 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
894 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
897 gzip -9 < "$IMAGE" > "$tmp" || return $?
900 lzop -9 < "$IMAGE" > "$tmp" || return $?
903 cat < "$IMAGE" > "$tmp" || return $?
907 mv -f "$tmp" "$target"
910 if [ -r /etc/sysconfig/geninitrd ]; then
911 . /etc/sysconfig/geninitrd
914 if [ ! -f /proc/mounts ]; then
915 warn "/proc filesystem not mounted, may cause wrong results or failure."
918 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
920 while [ $# -gt 0 ]; do
930 modulefile=${1#--modules-conf=}
939 --without-bootsplash)
951 --without-fbcondecor)
960 --with-suspend2 | --with-tuxonice)
963 --without-suspend2 | --without-tuxonice)
967 LVMTOOLSVERSION=${1#--lvmversion=}
970 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
972 --lvmtoolsversion|--lvmversion)
989 USE_MULTIPATH=${1#--with-multipath=}
998 BASICMODULES="$BASICMODULES ${1#--with=}"
1001 BASICMODULES="$BASICMODULES $2"
1005 echo "$PROGRAM: version $VERSION"
1015 COMPRESS="${1#--compress=}"
1024 STRIP="${1#--strip=}"
1037 PREMODS="$PREMODS ${1#--preload=}"
1040 PREMODS="$PREMODS $2"
1044 die "--fs option is obsoleted. Use --initrdfs instead"
1047 INITRDFS=${1#--initrdfs=}
1060 if [ -z "$target" ]; then
1062 elif [ -z "$kernel" ]; then
1074 if [ -z "$target" -o -z "$kernel" ]; then
1080 if [ "$(id -u)" != 0 ]; then
1081 die "You need to be root to generate initrd"
1084 if [ -d /lib64 -a -d /usr/lib64 ]; then
1090 initrd_dir=/usr/$_lib/initrd
1091 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1092 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1094 debug "# $GENINITRD_RCSID (geninitrd)"
1095 debug "Using _lib: $_lib"
1096 debug "Using initrd_dir: $initrd_dir"
1098 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1100 # we setup mods after parsing command line args
1101 geninitrd_setup_mods
1103 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1104 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1107 if [ -z "$INITRDFS" ]; then
1108 if [ -n "$FS" ]; then
1109 # FS= can came only via /etc/sysconfig/geninitrd likely?
1110 die "FS configuration option is obsoleted. Use INITRDFS instead"
1114 if [ "$kernel_version" -ge "002005" ]; then
1115 INITRDFS="initramfs"
1123 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1126 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1129 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1132 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1133 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1136 die "Filesystem $INITRDFS on initrd is not supported"
1140 if [ -L "$target" ]; then
1141 target=$(readlink -f "$target")
1144 if [ -n "$img_vers" ]; then
1145 target="$target-$kernel"
1148 if [ -z "$force" -a -f "$target" ]; then
1149 die "$target already exists."
1152 if [ ! -d "/lib/modules/$kernel" ]; then
1153 die "/lib/modules/$kernel is not a directory."
1156 if [ "$kernel_version" -ge "002005" ]; then
1162 for n in $PREMODS; do
1166 if [ "$FBMODULE" ]; then
1167 find_module "$FBMODULE"
1170 # autodetect USB keyboards
1173 # allow forcing loading SCSI and/or IDE modules
1174 # XXX: where ADDSCSI cames from? drop?
1175 if is_yes "$ADDSCSI"; then
1179 # autodetect SATA modules
1182 # XXX: where ADDIDE cames from? drop?
1183 if is_yes "$ADDIDE"; then
1187 if is_yes "$USE_SUSPEND"; then
1188 find_modules_suspend
1191 find_root "$fstab" || exit
1192 debug "Using $rootdev as device for rootfs"
1194 find_modules_for_devpath "$rootdev"
1196 # if USE_MULTIPATH is path to device, scan that too
1197 # this is to bootstrap multipath setup into initrd.
1198 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1199 find_modules_multipath $USE_MULTIPATH
1202 find_module "-$rootFs"
1204 for n in $BASICMODULES; do
1208 if is_yes "$USE_TUXONICE"; then
1212 find_modules_fbsplash
1214 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1215 debug "No modules are needed -- not building initrd image."
1219 debug "Building initrd..."
1220 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1221 RCFILE="$DESTDIR/linuxrc"
1223 chmod a+rx "$RCFILE"
1224 ln -s linuxrc $DESTDIR/init
1226 # create dirs that we really need
1227 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1229 modules_install "$MODULES"
1231 # mknod'ing the devices instead of copying them works both with and
1233 mknod "$DESTDIR/dev/console" c 5 1
1234 mknod "$DESTDIR/dev/null" c 1 3
1235 mknod "$DESTDIR/dev/zero" c 1 5
1236 mknod "$DESTDIR/dev/random" c 1 8
1237 mknod "$DESTDIR/dev/urandom" c 1 9
1239 inst_exec $busybox /bin/busybox
1240 ln -s busybox $DESTDIR/bin/sh
1241 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1242 ln -s busybox $DESTDIR/bin/initrd-busybox
1246 # initrd generated by:
1251 add_linuxrc <<-'EOF'
1252 read CMDLINE < /proc/cmdline; export CMDLINE
1254 for arg in $CMDLINE; do
1255 if [ "${arg}" = "debuginitrd" ]; then
1258 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1259 DEBUGINITRD=${arg##debuginitrd=}
1261 if [ "${arg##root=}" != "${arg}" ]; then
1264 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1265 ROOTFSFLAGS=${arg##rootfsflags=}
1269 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1270 if [ "$DEBUGINITRD" = "sh" ]; then
1273 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1274 add_linuxrc <<-'EOF'
1275 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1278 add_linuxrc <<-'EOF'
1282 add_linuxrc <<-'EOF'
1290 if [ "$DEBUGINITRD" ]; then
1295 modules_add_linuxrc $MODULES
1297 # TODO: rewrite for busybox
1298 #if [ -n "$loopDev" ]; then
1299 # if [ ! -d /initrd ]; then
1303 # cp -a "$loopDev" "$DESTDIR/dev"
1304 # cp -a "$rootdev" "$DESTDIR/dev"
1305 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1306 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1307 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1308 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1311 if is_yes "$USE_UDEV"; then
1315 find_modules_uvesafb
1320 initrd_gen_multipath
1323 if is_yes "$have_nfs"; then
1329 initrd_gen_setrootdev
1335 # additional devs always needed
1336 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1338 initrd_gen_stop_udevd
1339 initrd_gen_stop_uvesafb
1341 if [ "$INITRDFS" = "initramfs" ]; then
1342 initrd_gen_initramfs_switchroot
1348 initrd_gen_fbcondecor
1350 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1352 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1353 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1355 debug "Creating $INITRDFS image $IMAGE"
1358 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1359 # NOTE: ext2 label is max 16 chars
1360 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1361 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1363 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1364 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1365 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1366 # We don't need this directory, so let's save space
1367 rm -rf "$tmpmnt"/lost+found
1369 debug "Copy recursively $DESTDIR -> $tmpmnt"
1370 cp -a $DESTDIR/* $tmpmnt
1376 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1379 mkcramfs "$DESTDIR" "$IMAGE"
1382 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1385 die "Filesystem $INITRDFS not supported by $PROGRAM"
1388 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1389 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1390 CONFIG_BLK_DEV_RAM_SIZE=4096
1393 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1394 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1397 if ! is_no "$COMPRESS"; then
1398 compressor=$(find_compressor "$COMPRESS")
1399 debug "Compressing $target with $compressor"
1401 # TODO: the image name (specified from kernel.spec) already contains
1402 # extension, which is .gz most of the time.
1403 compress_image "$compressor" "$IMAGE" "$target" || {
1404 if [ $compressor != gzip ]; then
1405 warn "Could not compress with $compressor, retrying with gzip"
1406 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1408 die "Could not compress image with $compressor"
1412 cp -a "$IMAGE" "$target"
1415 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1416 initrd_gen_bootsplash "$target"
1418 rm -rf "$DESTDIR" "$IMAGE"
1420 # vim:ts=4:sw=4:noet:fdm=marker