7 # based on mkinitrd from RedHat Linux
13 . /etc/rc.d/init.d/functions
14 . /lib/geninitrd/functions
15 . /etc/sysconfig/system
17 # list of geninitrd modules which need setup routine after commandline args parsing
30 # device node for rootfs from fstab
40 # is /tmp mounted on tmpfs
43 # are /dev nodes already created from /proc/devices info?
47 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
48 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
49 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
50 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
51 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
52 echo " [--with-bootsplash] [--without-bootsplash]"
53 echo " [--with-fbsplash] [--without-fbsplash]"
54 echo " [--with-fbcondecor] [--without-fbcondecor]"
55 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
56 echo " [--with-suspend] [--without-suspend]"
57 echo " [--with-tuxonice] [--without-tuxonice]"
58 echo " [--without-dmraid]"
59 echo " [--with-multipath=DEVPATH] [--without-multipath]"
60 echo " [--without-blkid] [--without-luks]"
61 echo " <initrd-image> <kernel-version>"
65 local kdir kver dir=${target:-/boot}
66 for kdir in /lib/modules/*; do
67 [ -d $kdir ] || continue
69 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
82 [ -n "$verbose" ] && msg "$*" >&3
86 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
89 # add initrd code to print to kmsg
90 # @param string message
91 # @param int loglevel. defaults to "6" (info)
94 # KERN_EMERG "0" Emergency messages, system is about to crash or is unstable
95 # KERN_ALERT "1" Something bad happened and action must be taken immediately
96 # KERN_CRIT "2" A critical condition occurred like a serious hardware/software failure
97 # KERN_ERR "3" An error condition, often used by drivers to indicate difficulties with the hardware
98 # KERN_WARNING "4" A warning, meaning nothing serious by itself but might indicate problems
99 # KERN_NOTICE "5" Nothing serious, but notably nevertheless. Often used to report security events.
100 # KERN_INFO "6" Informational message e.g. startup information at driver initialization
101 # KERN_DEBUG "7" Debug messages
102 # KERN_CONT "c" "continued" line of log printout (only done after a line that had no enclosing \n)
104 local msg="$1" level=${2:-6}
105 echo "echo '<$level>$msg' > /dev/kmsg" | add_linuxrc
108 # aborts program abnormally
115 # find program from specified paths
118 local paths="$initrd_dir /bin /sbin /usr/bin /usr/sbin"
120 debug "find_tool: checking $x"
123 verbose "find_tool: found $x"
129 debug "find_tool: checking $p/$b"
130 if [ -x "$p/$b" ]; then
132 verbose "find_tool: found $p/$b"
138 debug "find_tool: did not find any of: $n"
142 # loads geninitrd modules
143 geninitrd_load_mods() {
146 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
147 die "$mod geninitrd module can't be loaded"
149 . /lib/geninitrd/mod-$mod.sh
151 GENINITRD_MODS="$GENINITRD_MODS $mod"
155 # setup geninitrd modules
156 geninitrd_setup_mods() {
159 for mod in $GENINITRD_MODS; do
162 # some mods want init
163 if type setup_mod_$mod > /dev/null; then
169 # append text to /linuxrc
170 # takes STDIN as input
175 # generate code to mount /dev on tmpfs and create initial nodes
176 # can be called multiple times. /dev is cleaned up (umounted) automatically at
179 # we already generated tmpfs code; return
180 if is_yes "$dev_mounted"; then
186 busybox_applet mount mknod mkdir
189 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
190 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
191 mknod -m 600 /dev/console c 5 1
192 mknod -m 666 /dev/null c 1 3
193 mknod -m 666 /dev/zero c 1 5
194 mknod -m 666 /dev/random c 1 8
195 mknod -m 600 /dev/snapshot c 10 231
196 mknod -m 666 /dev/urandom c 1 9
197 mknod -m 666 /dev/ptmx c 5 2
198 mknod -m 644 /dev/kmsg c 1 11
208 [ ! -r /etc/sysconfig/console ] && return
209 . /etc/sysconfig/console
210 if [ -n "$CONSOLEFONT" ]; then
211 font=$(ls -1 /lib/kbd/consolefonts/${CONSOLEFONT}*.gz 2> /dev/null)
212 if [ -n "$font" ]; then
213 verbose "Loading font $font"
214 busybox_applet loadfont
215 inst_d "/lib/kbd/consolefonts"
216 cp -a "$font" "$DESTDIR/lib/kbd/consolefonts/"
217 gunzip ${DESTDIR}/lib/kbd/consolefonts/${CONSOLEFONT}*.gz
219 echo "loadfont < $font" | add_linuxrc
224 # generate code to mount /proc on initrd
225 # can be called multiple times
227 if is_yes "$proc_mounted"; then
232 if [ "$INITRDFS" = "initramfs" ]; then
233 # /proc is mounted with initramfs 2.6.22.14 kernel
234 # XXX: remove when it is clear why proc was already mounted
235 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
237 echo "mount -t proc none /proc" | add_linuxrc
241 # generate code to mount /sys on initrd
242 # can be called multiple times
244 if is_yes "$sys_mounted"; then
249 echo "mount -t sysfs none /sys" | add_linuxrc
252 # generate code to mount /tmp on initrd
253 # can be called multiple times
255 if [ "$INITRDFS" = "initramfs" ]; then
256 # initramfs is read-write filesystem, no need for tmpfs
260 if is_yes "$tmp_mounted"; then
265 echo "mount -t tmpfs none /tmp" | add_linuxrc
268 # generate code to mount /run on initrd
269 # can be called multiple times
271 if is_yes "$run_mounted"; then
276 echo "mount -t tmpfs run /run" | add_linuxrc
279 # unmount all mountpoints mounted by geninitrd
280 # try to move pseudo filesystems to newroot if possible
284 : Last shell before umounting all and giving control over to real init.
288 if is_yes "$run_mounted"; then
290 mount --bind /run /newroot/run
295 if is_yes "$dev_mounted"; then
297 mount --bind /dev /newroot/dev
302 if is_yes "$sys_mounted"; then
304 mount --bind /sys /newroot/sys
309 if is_yes "$proc_mounted"; then
311 mount --bind /proc /newroot/proc
316 if is_yes "$tmp_mounted"; then
317 echo 'umount /tmp' | add_linuxrc
322 # Checks if busybox has support for APPLET(s)
323 # Exits from geninitrd if the support is not present.
325 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
329 if [ -z "$busybox_functions" ]; then
330 local tmp=$($busybox 2>&1)
332 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
333 if [[ "$tmp" = *applet\ not\ found* ]]; then
335 ln -s $busybox $t/busybox
336 local tmp=$($t/busybox 2>&1)
340 busybox_functions=$(echo "$tmp" | \
341 sed -ne '/Currently defined functions:/,$p' | \
342 xargs | sed -e 's,.*Currently defined functions: ,,'
348 eval have='$'busybox_have_$applet
349 if [ -z "$have" ]; then
350 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
351 if [ "$have" = 0 ]; then
352 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
355 eval busybox_have_$applet=$have
358 if [ $err = 1 ]; then
363 # Extract the .config file from a kernel image
364 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
366 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
367 if [ -n "$kofile" ]; then
368 /lib/geninitrd/extract-ikconfig $kofile
372 # see if config available as separate file
373 if [ -f /boot/config-$kernel ]; then
374 cat /boot/config-$kernel
378 # finally try vmlinuz itself
379 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
387 module=${module%$modext*}
391 # Finds module dependencies
395 # Outputs full path to module and it's dependencies
400 # if module is prefixed with dash, we should ignore errors if the module
402 if [ ${module#-} != $module ]; then
407 # This works when user has module-init-tools installed even on 2.4 kernels
409 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
412 if [ $skiperrors = 1 ]; then
417 if ! is_no "$EXIT_IF_MISSING"; then
418 die "$module: module not found for $kernel kernel"
421 warn "$module: module not found for $kernel kernel"
422 warn "If $module isn't compiled in kernel then this initrd may not start your system."
428 while read insmod modpath options; do
429 if [ "$insmod" = "insmod" ]; then
431 # XXX: find a away to autodetect
432 smodule=$(basename_module $modpath)
435 find_depmod "-libcrc32c"
438 find_depmod "-crct10dif-pclmul"
439 find_depmod "-crct10dif"
442 find_depmod "-crc32c-intel"
443 find_depmod "-crc32c"
445 virtio_blk|virtio_scsi)
446 find_depmod "-virtio_pci"
447 find_depmod "-virtio_mmio"
460 # no firmware support in 2.4 kernels
461 if [ "$kernel_version_long" -lt "002005048" ]; then
464 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
469 local mod depmod module=$1
471 depmod=$(find_depmod $module) || exit 1
472 for mod in $depmod; do
473 mod=${mod#/lib/modules/$kernel/}
475 # add each module only once
477 for m in $MODULES; do
478 [ $m = $mod ] && have=1
480 if [ $have = 0 ]; then
481 MODULES="$MODULES $mod"
486 # install a file to temporary mount image.
487 # it will operate recursively (copying directories)
488 # and will symlink destinations if source is symlink.
490 if [ $# -lt 2 ]; then
491 die 'Usage: inst <file> [<file>] <destination>'
494 local src i=0 c=$(($# - 1))
495 while [ $i -lt $c ]; do
502 local parentDir=$(dirname $DESTDIR$dest)
503 if [ ! -d "$parentDir" ]; then
504 verbose "+ mkdir -p DESTDIR${parentDir#$DESTDIR}"
507 verbose "+ cp $* DESTDIR$dest"
508 cp -HR "$@" "$DESTDIR$dest"
513 die 'Usage: inst_d <destination> <destination>'
517 install -d "$DESTDIR$dir"
521 # install executable and it's shared libraries
523 if [ $# -lt 2 ]; then
524 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
526 local src i=0 c=$(($# - 1))
527 while [ $i -lt $c ]; do
540 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
544 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
546 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
548 inst_exec $lib /$_lib
553 # hack for uclibc linked binaries requiring this fixed path
554 # XXX: shouldn't rpath be used here instead so th
555 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
556 local lib=$DESTDIR/$_lib/libc.so.0
557 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
558 local libdir=$(cd $(dirname "$lib"); pwd)
559 if [ ! -e $DESTDIR$libdir ]; then
560 libdir=$(dirname "$libdir")
562 verbose "+ ln -s /$_lib $DESTDIR$libdir"
563 ln -s /$_lib $DESTDIR$libdir
568 # output modules.conf / modprobe.conf
570 echo "$modprobe_conf_cache"
573 # return options for MODULE
574 # @param $1 module name
577 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
582 # defaults to modprobe -c if not told otherwise, this means include statements
584 cache_modprobe_conf() {
585 if [ "$kernel_version" -lt "002005" ]; then
586 modulefile=/etc/modules.conf
587 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
588 modulefile=/etc/conf.modules
592 if [ -n "$modulefile" ]; then
593 debug "Using $modulefile for modules config"
594 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
597 debug "Using modprobe -c to get modules config"
598 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
602 # find modules for $devpath
603 find_modules_for_devpath() {
605 if [ -z "$devpath" ]; then
606 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
609 if [[ "$devpath" = /dev/dm-* ]]; then
610 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
611 devpath=$(dm_node "$devpath")
614 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
615 # sanitize things like:
616 # /dev/block/104:2 -> /dev/cciss/c0d0p2
617 devpath=$(readlink -f "$devpath")
620 verbose "Finding modules for device path $devpath"
622 if is_luks "$devpath"; then
623 find_modules_luks "$devpath"
627 if is_nfs "$devpath"; then
628 find_modules_nfs "$devpath"
632 if is_md "$devpath"; then
633 find_modules_md "$devpath"
637 if is_multipath "$devpath"; then
638 if find_modules_multipath "$devpath"; then
645 if is_dmraid "$devpath"; then
646 if find_modules_dmraid "$devpath"; then
652 if is_scsi "$devpath"; then
653 find_modules_scsi "$devpath"
657 if is_ide "$devpath"; then
658 find_modules_ide "$devpath"
662 if [[ "$devpath" == /dev/bcache* ]]; then
663 find_modules_bcache "$devpath"
667 if [[ "$devpath" == /dev/rd/* ]]; then
673 if [[ "$devpath" == /dev/ida/* ]]; then
674 find_module "cpqarray"
675 rootdev_add=/dev/ida/
679 if [[ "$devpath" == /dev/cciss/* ]]; then
680 rootdev_add=/dev/cciss/
682 # load hpsa for future kernels, cciss for backwards compat
683 if [ "$kernel_version_long" -ge "003000000" ]; then
684 find_module "hpsa" "-cciss"
685 find_modules_scsi "$devpath"
693 if [[ "$devpath" == /dev/ataraid/* ]]; then
695 find_module "ataraid"
696 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
697 if [ -n "$ataraidmodules" ]; then
698 # FIXME: think about modules compiled in kernel
699 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
701 for n in $ataraidmodules; do
704 rootdev_add=/dev/ataraid/
708 # check to see if we need to set up a loopback filesystem
709 if [[ "$devpath" == /dev/loop* ]]; then
710 die "Sorry, root on loop device isn't supported."
711 # TODO: rewrite for bsp and make nfs ready
712 if [ ! -x /sbin/losetup ]; then
713 die "losetup is missing"
715 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
716 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
717 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"
720 line="`awk '/'$key'/ { print $0; }' $fstab`"
721 loopDev="$(echo $line | awk '{print $3}')"
722 loopFs="$(echo $line | awk '{print $4}')"
723 loopFile="$(echo $line | awk '{print $5}')"
725 BASICMODULES="$BASICMODULES -loop"
726 find_module "-$loopFs"
727 BASICMODULES="$BASICMODULES -${loopFs}"
731 if is_lvm "$devpath"; then
732 find_modules_lvm "$devpath"
737 firmware_install_module() {
739 local firmware_files="$2"
741 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
742 # firmware not yet installed
743 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
745 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
747 # handle only firmware add requests
748 if [ "$SUBSYSTEM" != "firmware" ]; then
751 if [ "$ACTION" != "add" ]; then
754 echo 1 > /sys$DEVPATH/loading
755 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
756 echo 0 > /sys$DEVPATH/loading
759 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
761 # setup firmware loader agent
762 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
765 for firmware in $firmware_files; do
766 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
767 FIRMWAREDIR=${firmware%/*}
768 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
769 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
770 elif [ -f "/lib/firmware/$firmware" ]; then
771 FIRMWAREDIR=${firmware%/*}
772 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
773 inst /lib/firmware/$firmware /lib/firmware/$firmware
775 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
786 for mod in $modules; do
788 inst_d "/lib/modules/$kernel/$MODULEDIR"
789 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
792 gunzip "$DESTDIR/lib/modules/$kernel/$mod"
796 xz -d "$DESTDIR/lib/modules/$kernel/$mod"
800 bzip2 -d "$DESTDIR/lib/modules/$kernel/$mod"
804 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
805 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod}"
810 modules_add_linuxrc() {
814 # module path without optional compression
816 modpath=${modpath%.xz}
817 modpath=${modpath%.bz2}
820 local module=${modpath##*/}; module=${module%$modext}
821 local options=$(modprobe_options "$module")
822 local genericname=$(echo $module | tr - _)
823 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
824 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
826 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
827 options="scan=sync $options"
830 if [ x"$verbose" = x"-v" ]; then
832 if [ "$options" ]; then
833 s="$s with options [$options]"
835 if [ "$usleep" ]; then
836 s="$s and $usleep usleep"
838 verbose "Loading module [$module]$s"
841 if [ -n "$firmware" ]; then
842 firmware_install_module "$module" "$firmware"
844 for file in $(find_firmware "$module"); do
845 firmware_install_module "$module" "$file"
849 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
850 if [ -n "$usleep" ]; then
851 echo "usleep $usleep" | add_linuxrc
853 if [ "$module" = "scsi_wait_scan" ]; then
854 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
855 echo "rmmod scsi_wait_scan" | add_linuxrc
862 # Generates /dev nodes based on /proc/partitions information.
863 # Needs /proc mounted.
864 # Can be called multiple times.
865 initrd_gen_devices() {
866 if is_yes "$proc_partitions"; then
873 : 'Making device nodes'
874 cat /proc/partitions | (
875 # ignore first two lines: header, empty line
878 while read major minor blocks dev rest; do
881 [ -e $node ] || mknod -m 660 $node b $major $minor
888 initrd_gen_setrootdev() {
889 verbose "Adding rootfs finding based on kernel cmdline root= option support."
891 debug "Current /proc/partitions:\n$(sed -e 's,^,| ,' /proc/partitions)"
893 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
894 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
895 # fallback to ls, try two different formats
896 # http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023915.html
897 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
899 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
901 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
902 # busybox 1.22 and upwards
903 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $5 + $6; }}')"
905 if [ "${rootnr:-0}" -gt 0 ]; then
906 echo "$rootnr" > /proc/sys/kernel/real-root-dev
912 initrd_gen_initramfs_switchroot() {
914 if [ "$rootdev" = "/dev/nfs" ]; then
915 echo "rootfs on NFS root=/dev/nfs"
917 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
920 # parse 'root=xxx' kernel commandline
921 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
923 # from lilo-23.2/readme/README:
924 # root=<device> changes the root device. This overrides settings that may
925 # have been made in the boot image and on the LILO command line. <device> is
926 # either the hexadecimal device number or the full path name of the device,
929 # * The device names are hard-coded in the kernel. Therefore, only the
930 # "standard" names are supported and some less common devices may not be
931 # recognized. In those cases, only numbers can be used.
935 eval "$(busybox awk -v root="$ROOT" '
936 # http://9fans.net/archive/2006/09/261
937 function h2d(str, hstr, res, num, n, digit, i) {
938 hstr = "0123456789abdcef";
940 n = split(tolower(str), digit, "");
942 for (i = 1; i <= n; i++) {
943 num = index(hstr, digit[i]) - 1;
944 res = res + (num * 16 ^ (n - i));
951 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
952 num_pattern = "[0-9a-fA-F]" num_pattern_short;
953 dev_pattern = "[hms][a-z][a-z]([0-9])+";
957 # see if we have /dev/hdX or hdX, we can just take partition name
958 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
960 sub("^/dev/", "", partition);
964 if (root ~ "^" num_pattern_short "$") {
965 # change "303" => "0x0303"
967 } else if (root ~ "^" num_pattern "$") {
968 # change "0303" => "0x0303"
972 maj = h2d(substr(root, 3, 2));
973 min = h2d(substr(root, 5, 2));
977 partition && $4 == partition { maj = $1; min = $2; }
978 $1 == maj && $2 == min { partition = $4; }
981 if (maj >= 0 && min >= 0) {
982 printf("maj=%s; min=%s;\n", maj, min);
985 printf("device=/dev/%s;\n", partition);
990 if [ -z "$device" ]; then
991 if [ "$DEBUGINITRD" ]; then
997 if [ "$device" -a ! -b $device -a "$maj$min" ]; then
998 mknod -m 660 $device b $maj $min
1001 # XXX hack, if no device, try to parse it from /proc/partitions using /proc/sys/kernel/real-root-dev
1002 if [ ! -e "$device" ]; then
1003 rrd=$(cat /proc/sys/kernel/real-root-dev)
1004 major=$(($rrd / 256))
1005 minor=$(($rrd % 256))
1007 while read pmajor pminor blocks dev rest; do
1008 # skip header and empty line
1009 [ -z "$pmajor" -o "$pmajor" = "major" ] && continue
1011 if [ $pmajor = $major -a $pminor = $minor ]; then
1013 echo "DEVICE set to $device based on real-root-dev"
1015 done < /proc/partitions
1018 [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
1020 mount -t $ROOTFS -r $device $ROOTFLAGS /newroot || echo "Mount of rootfs failed."
1022 if [ -z "$init" -o ! -x "/newroot$init" ]; then
1027 busybox_applet dmesg
1029 add_linuxrc <<-'EOF'
1030 if [ "$DEBUGINITRD" ]; then
1031 echo "Last 20 lines of dmesg:"
1037 kmsg "geninitrd/$VERSION switching root"
1040 busybox_applet switch_root usleep
1041 add_linuxrc <<-'EOF'
1042 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
1044 # switch root to empty dir will make kernel panic, so sleep 10s before it
1045 # switch_root needs to be pid 1, so there's no other way to recover from here
1046 # if /dev is missing, switch root will likely fail, give debug shell before that
1047 if [ ! -d /newroot/dev ]; then
1048 echo "/dev is missing, switch_root will likely fail"
1049 echo "if you booted with debugrd=sh, then you be given shell and you might able to recover this situation"
1051 [ "$DEBUGINITRD" ] || usleep 10000000
1054 exec switch_root /newroot $init ${1:+"$@"}
1056 # FIXME: this code is never executed, as "exec" does not return!
1058 echo "Error! initramfs should not reach this place."
1059 echo "It probably means you've got old version of busybox, with broken"
1060 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1062 exec chroot /newroot $init ${1:+"$@"}
1064 echo "Failed to chroot!"
1067 # we need /init being real file, not symlink, otherwise the initramfs will
1068 # not be ran by pid 1 which is required for switch_root
1069 mv $DESTDIR/linuxrc $DESTDIR/init
1070 ln -s init $DESTDIR/linuxrc
1073 # find if $symbol exists in System.map $mapfile
1077 if [ ! -f $mapfile ]; then
1078 # missing mapfile (not a pld kernel?)
1082 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
1085 # find best compressor (or forced one) for initrd
1088 # fastest initrd decompression speed is first
1089 local compressors='lzo gzip xz lzma bzip2'
1091 # a specified one, take it
1092 if ! is_yes "$mode"; then
1096 verbose "finding compressor: $compressors (via $mode)"
1097 # check for compressor validity
1098 local c prog map=/boot/System.map-$kernel
1099 for c in $compressors; do
1122 # any existing sym will work
1127 die "Unknown compressor $c"
1130 if sym_exists $map $sym && [ -x $prog ]; then
1136 verbose "using gzip for compressor (fallback)"
1140 # compresses kernel image image
1141 # in function so we could retry with other compressor on failure
1143 local compressor="$1" IMAGE="$2" target="$3" tmp
1144 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1146 case "$compressor" in
1148 # don't use -9 here since kernel won't understand it
1149 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1152 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1155 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1158 gzip -9 < "$IMAGE" > "$tmp" || return $?
1161 lzop -9 < "$IMAGE" > "$tmp" || return $?
1164 cat < "$IMAGE" > "$tmp" || return $?
1168 mv -f "$tmp" "$target"
1171 if [ -r /etc/sysconfig/geninitrd ]; then
1172 . /etc/sysconfig/geninitrd
1175 if [ ! -f /proc/mounts ]; then
1176 warn "/proc filesystem not mounted, may cause wrong results or failure."
1179 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd bcache
1181 while [ $# -gt 0 ]; do
1191 modulefile=${1#--modules-conf=}
1200 --without-bootsplash)
1212 --without-fbcondecor)
1221 --with-suspend2 | --with-tuxonice)
1224 --without-suspend2 | --without-tuxonice)
1228 LVMTOOLSVERSION=${1#--lvmversion=}
1230 --lvmtoolsversion=*)
1231 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1233 --lvmtoolsversion|--lvmversion)
1246 --without-multipath)
1250 USE_MULTIPATH=${1#--with-multipath=}
1259 BASICMODULES="$BASICMODULES ${1#--with=}"
1262 BASICMODULES="$BASICMODULES $2"
1266 echo "$PROGRAM: version $VERSION"
1270 if [ x"$verbose" = x"-v" ]; then
1281 COMPRESS="${1#--compress=}"
1290 STRIP="${1#--strip=}"
1303 PREMODS="$PREMODS ${1#--preload=}"
1306 PREMODS="$PREMODS $2"
1310 die "--fs option is obsoleted. Use --initrdfs instead"
1313 INITRDFS=${1#--initrdfs=}
1326 if [ -z "$target" ]; then
1328 elif [ -z "$kernel" ]; then
1340 if [ -z "$target" -o -z "$kernel" ]; then
1346 if [ "$(id -u)" != 0 ]; then
1347 die "You need to be root to generate initrd"
1350 if [ -d /lib64 -a -d /usr/lib64 ]; then
1356 initrd_dir=/usr/$_lib/initrd
1357 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1358 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1360 verbose "# geninitrd $VERSION"
1361 debug "Using _lib: $_lib"
1362 debug "Using initrd_dir: $initrd_dir"
1364 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1366 # we setup mods after parsing command line args
1367 geninitrd_setup_mods
1369 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1370 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1373 if [ -z "$INITRDFS" ]; then
1374 if [ -n "$FS" ]; then
1375 # FS= can came only via /etc/sysconfig/geninitrd likely?
1376 die "FS configuration option is obsoleted. Use INITRDFS instead"
1380 if [ "$kernel_version" -ge "002005" ]; then
1381 INITRDFS="initramfs"
1389 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1392 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1395 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1398 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1399 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1402 die "Filesystem $INITRDFS on initrd is not supported"
1406 if [ -L "$target" ]; then
1407 target=$(readlink -f "$target")
1410 if [ -n "$img_vers" ]; then
1411 target="$target-$kernel"
1414 if [ -z "$force" -a -f "$target" ]; then
1415 die "$target already exists."
1418 if [ ! -d "/lib/modules/$kernel" ]; then
1419 die "/lib/modules/$kernel is not a directory."
1422 if [ "$kernel_version" -ge "002005" ]; then
1428 for n in $PREMODS; do
1432 if [ "$FBMODULE" ]; then
1433 find_module "$FBMODULE"
1436 # autodetect USB keyboards
1439 # allow forcing loading SCSI and/or IDE modules
1440 # XXX: where ADDSCSI cames from? drop?
1441 if is_yes "$ADDSCSI"; then
1445 # autodetect SATA modules
1448 # XXX: where ADDIDE cames from? drop?
1449 if is_yes "$ADDIDE"; then
1453 if is_yes "$USE_SUSPEND"; then
1454 find_modules_suspend
1457 find_root "$fstab" || exit
1458 verbose "Using $rootdev as device for rootfs"
1460 find_modules_for_devpath "$rootdev"
1462 # if USE_MULTIPATH is path to device, scan that too
1463 # this is to bootstrap multipath setup into initrd.
1464 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1465 find_modules_multipath $USE_MULTIPATH
1468 find_module "-$rootFs"
1470 for n in $BASICMODULES; do
1474 if is_yes "$USE_TUXONICE"; then
1478 find_modules_uvesafb
1479 find_modules_fbsplash
1481 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1482 verbose "No modules are needed -- not building initrd image."
1486 verbose "Building initrd..."
1487 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1488 RCFILE="$DESTDIR/linuxrc"
1490 chmod a+rx "$RCFILE"
1491 ln -s linuxrc $DESTDIR/init
1493 # create dirs that we really need
1494 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1496 modules_install "$MODULES"
1498 # mknod'ing the devices instead of copying them works both with and
1500 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1501 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1502 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1503 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1504 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1505 mknod -m 644 "$DESTDIR/dev/kmsg" c 1 11
1507 inst_exec $busybox /bin/busybox
1508 ln -s busybox $DESTDIR/bin/sh
1509 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1510 ln -s busybox $DESTDIR/bin/initrd-busybox
1514 # initrd generated by geninitrd/$VERSION
1515 # on $(LC_ALL=C date)
1521 kmsg "geninitrd/$VERSION starting"
1524 # builtin defaults from geninitrd
1528 add_linuxrc <<-'EOF'
1529 read CMDLINE < /proc/cmdline
1531 for arg in $CMDLINE; do
1532 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1535 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1536 DEBUGINITRD=${arg##debug*rd=}
1538 if [ "${arg##root=}" != "${arg}" ]; then
1541 if [ "${arg##rootflags=}" != "${arg}" ]; then
1542 ROOTFLAGS=${arg##rootflags=}
1544 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1545 ROOTFSFLAGS=${arg##rootfsflags=}
1547 if [ "${arg##init=}" != "${arg}" ]; then
1552 # handling of invalid, rootfsflags, option
1553 if [ -n "$ROOTFSFLAGS" ]; then
1554 if [ -n "$ROOTFLAGS" ]; then
1555 ROOTFLAGS="$ROOTFLAGS,$ROOTFSFLAGS"
1557 ROOTFLAGS="$ROOTFSFLAGS"
1561 if [ "$DEBUGINITRD" = "sh" ]; then
1562 # export some vars to subshell for debug to work
1563 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFLAGS DEBUGINITRD INIT
1564 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1565 export rootnr attrs majmin major minor device
1567 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1570 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1571 add_linuxrc <<-'EOF'
1572 echo "debug shell disabled by RUN_SULOGIN_ON_ERR=yes from /etc/sysconfig/system during initrd generation time"
1575 add_linuxrc <<-'EOF'
1579 add_linuxrc <<-'EOF'
1587 if [ "$DEBUGINITRD" ]; then
1592 modules_add_linuxrc $MODULES
1594 # TODO: rewrite for busybox
1595 #if [ -n "$loopDev" ]; then
1596 # if [ ! -d /initrd ]; then
1600 # cp -a "$loopDev" "$DESTDIR/dev"
1601 # cp -a "$rootdev" "$DESTDIR/dev"
1602 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1603 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1604 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1605 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1608 if is_yes "$USE_UDEV"; then
1617 initrd_gen_multipath
1620 if is_yes "$have_nfs"; then
1628 initrd_gen_setrootdev
1631 # additional devs always needed
1632 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1634 initrd_gen_stop_udevd
1635 initrd_gen_stop_mdev
1636 initrd_gen_stop_uvesafb
1638 # resume after killing local processes
1643 add_linuxrc <<-'EOF'
1644 if [ ! "$DEBUGINITRD" ]; then
1648 for i in $(export -p); do
1649 i=${i#declare -x } # ksh/bash
1650 i=${i#export } # busybox
1661 [ -z "$i" ] && continue
1664 ROOT|PATH|HOME|TERM)
1676 if [ "$INITRDFS" = "initramfs" ]; then
1677 initrd_gen_initramfs_switchroot
1683 initrd_gen_fbcondecor
1685 debug "Current /linuxrc:\n$(sed -e 's,^,| ,' $DESTDIR/linuxrc)"
1687 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1689 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1690 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1692 verbose "Creating $INITRDFS image $IMAGE"
1695 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1696 # NOTE: ext2 label is max 16 chars
1697 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1698 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1700 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1701 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1702 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1703 # We don't need this directory, so let's save space
1704 rm -rf "$tmpmnt"/lost+found
1706 debug "Copy recursively $DESTDIR -> $tmpmnt"
1707 cp -a $DESTDIR/* $tmpmnt
1713 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1716 mkcramfs "$DESTDIR" "$IMAGE"
1719 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1722 die "Filesystem $INITRDFS not supported by $PROGRAM"
1725 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1726 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1727 CONFIG_BLK_DEV_RAM_SIZE=4096
1728 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1731 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1732 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1735 if ! is_no "$COMPRESS"; then
1736 compressor=$(find_compressor "$COMPRESS")
1737 verbose "Compressing $target with $compressor"
1739 # TODO: the image name (specified from kernel.spec) already contains
1740 # extension, which is .gz most of the time.
1741 compress_image "$compressor" "$IMAGE" "$target" || {
1742 if [ $compressor != gzip ]; then
1743 warn "Could not compress with $compressor, retrying with gzip"
1744 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1746 die "Could not compress image with $compressor"
1750 cp -a "$IMAGE" "$target"
1753 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1754 initrd_gen_bootsplash "$target"
1756 rm -rf "$DESTDIR" "$IMAGE"
1758 # vim:ts=4:sw=4:noet:fdm=marker