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
438 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
442 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
444 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
446 inst_exec $lib /$_lib
451 # hack for uclibc linked binaries requiring this fixed path
452 # XXX: shouldn't rpath be used here instead so th
453 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
454 local lib=$DESTDIR/$_lib/libc.so.0
455 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
456 local libdir=$(cd $(dirname "$lib"); pwd)
457 if [ ! -e $DESTDIR$libdir ]; then
458 libdir=$(dirname "$libdir")
460 debug "+ ln -s /$_lib $DESTDIR$libdir"
461 ln -s /$_lib $DESTDIR$libdir
466 # output modules.conf / modprobe.conf
468 echo "$modprobe_conf_cache"
472 # defaults to modprobe -c if not told otherwise, this means include statements
474 cache_modprobe_conf() {
475 if [ "$kernel_version" -lt "002005" ]; then
476 modulefile=/etc/modules.conf
477 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
478 modulefile=/etc/conf.modules
482 if [ -n "$modulefile" ]; then
483 debug "Using $modulefile for modules config"
484 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
487 debug "Using modprobe -c to get modules config"
488 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
492 # find modules for $devpath
493 find_modules_for_devpath() {
495 if [ -z "$devpath" ]; then
496 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
499 if [[ "$devpath" = /dev/dm-* ]]; then
500 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
501 devpath=$(dm_node "$devpath")
504 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
505 # sanitize things like:
506 # /dev/block/104:2 -> /dev/cciss/c0d0p2
507 devpath=$(readlink -f "$devpath")
510 debug "Finding modules for device path $devpath"
512 if is_luks "$devpath"; then
513 find_modules_luks "$devpath"
517 if is_nfs "$devpath"; then
518 find_modules_nfs "$devpath"
522 if is_md "$devpath"; then
523 find_modules_md "$devpath"
527 if is_multipath "$devpath"; then
528 if find_modules_multipath "$devpath"; then
535 if is_dmraid "$devpath"; then
536 if find_modules_dmraid "$devpath"; then
542 if is_scsi "$devpath"; then
543 find_modules_scsi "$devpath"
547 if is_ide "$devpath"; then
548 find_modules_ide "$devpath"
552 if [[ "$devpath" == /dev/rd/* ]]; then
558 if [[ "$devpath" == /dev/ida/* ]]; then
559 find_module "cpqarray"
560 rootdev_add=/dev/ida/
564 if [[ "$devpath" == /dev/cciss/* ]]; then
565 rootdev_add=/dev/cciss/
567 # load hpsa for future kernels, cciss for backwards compat
568 if [ "$kernel_version_long" -ge "003000000" ]; then
569 find_module "hpsa" "-cciss"
570 find_modules_scsi "$devpath"
578 if [[ "$devpath" == /dev/ataraid/* ]]; then
580 find_module "ataraid"
581 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
582 if [ -n "$ataraidmodules" ]; then
583 # FIXME: think about modules compiled in kernel
584 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
586 for n in $ataraidmodules; do
589 rootdev_add=/dev/ataraid/
593 # check to see if we need to set up a loopback filesystem
594 if [[ "$devpath" == /dev/loop* ]]; then
595 die "Sorry, root on loop device isn't supported."
596 # TODO: rewrite for bsp and make nfs ready
597 if [ ! -x /sbin/losetup ]; then
598 die "losetup is missing"
600 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
601 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
602 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"
605 line="`awk '/'$key'/ { print $0; }' $fstab`"
606 loopDev="$(echo $line | awk '{print $3}')"
607 loopFs="$(echo $line | awk '{print $4}')"
608 loopFile="$(echo $line | awk '{print $5}')"
610 BASICMODULES="$BASICMODULES -loop"
611 find_module "-$loopFs"
612 BASICMODULES="$BASICMODULES -${loopFs}"
616 if is_lvm "$devpath"; then
617 find_modules_lvm "$devpath"
622 firmware_install_module() {
624 local firmware_files="$2"
626 debug "Adding Firmwares ($firmware_files) to initrd for module $module"
627 # firmware not yet installed
628 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
630 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
632 echo 1 > /sys$DEVPATH/loading
633 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
634 echo 0 > /sys$DEVPATH/loading
637 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
639 # setup firmware loader agent
640 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
643 for firmware in $firmware_files; do
644 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
645 FIRMWAREDIR=${firmware%/*}
646 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
647 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
648 elif [ -f "/lib/firmware/$firmware" ]; then
649 FIRMWAREDIR=${firmware%/*}
650 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
651 inst /lib/firmware/$firmware /lib/firmware/$firmware
653 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
664 for mod in $modules; do
666 inst_d "/lib/modules/$kernel/$MODULEDIR"
667 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
668 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
669 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
670 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
675 modules_add_linuxrc() {
679 # module path without optional compression
683 local module=${modpath##*/}; module=${module%$modext}
684 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}' | xargs)
685 local genericname=$(echo $module | tr - _)
686 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
687 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
689 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
690 options="scan=sync $options"
693 if [ -n "$verbose" ]; then
695 if [ "$options" ]; then
696 s="$s with options [$options]"
698 if [ "$usleep" ]; then
699 s="$s and $usleep usleep"
701 debug "Loading module [$module]$s"
704 if [ -n "$firmware" ]; then
705 firmware_install_module "$module" "$firmware"
707 for file in $(find_firmware "$module"); do
708 firmware_install_module "$module" "$file"
712 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
713 if [ -n "$usleep" ]; then
714 echo "usleep $usleep" | add_linuxrc
716 if [ "$module" = "scsi_wait_scan" ]; then
717 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
718 echo "rmmod scsi_wait_scan" | add_linuxrc
725 # Generates /dev nodes based on /proc/partitions information.
726 # Needs /proc mounted.
727 # Can be called multiple times.
728 initrd_gen_devices() {
729 if is_yes "$proc_partitions"; then
736 : 'Making device nodes'
737 cat /proc/partitions | (
738 # ignore first two lines: header, empty line
741 while read major minor blocks dev rest; do
744 [ -e $node ] || mknod $node b $major $minor
751 initrd_gen_setrootdev() {
752 debug "Adding rootfs finding based on kernel cmdline root= option support."
755 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
756 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
758 if [ -z "$rootnr" ]; then
759 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
761 if [ -n "$rootnr" ]; then
762 echo "$rootnr" > /proc/sys/kernel/real-root-dev
768 initrd_gen_initramfs_switchroot() {
770 if [ "$rootdev" = "/dev/nfs" ]; then
771 echo "rootfs on NFS root=/dev/nfs"
773 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
776 # parse 'root=xxx' kernel commandline
777 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
779 device=/dev/no_partition_found
780 eval "$(busybox awk -v c="$ROOT" '
782 num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
783 num_pattern = "[0-9a-f]" num_pattern_short;
784 dev_pattern = "[hms][a-z][a-z]([0-9])+";
785 partition = "no_partition_found";
789 if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
790 if (c ~ "^" num_pattern "$") {
791 maj = sprintf("%s",substr(c,1,2));
792 min = sprintf("%s",substr(c,3));
794 if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
795 if (c ~ "^" dev_pattern "$") partition = c;
798 $4 == partition { maj = $1; min = $2; }
799 $1 == maj && $2 == min { partition = $4; }
802 if (maj >= 0 && min >= 0) {
803 printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
807 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
808 mknod $device b $maj $min
818 if [ "$device" = '/dev/no_partition_found' ]; then
822 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
824 mount -t $rootfs -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
825 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
826 if [ -z "$init" -o ! -x "/newroot$init" ]; then
832 busybox_applet switch_root
834 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
835 exec switch_root /newroot $init ${1:+"$@"}
837 echo "Error! initramfs should not reach this place."
838 echo "It probably means you've got old version of busybox, with broken"
839 echo "initramfs support. Trying to boot anyway, but won't promise anything."
841 exec chroot /newroot $init ${1:+"$@"}
843 echo "Failed to chroot!"
846 # we need /init being real file, not symlink, otherwise the initramfs will
847 # not be ran by pid 1 which is required for switch_root
848 mv $DESTDIR/linuxrc $DESTDIR/init
849 ln -s init $DESTDIR/linuxrc
852 # find if $symbol exists in System.map $mapfile
856 if [ ! -f $mapfile ]; then
857 # missing mapfile (not a pld kernel?)
861 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
864 # find best compressor (or forced one) for initrd
867 # fastest initrd decompression speed is first
868 local compressors='lzo gzip xz lzma bzip2'
870 # a specified one, take it
871 if ! is_yes "$mode"; then
875 debug "finding compressor: $compressors (via $mode)"
876 # check for compressor validity
877 local c prog map=/boot/System.map-$kernel
878 for c in $compressors; do
901 # any existing sym will work
906 die "Unknown compressor $c"
909 if sym_exists $map $sym && [ -x $prog ]; then
915 debug "using gzip for compressor (fallback)"
919 # compresses kernel image image
920 # in function so we could retry with other compressor on failure
922 local compressor="$1" IMAGE="$2" target="$3" tmp
923 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
925 case "$compressor" in
927 # don't use -9 here since kernel won't understand it
928 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
931 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
934 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
937 gzip -9 < "$IMAGE" > "$tmp" || return $?
940 lzop -9 < "$IMAGE" > "$tmp" || return $?
943 cat < "$IMAGE" > "$tmp" || return $?
947 mv -f "$tmp" "$target"
950 if [ -r /etc/sysconfig/geninitrd ]; then
951 . /etc/sysconfig/geninitrd
954 if [ ! -f /proc/mounts ]; then
955 warn "/proc filesystem not mounted, may cause wrong results or failure."
958 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
960 while [ $# -gt 0 ]; do
970 modulefile=${1#--modules-conf=}
979 --without-bootsplash)
991 --without-fbcondecor)
1000 --with-suspend2 | --with-tuxonice)
1003 --without-suspend2 | --without-tuxonice)
1007 LVMTOOLSVERSION=${1#--lvmversion=}
1009 --lvmtoolsversion=*)
1010 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1012 --lvmtoolsversion|--lvmversion)
1025 --without-multipath)
1029 USE_MULTIPATH=${1#--with-multipath=}
1038 BASICMODULES="$BASICMODULES ${1#--with=}"
1041 BASICMODULES="$BASICMODULES $2"
1045 echo "$PROGRAM: version $VERSION"
1055 COMPRESS="${1#--compress=}"
1064 STRIP="${1#--strip=}"
1077 PREMODS="$PREMODS ${1#--preload=}"
1080 PREMODS="$PREMODS $2"
1084 die "--fs option is obsoleted. Use --initrdfs instead"
1087 INITRDFS=${1#--initrdfs=}
1100 if [ -z "$target" ]; then
1102 elif [ -z "$kernel" ]; then
1114 if [ -z "$target" -o -z "$kernel" ]; then
1120 if [ "$(id -u)" != 0 ]; then
1121 die "You need to be root to generate initrd"
1124 if [ -d /lib64 -a -d /usr/lib64 ]; then
1130 initrd_dir=/usr/$_lib/initrd
1131 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1132 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1134 debug "# $GENINITRD_RCSID (geninitrd)"
1135 debug "Using _lib: $_lib"
1136 debug "Using initrd_dir: $initrd_dir"
1138 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1140 # we setup mods after parsing command line args
1141 geninitrd_setup_mods
1143 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1144 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1147 if [ -z "$INITRDFS" ]; then
1148 if [ -n "$FS" ]; then
1149 # FS= can came only via /etc/sysconfig/geninitrd likely?
1150 die "FS configuration option is obsoleted. Use INITRDFS instead"
1154 if [ "$kernel_version" -ge "002005" ]; then
1155 INITRDFS="initramfs"
1163 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1166 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1169 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1172 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1173 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1176 die "Filesystem $INITRDFS on initrd is not supported"
1180 if [ -L "$target" ]; then
1181 target=$(readlink -f "$target")
1184 if [ -n "$img_vers" ]; then
1185 target="$target-$kernel"
1188 if [ -z "$force" -a -f "$target" ]; then
1189 die "$target already exists."
1192 if [ ! -d "/lib/modules/$kernel" ]; then
1193 die "/lib/modules/$kernel is not a directory."
1196 if [ "$kernel_version" -ge "002005" ]; then
1202 for n in $PREMODS; do
1206 if [ "$FBMODULE" ]; then
1207 find_module "$FBMODULE"
1210 # autodetect USB keyboards
1213 # allow forcing loading SCSI and/or IDE modules
1214 # XXX: where ADDSCSI cames from? drop?
1215 if is_yes "$ADDSCSI"; then
1219 # autodetect SATA modules
1222 # XXX: where ADDIDE cames from? drop?
1223 if is_yes "$ADDIDE"; then
1227 if is_yes "$USE_SUSPEND"; then
1228 find_modules_suspend
1231 find_root "$fstab" || exit
1232 debug "Using $rootdev as device for rootfs"
1234 find_modules_for_devpath "$rootdev"
1236 # if USE_MULTIPATH is path to device, scan that too
1237 # this is to bootstrap multipath setup into initrd.
1238 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1239 find_modules_multipath $USE_MULTIPATH
1242 find_module "-$rootFs"
1244 for n in $BASICMODULES; do
1248 if is_yes "$USE_TUXONICE"; then
1252 find_modules_fbsplash
1254 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1255 debug "No modules are needed -- not building initrd image."
1259 debug "Building initrd..."
1260 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1261 RCFILE="$DESTDIR/linuxrc"
1263 chmod a+rx "$RCFILE"
1264 ln -s linuxrc $DESTDIR/init
1266 # create dirs that we really need
1267 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1269 modules_install "$MODULES"
1271 # mknod'ing the devices instead of copying them works both with and
1273 mknod "$DESTDIR/dev/console" c 5 1
1274 mknod "$DESTDIR/dev/null" c 1 3
1275 mknod "$DESTDIR/dev/zero" c 1 5
1276 mknod "$DESTDIR/dev/random" c 1 8
1277 mknod "$DESTDIR/dev/urandom" c 1 9
1279 inst_exec $busybox /bin/busybox
1280 ln -s busybox $DESTDIR/bin/sh
1281 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1282 ln -s busybox $DESTDIR/bin/initrd-busybox
1286 # initrd generated by:
1291 add_linuxrc <<-'EOF'
1292 read CMDLINE < /proc/cmdline
1294 for arg in $CMDLINE; do
1295 if [ "${arg}" = "debuginitrd" ]; then
1298 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1299 DEBUGINITRD=${arg##debuginitrd=}
1301 if [ "${arg##root=}" != "${arg}" ]; then
1304 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1305 ROOTFSFLAGS=${arg##rootfsflags=}
1309 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1310 if [ "$DEBUGINITRD" = "sh" ]; then
1313 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1314 add_linuxrc <<-'EOF'
1315 echo "debug shell disabled by /etc/sysconfig/system:RUN_SULOGIN_ON_ERR setting"
1318 add_linuxrc <<-'EOF'
1322 add_linuxrc <<-'EOF'
1330 if [ "$DEBUGINITRD" ]; then
1335 modules_add_linuxrc $MODULES
1337 # TODO: rewrite for busybox
1338 #if [ -n "$loopDev" ]; then
1339 # if [ ! -d /initrd ]; then
1343 # cp -a "$loopDev" "$DESTDIR/dev"
1344 # cp -a "$rootdev" "$DESTDIR/dev"
1345 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1346 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1347 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1348 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1351 if is_yes "$USE_UDEV"; then
1355 find_modules_uvesafb
1360 initrd_gen_multipath
1363 if is_yes "$have_nfs"; then
1369 initrd_gen_setrootdev
1375 # additional devs always needed
1376 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1378 initrd_gen_stop_udevd
1379 initrd_gen_stop_uvesafb
1381 if [ "$INITRDFS" = "initramfs" ]; then
1382 initrd_gen_initramfs_switchroot
1388 initrd_gen_fbcondecor
1390 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1392 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1393 debug "image size: $IMAGESIZE KiB ($DESTDIR)"
1395 debug "Creating $INITRDFS image $IMAGE"
1398 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1399 # NOTE: ext2 label is max 16 chars
1400 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1401 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1403 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1404 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1405 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1406 # We don't need this directory, so let's save space
1407 rm -rf "$tmpmnt"/lost+found
1409 debug "Copy recursively $DESTDIR -> $tmpmnt"
1410 cp -a $DESTDIR/* $tmpmnt
1416 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1419 mkcramfs "$DESTDIR" "$IMAGE"
1422 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1425 die "Filesystem $INITRDFS not supported by $PROGRAM"
1428 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1429 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1430 CONFIG_BLK_DEV_RAM_SIZE=4096
1431 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1434 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1435 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1438 if ! is_no "$COMPRESS"; then
1439 compressor=$(find_compressor "$COMPRESS")
1440 debug "Compressing $target with $compressor"
1442 # TODO: the image name (specified from kernel.spec) already contains
1443 # extension, which is .gz most of the time.
1444 compress_image "$compressor" "$IMAGE" "$target" || {
1445 if [ $compressor != gzip ]; then
1446 warn "Could not compress with $compressor, retrying with gzip"
1447 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1449 die "Could not compress image with $compressor"
1453 cp -a "$IMAGE" "$target"
1456 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1457 initrd_gen_bootsplash "$target"
1459 rm -rf "$DESTDIR" "$IMAGE"
1461 # vim:ts=4:sw=4:noet:fdm=marker