]> git.pld-linux.org Git - projects/geninitrd.git/blame_incremental - geninitrd
- swsusp support from mis@pld-linux
[projects/geninitrd.git] / geninitrd
... / ...
CommitLineData
1#!/bin/sh
2
3# geninitrd
4#
5# by PLD Linux Team
6#
7# based on mkinitrd from RedHat Linux
8#
9
10VERSION='devel'
11PROGRAM=${0##*/}
12
13. /etc/rc.d/init.d/functions
14. /lib/geninitrd/functions
15. /etc/sysconfig/system
16
17# list of geninitrd modules which need setup routine after commandline args parsing
18GENINITRD_MODS=""
19COMPRESS=yes
20LILO_MICROCODE=yes
21STRIP=/usr/bin/strip
22target=""
23kernel=""
24force=""
25verbose=""
26MODULES=""
27img_vers=""
28fstab=/etc/fstab
29modext=.o
30rootdev_nr=0
31# device node for rootfs from fstab
32rootdev=""
33
34# internal variables
35# is /dev on tmpfs
36dev_mounted=no
37# is /proc mounted
38proc_mounted=no
39# is /sys mounted
40sys_mounted=no
41# is /tmp mounted on tmpfs
42tmp_mounted=no
43
44# are /dev nodes already created from /proc/devices info?
45proc_partitions=no
46
47usage() {
48 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
49 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
50 echo " [--compress=yes|zstd|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>"
63 echo ""
64 echo "Example:"
65
66 local kdir kver dir=${target:-/boot}
67 for kdir in /lib/modules/*; do
68 [ -d $kdir ] || continue
69 kver=${kdir##*/}
70 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
71 done | sort -V
72}
73
74msg() {
75 echo "$PROGRAM: $*"
76}
77
78warn() {
79 msg "WARNING: $*" >&2
80}
81
82verbose() {
83 [ -n "$verbose" ] && msg "$*" >&3
84}
85
86debug() {
87 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
88}
89
90# add initrd code to print to kmsg
91# @param string message
92# @param int loglevel. defaults to "6" (info)
93# Log levels can be:
94# Name String Meaning
95# KERN_EMERG "0" Emergency messages, system is about to crash or is unstable
96# KERN_ALERT "1" Something bad happened and action must be taken immediately
97# KERN_CRIT "2" A critical condition occurred like a serious hardware/software failure
98# KERN_ERR "3" An error condition, often used by drivers to indicate difficulties with the hardware
99# KERN_WARNING "4" A warning, meaning nothing serious by itself but might indicate problems
100# KERN_NOTICE "5" Nothing serious, but notably nevertheless. Often used to report security events.
101# KERN_INFO "6" Informational message e.g. startup information at driver initialization
102# KERN_DEBUG "7" Debug messages
103# KERN_CONT "c" "continued" line of log printout (only done after a line that had no enclosing \n)
104kmsg() {
105 local msg="$1" level=${2:-6}
106 echo "echo '<$level>$msg' > /dev/kmsg" | add_linuxrc
107}
108
109# aborts program abnormally
110die() {
111 local rc=${2:-1}
112 msg "ERROR: $1" >&2
113 exit $rc
114}
115
116# find program from specified paths
117find_tool() {
118 local x p b n
119 local paths="$initrd_dirs /bin /sbin /usr/bin /usr/sbin"
120 for x in "$@"; do
121 debug "find_tool: checking $x"
122 if [ -x "$x" ]; then
123 echo $x
124 verbose "find_tool: found $x"
125 return 0
126 fi
127 n="$x"
128 for p in $paths; do
129 b=$(basename $x)
130 debug "find_tool: checking $p/$b"
131 if [ -x "$p/$b" ]; then
132 echo $p/$b
133 verbose "find_tool: found $p/$b"
134 return 0
135 fi
136 n="$n $p/$b"
137 done
138 done
139 debug "find_tool: did not find any of: $n"
140 return 1
141}
142
143# loads geninitrd modules
144geninitrd_load_mods() {
145 local mod
146 for mod in "$@"; do
147 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
148 die "$mod geninitrd module can't be loaded"
149 fi
150 . /lib/geninitrd/mod-$mod.sh
151
152 GENINITRD_MODS="$GENINITRD_MODS $mod"
153 done
154}
155
156# setup geninitrd modules
157geninitrd_setup_mods() {
158 local mod
159
160 for mod in $GENINITRD_MODS; do
161 debug "# $mod"
162
163 # some mods want init
164 if type setup_mod_$mod > /dev/null; then
165 eval setup_mod_$mod
166 fi
167 done
168}
169
170# append text to /linuxrc
171# takes STDIN as input
172add_linuxrc() {
173 cat >> "$RCFILE"
174}
175
176# generate code to mount /dev on tmpfs and create initial nodes
177# can be called multiple times. /dev is cleaned up (umounted) automatically at
178# the end of script.
179mount_dev() {
180 # we already generated tmpfs code; return
181 if is_yes "$dev_mounted"; then
182 return
183 fi
184
185 dev_mounted=yes
186
187 busybox_applet mount mknod mkdir
188 add_linuxrc <<-EOF
189 : 'Creating /dev'
190 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
191 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
192 mknod -m 600 /dev/console c 5 1
193 mknod -m 666 /dev/null c 1 3
194 mknod -m 666 /dev/zero c 1 5
195 mknod -m 666 /dev/random c 1 8
196 mknod -m 600 /dev/snapshot c 10 231
197 mknod -m 666 /dev/urandom c 1 9
198 mknod -m 666 /dev/ptmx c 5 2
199 mknod -m 644 /dev/kmsg c 1 11
200 fi
201 mkdir /dev/pts
202 mkdir /dev/shm
203 EOF
204}
205
206# load font
207load_font() {
208 local font
209 [ ! -r /etc/sysconfig/console ] && return
210 . /etc/sysconfig/console
211 if [ -n "$CONSOLEFONT" ]; then
212 font=$(ls -1 /lib/kbd/consolefonts/${CONSOLEFONT}*.gz 2> /dev/null)
213 if [ -n "$font" ]; then
214 verbose "Loading font $font"
215 busybox_applet loadfont
216 inst_d "/lib/kbd/consolefonts"
217 cp -a "$font" "$DESTDIR/lib/kbd/consolefonts/"
218 gunzip ${DESTDIR}/lib/kbd/consolefonts/${CONSOLEFONT}*.gz
219 font=${font%.gz}
220 echo "loadfont < $font" | add_linuxrc
221 fi
222 fi
223}
224
225# generate code to mount /proc on initrd
226# can be called multiple times
227mount_proc() {
228 if is_yes "$proc_mounted"; then
229 return
230 fi
231
232 proc_mounted=yes
233 if [ "$INITRDFS" = "initramfs" ]; then
234 # /proc is mounted with initramfs 2.6.22.14 kernel
235 # XXX: remove when it is clear why proc was already mounted
236 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
237 else
238 echo "mount -t proc none /proc" | add_linuxrc
239 fi
240}
241
242# generate code to mount /sys on initrd
243# can be called multiple times
244mount_sys() {
245 if is_yes "$sys_mounted"; then
246 return
247 fi
248
249 sys_mounted=yes
250 echo "mount -t sysfs none /sys" | add_linuxrc
251}
252
253# generate code to mount /tmp on initrd
254# can be called multiple times
255mount_tmp() {
256 if [ "$INITRDFS" = "initramfs" ]; then
257 # initramfs is read-write filesystem, no need for tmpfs
258 return
259 fi
260
261 if is_yes "$tmp_mounted"; then
262 return
263 fi
264
265 tmp_mounted=yes
266 echo "mount -t tmpfs none /tmp" | add_linuxrc
267}
268
269# generate code to mount /run on initrd
270# can be called multiple times
271mount_run() {
272 if is_yes "$run_mounted"; then
273 return
274 fi
275
276 run_mounted=yes
277 echo "mount -t tmpfs run /run -o mode=0755,noexec,nosuid,nodev" | add_linuxrc
278}
279
280# unmount all mountpoints mounted by geninitrd
281# try to move pseudo filesystems to newroot if possible
282umount_all() {
283
284 add_linuxrc <<-'EOF'
285 : Last shell before umounting all and giving control over to real init.
286 debugshell
287 EOF
288
289 if is_yes "$run_mounted"; then
290 add_linuxrc <<-EOF
291 mount -n --move /run /newroot/run
292 EOF
293 run_mounted=no
294 fi
295 if is_yes "$dev_mounted"; then
296 add_linuxrc <<-EOF
297 mount --bind /dev /newroot/dev
298 umount /dev
299 EOF
300 dev_mounted=no
301 fi
302 if is_yes "$sys_mounted"; then
303 add_linuxrc <<-EOF
304 mount --bind /sys /newroot/sys
305 umount /sys
306 EOF
307 sys_mounted=no
308 fi
309 if is_yes "$proc_mounted"; then
310 add_linuxrc <<-EOF
311 mount --bind /proc /newroot/proc
312 umount /proc
313 EOF
314 proc_mounted=no
315 fi
316 if is_yes "$tmp_mounted"; then
317 echo 'umount /tmp' | add_linuxrc
318 tmp_mounted=no
319 fi
320}
321
322# Checks if busybox has support for APPLET(s)
323# Exits from geninitrd if the support is not present.
324#
325# NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
326busybox_applet() {
327 local err=0 applet
328
329 if [ -z "$busybox_functions" ]; then
330 local tmp=$($busybox 2>&1)
331
332 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
333 if [[ "$tmp" = *applet\ not\ found* ]]; then
334 local t=$(mktemp -d)
335 ln -s $busybox $t/busybox
336 local tmp=$($t/busybox 2>&1)
337 rm -rf $t
338 fi
339
340 busybox_functions=$(echo "$tmp" | \
341 sed -ne '/Currently defined functions:/,$p' | \
342 xargs | sed -e 's,.*Currently defined functions: ,,'
343 )
344 fi
345 for applet in $*; do
346 local have
347 # try cache
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"
353 err=1
354 fi
355 eval busybox_have_$applet=$have
356 fi
357 done
358 if [ $err = 1 ]; then
359 die "Aborted"
360 fi
361}
362
363# Extract the .config file from a kernel image
364# uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
365ikconfig() {
366 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
367 if [ -n "$kofile" ]; then
368 /lib/geninitrd/extract-ikconfig $kofile
369 return
370 fi
371
372 # see if config available as separate file
373 if [ -f /boot/config-$kernel ]; then
374 cat /boot/config-$kernel
375 return
376 fi
377
378 # finally try vmlinuz itself
379 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
380}
381
382# @param $module
383basename_module() {
384 local module=$1
385
386 module=${module##*/}
387 module=${module%$modext*}
388 echo $module
389}
390
391# Finds module dependencies
392#
393# @param $module
394#
395# Outputs full path to module and it's dependencies
396find_depmod() {
397 local module="$1"
398 local skiperrors=0
399
400 # if module is prefixed with dash, we should ignore errors if the module
401 # can't be found.
402 if [ ${module#-} != $module ]; then
403 skiperrors=1
404 module=${module#-}
405 fi
406
407 # This works when user has module-init-tools installed even on 2.4 kernels
408 local modprobe
409 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
410
411 if [ $? != 0 ]; then
412 if [ $skiperrors = 1 ]; then
413 return 0
414 fi
415 echo >&2 "$modprobe"
416
417 if ! is_no "$EXIT_IF_MISSING"; then
418 die "$module: module not found for $kernel kernel"
419 fi
420
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."
423 fi
424
425 local smodule
426
427 echo "$modprobe" | \
428 while read insmod modpath options; do
429 if [ "$insmod" = "insmod" ]; then
430
431 # XXX: find a away to autodetect
432 smodule=$(basename_module $modpath)
433 case "$smodule" in
434 btrfs)
435 warn "mounting multidevice btrfs volume requires rootfsflags=device=/dev/...,device=/dev/... kernel option"
436 find_depmod "-libcrc32c"
437 ;;
438 ext4)
439 find_depmod "-libcrc32c"
440 ;;
441 crc-t10dif)
442 find_depmod "-crct10dif-pclmul"
443 find_depmod "-crct10dif"
444 ;;
445 libcrc32c)
446 find_depmod "-crc32c-intel"
447 find_depmod "-crc32c"
448 ;;
449 virtio_blk|virtio_scsi)
450 find_depmod "-virtio_pci"
451 find_depmod "-virtio_mmio"
452 ;;
453 esac
454
455 echo $modpath
456 fi
457 done
458 return 0
459}
460
461find_firmware() {
462 local module="$1"
463
464 # no firmware support in 2.4 kernels
465 if [ "$kernel_version_long" -lt "002005048" ]; then
466 return
467 fi
468 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
469}
470
471# @param $module
472find_module() {
473 local mod depmod module=$1
474
475 depmod=$(find_depmod $module) || exit 1
476 for mod in $depmod; do
477 mod=${mod#/lib/modules/$kernel/}
478
479 # add each module only once
480 local m have=0
481 for m in $MODULES; do
482 [ $m = $mod ] && have=1
483 done
484 if [ $have = 0 ]; then
485 MODULES="$MODULES $mod"
486 fi
487 done
488}
489
490# install a file to temporary mount image.
491# it will operate recursively (copying directories)
492# and will symlink destinations if source is symlink.
493inst() {
494 if [ $# -lt 2 ]; then
495 die 'Usage: inst <file> [<file>] <destination>'
496 fi
497
498 local src i=0 c=$(($# - 1))
499 while [ $i -lt $c ]; do
500 src="$src $1"
501 i=$((i + 1))
502 shift
503 done
504 local dest=$1
505 set -- $src
506 local parentDir=$(dirname $DESTDIR$dest)
507 if [ ! -d "$parentDir" ]; then
508 verbose "+ mkdir -p DESTDIR${parentDir#$DESTDIR}"
509 mkdir -p $parentDir
510 fi
511 verbose "+ cp $* DESTDIR$dest"
512 cp -HRp "$@" "$DESTDIR$dest"
513}
514
515inst_d() {
516 if [ $# = 0 ]; then
517 die 'Usage: inst_d <destination> <destination>'
518 fi
519 local dir
520 for dir in "$@"; do
521 install -d "$DESTDIR$dir"
522 done
523}
524
525# install executable and it's shared libraries
526inst_exec() {
527 if [ $# -lt 2 ]; then
528 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
529 fi
530 local src i=0 c=$(($# - 1))
531 while [ $i -lt $c ]; do
532 src="$src $1"
533 i=$((i + 1))
534 shift
535 done
536 local dest=$1
537 set -- $src
538
539 inst "$@" $dest
540
541 local obj lib libs libs_additional libdir
542 for obj in "$@"; do
543 case "$obj" in
544 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2 | /libx32/ld-linux-x32.so.2)
545 continue
546 ;;
547 /lib/libpthread.so* | /lib64/libpthread.so* | /libx32/libpthread.so*)
548 libs_additional="${obj%/libpthread*}/libgcc_s.so.1"
549 ;;
550 esac
551
552
553 libs=$(ldd "$obj" 2> /dev/null | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
554 for lib in $libs $libs_additional; do
555 libdir=$(cd $(dirname "$lib"); pwd)
556 if [ ! -f "$DESTDIR/$lib" ]; then
557 inst_d $libdir
558 inst_exec $lib $libdir
559 fi
560 done
561 done
562
563 # hack for uclibc linked binaries requiring this fixed path
564 # XXX: shouldn't rpath be used here instead so th
565 for _lib in $(get_libdir LIBDIR); do
566 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
567 lib=$DESTDIR/$_lib/libc.so.0
568 lib=$(ldd "$lib" 2> /dev/null | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
569 libdir=$(cd $(dirname "$lib"); pwd)
570 if [ ! -e $DESTDIR$libdir ]; then
571 libdir=$(dirname "$libdir")
572 inst_d $libdir
573 verbose "+ ln -s /$_lib $DESTDIR$libdir"
574 ln -s /$_lib $DESTDIR$libdir
575 break
576 fi
577 fi
578 done
579}
580
581# output modules.conf / modprobe.conf
582modprobe_conf() {
583 echo "$modprobe_conf_cache"
584}
585
586# return options for MODULE
587# @param $1 module name
588modprobe_options() {
589 local module=$1
590 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
591 echo ${options# }
592}
593
594#
595# defaults to modprobe -c if not told otherwise, this means include statements
596# work from there.
597cache_modprobe_conf() {
598 if [ "$kernel_version" -lt "002005" ]; then
599 modulefile=/etc/modules.conf
600 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
601 modulefile=/etc/conf.modules
602 fi
603 fi
604
605 if [ -n "$modulefile" ]; then
606 debug "Using $modulefile for modules config"
607 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
608
609 else
610 debug "Using modprobe -c to get modules config"
611 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
612 fi
613}
614
615# find modules for $devpath
616find_modules_for_devpath() {
617 local devpath="$1"
618 if [ -z "$devpath" ]; then
619 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
620 fi
621
622 if [[ "$devpath" = /dev/dm-* ]]; then
623 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
624 devpath=$(dm_node "$devpath")
625 fi
626
627 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
628 # sanitize things like:
629 # /dev/block/104:2 -> /dev/cciss/c0d0p2
630 devpath=$(readlink -f "$devpath")
631 fi
632
633 verbose "Finding modules for device path $devpath"
634
635 if is_luks "$devpath"; then
636 find_modules_luks "$devpath"
637 return
638 fi
639
640 if is_nfs "$devpath"; then
641 find_modules_nfs "$devpath"
642 return
643 fi
644
645 if is_md "$devpath"; then
646 find_modules_md "$devpath"
647 return
648 fi
649
650 if is_multipath "$devpath"; then
651 if find_modules_multipath "$devpath"; then
652 return
653 fi
654
655 # fallback
656 fi
657
658 if is_dmraid "$devpath"; then
659 if find_modules_dmraid "$devpath"; then
660 return
661 fi
662 # fallback
663 fi
664
665 if is_scsi "$devpath"; then
666 find_modules_scsi "$devpath"
667 return
668 fi
669
670 if is_ide "$devpath"; then
671 find_modules_ide "$devpath"
672 return
673 fi
674
675 if [[ "$devpath" == /dev/nvme* ]]; then
676 find_module "nvme"
677 return
678 fi
679
680 if [[ "$devpath" == /dev/bcache* ]]; then
681 find_modules_bcache "$devpath"
682 return
683 fi
684
685 if [[ "$devpath" == /dev/rd/* ]]; then
686 find_module "DAC960"
687 rootdev_add=/dev/rd/
688 return
689 fi
690
691 if [[ "$devpath" == /dev/ida/* ]]; then
692 find_module "cpqarray"
693 rootdev_add=/dev/ida/
694 return
695 fi
696
697 if [[ "$devpath" == /dev/cciss/* ]]; then
698 rootdev_add=/dev/cciss/
699
700 # load hpsa for future kernels, cciss for backwards compat
701 if [ "$kernel_version_long" -ge "003000000" ]; then
702 find_module "hpsa" "-cciss"
703 find_modules_scsi "$devpath"
704 else
705 find_module "cciss"
706 fi
707
708 return
709 fi
710
711 if [[ "$devpath" == /dev/ataraid/* ]]; then
712 find_modules_ide
713 find_module "ataraid"
714 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
715 if [ -n "$ataraidmodules" ]; then
716 # FIXME: think about modules compiled in kernel
717 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
718 fi
719 for n in $ataraidmodules; do
720 find_module "$n"
721 done
722 rootdev_add=/dev/ataraid/
723 return
724 fi
725
726 # check to see if we need to set up a loopback filesystem
727 if [[ "$devpath" == /dev/loop* ]]; then
728 die "Sorry, root on loop device isn't supported."
729 # TODO: rewrite for bsp and make nfs ready
730 if [ ! -x /sbin/losetup ]; then
731 die "losetup is missing"
732 fi
733 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
734 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
735 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"
736 fi
737
738 line="`awk '/'$key'/ { print $0; }' $fstab`"
739 loopDev="$(echo $line | awk '{print $3}')"
740 loopFs="$(echo $line | awk '{print $4}')"
741 loopFile="$(echo $line | awk '{print $5}')"
742
743 BASICMODULES="$BASICMODULES -loop"
744 find_module "-$loopFs"
745 BASICMODULES="$BASICMODULES -${loopFs}"
746 return
747 fi
748
749 if is_lvm "$devpath"; then
750 find_modules_lvm "$devpath"
751 return
752 fi
753}
754
755firmware_install_module() {
756 local module="$1"
757 local firmware_files="$2"
758
759 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
760 # firmware not yet installed
761 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
762 inst_d /lib/firmware
763cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
764#!/bin/sh -e
765# handle only firmware add requests
766if [ "$SUBSYSTEM" != "firmware" ]; then
767 exit 0
768fi
769if [ "$ACTION" != "add" ]; then
770 exit 0
771fi
772echo 1 > /sys$DEVPATH/loading
773cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
774echo 0 > /sys$DEVPATH/loading
775exit 0
776EOF
777 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
778
779 # setup firmware loader agent
780 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
781 fi
782
783 for firmware in $firmware_files; do
784 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
785 FIRMWAREDIR=${firmware%/*}
786 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
787 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
788 elif [ -f "/lib/firmware/$firmware" ]; then
789 FIRMWAREDIR=${firmware%/*}
790 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
791 inst /lib/firmware/$firmware /lib/firmware/$firmware
792 else
793 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
794 fi
795 done
796
797 mount_sys
798}
799
800modules_install() {
801 local modules="$1"
802 local mod
803
804 for mod in $modules; do
805 MODULEDIR=${mod%/*}
806 inst_d "/lib/modules/$kernel/$MODULEDIR"
807 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
808 case $mod in
809 *.gz)
810 gunzip "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress gz"
811 mod=${mod%.gz}
812 ;;
813 *.xz)
814 xz -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress xz"
815 mod=${mod%.xz}
816 ;;
817 *.bz2)
818 bzip2 -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress bz2"
819 mod=${mod%.bz2}
820 ;;
821 esac
822 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
823 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod}"
824 fi
825 done
826}
827
828modules_add_linuxrc() {
829 local mod modpath
830
831 for mod in "$@"; do
832 # module path without optional compression
833 modpath=${mod%.gz}
834 modpath=${modpath%.xz}
835 modpath=${modpath%.bz2}
836
837 # name of the module
838 local module=${modpath##*/}; module=${module%$modext}
839 local options=$(modprobe_options "$module")
840 local genericname=$(echo $module | tr - _)
841 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
842 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
843
844 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
845 options="scan=sync $options"
846 fi
847
848 if [ x"$verbose" = x"-v" ]; then
849 s=""
850 if [ "$options" ]; then
851 s="$s with options [$options]"
852 fi
853 if [ "$usleep" ]; then
854 s="$s and $usleep usleep"
855 fi
856 verbose "Loading module [$module]$s"
857 fi
858
859 if [ -n "$firmware" ]; then
860 firmware_install_module "$module" "$firmware"
861 else
862 for file in $(find_firmware "$module"); do
863 firmware_install_module "$module" "$file"
864 done
865 fi
866
867 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
868 if [ -n "$usleep" ]; then
869 echo "usleep $usleep" | add_linuxrc
870 fi
871 if [ "$module" = "scsi_wait_scan" ]; then
872 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
873 echo "rmmod scsi_wait_scan" | add_linuxrc
874 fi
875 fi
876
877 done
878}
879
880# Generates /dev nodes based on /proc/partitions information.
881# Needs /proc mounted.
882# Can be called multiple times.
883initrd_gen_devices() {
884 if is_yes "$proc_partitions"; then
885 return
886 fi
887 proc_partitions=yes
888
889 mount_dev
890 add_linuxrc <<-'EOF'
891 : 'Making device nodes'
892 cat /proc/partitions | (
893 # ignore first two lines: header, empty line
894 read b; read b
895
896 while read major minor blocks dev rest; do
897 node=/dev/$dev
898 mkdir -p ${node%/*}
899 [ -e $node ] || mknod -m 660 $node b $major $minor
900 done
901 )
902 EOF
903}
904
905
906initrd_gen_setrootdev() {
907 verbose "Adding rootfs finding based on kernel cmdline root= option support."
908 busybox_applet ls
909 debug "Current /proc/partitions:\n$(sed -e 's,^,| ,' /proc/partitions)"
910 add_linuxrc <<-'EOF'
911 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
912 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
913 # fallback to ls, try two different formats
914 # http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023915.html
915 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
916 # busybox up to 1.22
917 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
918 fi
919 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
920 # busybox 1.22 and upwards
921 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $5 + $6; }}')"
922 fi
923 if [ "${rootnr:-0}" -gt 0 ]; then
924 echo "$rootnr" > /proc/sys/kernel/real-root-dev
925 fi
926 fi
927 EOF
928}
929
930initrd_gen_initramfs_switchroot() {
931 inst_d /newroot
932 if [ "$rootdev" = "/dev/nfs" ]; then
933 echo "rootfs on NFS root=/dev/nfs"
934 else
935 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
936 fi
937
938 # parse 'root=xxx' kernel commandline
939 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
940
941 # from lilo-23.2/readme/README:
942 # root=<device> changes the root device. This overrides settings that may
943 # have been made in the boot image and on the LILO command line. <device> is
944 # either the hexadecimal device number or the full path name of the device,
945 # e.g. /dev/hda3 [*]
946 #
947 # * The device names are hard-coded in the kernel. Therefore, only the
948 # "standard" names are supported and some less common devices may not be
949 # recognized. In those cases, only numbers can be used.
950 busybox_applet cat
951 add_linuxrc <<-'EOF'
952 device=
953 eval "$(busybox awk -v root="$ROOT" '
954 function h2d(str, hstr, res, num, n, digit, i) { # http://9fans.net/archive/2006/09/261
955 hstr = "0123456789abdcef"; res = 0;
956 n = split(tolower(str), digit, "");
957
958 for (i = 1; i <= n; i++) {
959 num = index(hstr, digit[i]) - 1;
960 res = res + (num * 16 ^ (n - i));
961 }
962 return res;
963 }
964 BEGIN {
965 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
966 num_pattern = "[0-9a-fA-F]" num_pattern_short;
967 dev_pattern = "[hms][a-z][a-z]([0-9])+";
968 partition = ""; min = -1; maj = -1;
969
970 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") { # see if we have /dev/hdX or hdX, we can just take partition name
971 partition = root; sub("^/dev/", "", partition);
972 } else { # unify values first
973 if (root ~ "^" num_pattern_short "$") { # change "303" => "0x0303"
974 root = "0x0" root
975 } else if (root ~ "^" num_pattern "$") { # change "0303" => "0x0303"
976 root = "0x" root
977 }
978 maj = h2d(substr(root, 3, 2));
979 min = h2d(substr(root, 5, 2));
980 }
981 }
982 partition && $4 == partition { maj = $1; min = $2; }
983 $1 == maj && $2 == min { partition = $4; }
984 END {
985 if (maj >= 0 && min >= 0) { printf("maj=%s; min=%s;\n", maj, min); }
986 if (partition) { printf("device=/dev/%s;\n", partition); }
987 }' /proc/partitions)"
988
989 if [ -z "$device" ]; then
990 if [ "$DEBUGINITRD" -a "$DEBUGINITRD" != 'sh' ]; then
991 cat /proc/partitions
992 fi
993 device=$ROOT
994 fi
995
996 if [ "$device" -a ! -b $device -a "$maj$min" ]; then
997 mknod -m 660 $device b $maj $min
998 fi
999
1000 # XXX hack, fallback to rootdev from geninitrd time
1001 if [ ! -e "$device" ]; then
1002 EOF
1003 add_linuxrc <<-EOF
1004 device="$rootdev"
1005 EOF
1006 add_linuxrc <<-'EOF'
1007 echo "DEVICE set to $device based on fstab entry from initrd gen time"
1008 fi
1009
1010 # XXX hack, if no device, try to parse it from /proc/partitions using /proc/sys/kernel/real-root-dev
1011 if [ ! -e "$device" ]; then
1012 rrd=$(cat /proc/sys/kernel/real-root-dev)
1013 major=$(($rrd / 256))
1014 minor=$(($rrd % 256))
1015
1016 while read pmajor pminor blocks dev rest; do
1017 # skip header and empty line
1018 [ -z "$pmajor" -o "$pmajor" = "major" ] && continue
1019
1020 if [ $pmajor = $major -a $pminor = $minor ]; then
1021 device=/dev/$dev
1022 echo "DEVICE set to $device based on real-root-dev"
1023 fi
1024 done < /proc/partitions
1025 fi
1026
1027 [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
1028
1029 mount -t $ROOTFS -r $device $ROOTFLAGS /newroot || echo "Mount of rootfs failed."
1030 init=$INIT
1031 if [ -z "$init" -o ! -x "/newroot$init" ]; then
1032 init=/sbin/init
1033 fi
1034 EOF
1035
1036 busybox_applet dmesg
1037 busybox_applet tail
1038 add_linuxrc <<-'EOF'
1039 if [ "$DEBUGINITRD" -a "$DEBUGINITRD" != 'sh' ]; then
1040 echo "Last 20 lines of dmesg:"
1041 dmesg | tail -n 20
1042 fi
1043
1044 EOF
1045
1046 kmsg "geninitrd/$VERSION switching root"
1047
1048 umount_all
1049 busybox_applet switch_root usleep
1050 add_linuxrc <<-'EOF'
1051 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
1052
1053 # switch root to empty dir will make kernel panic, so sleep 10s before it
1054 # switch_root needs to be pid 1, so there's no other way to recover from here
1055 # if /dev is missing, switch root will likely fail, give debug shell before that
1056 if [ ! -d /newroot/dev ]; then
1057 echo "/dev is missing, switch_root will likely fail"
1058 echo "if you booted with debugrd=sh, then you be given shell and you might able to recover this situation"
1059 debugshell
1060 [ "$DEBUGINITRD" ] || usleep 10000000
1061 fi
1062
1063 # systemd[1]: /usr appears to be on its own filesytem and is not
1064 # already mounted. This is not a supported setup. Some things will
1065 # probably break (sometimes even silently) in mysterious ways. Consult
1066 # http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
1067 # for more information.
1068 echo trying to mount /usr
1069 chroot /newroot mount -n /usr
1070
1071 exec switch_root /newroot $init ${1:+"$@"}
1072
1073 # FIXME: this code is never executed, as "exec" does not return!
1074
1075 echo "Error! initramfs should not reach this place."
1076 echo "It probably means you've got old version of busybox, with broken"
1077 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1078
1079 exec chroot /newroot $init ${1:+"$@"}
1080
1081 echo "Failed to chroot!"
1082 debugshell
1083 EOF
1084 # we need /init being real file, not symlink, otherwise the initramfs will
1085 # not be ran by pid 1 which is required for switch_root
1086 mv $DESTDIR/linuxrc $DESTDIR/init
1087 ln -s init $DESTDIR/linuxrc
1088}
1089
1090# find if $symbol exists in System.map $mapfile
1091sym_exists() {
1092 local mapfile="$1"
1093 local symbol="$2"
1094 if [ ! -f $mapfile ]; then
1095 # missing mapfile (not a pld kernel?)
1096 return 1
1097 fi
1098
1099 awk -vc=1 -vsymbol="$symbol" '(tolower($2) == "t" || tolower($2) == "d") && $3 == symbol {c = 0} END {exit c}' $mapfile
1100}
1101
1102# find best compressor (or forced one) for initrd
1103find_compressor() {
1104 local mode="$1"
1105 local compressors='zstd xz lzma bzip2 gzip lzo'
1106
1107 # a specified one, take it
1108 if ! is_yes "$mode"; then
1109 compressors="$mode"
1110 fi
1111
1112 verbose "finding compressor: $compressors (via $mode)"
1113 # check for compressor validity
1114 local c prog map=/boot/System.map-$kernel
1115 for c in $compressors; do
1116 case $c in
1117 xz)
1118 sym=unxz
1119 prog=/usr/bin/xz
1120 ;;
1121 lzma)
1122 sym=unlzma
1123 prog=/usr/bin/xz
1124 ;;
1125 bzip2)
1126 sym=bzip2
1127 prog=/usr/bin/bzip2
1128 ;;
1129 gzip)
1130 sym=gunzip
1131 prog=/bin/gzip
1132 ;;
1133 lzo)
1134 sym=unlzo
1135 prog=/usr/bin/lzop
1136 ;;
1137 zstd)
1138 sym=zstd
1139 prog=/usr/bin/zstd
1140 ;;
1141 none|no)
1142 # any existing sym will work
1143 sym=initrd_load
1144 prog=/bin/cat
1145 ;;
1146 *)
1147 die "Unknown compressor $c"
1148 ;;
1149 esac
1150 if sym_exists $map $sym && [ -x $prog ]; then
1151 echo $c
1152 return
1153 fi
1154 done
1155
1156 verbose "using gzip for compressor (fallback)"
1157 echo gzip
1158}
1159
1160# compresses kernel image image
1161# in function so we could retry with other compressor on failure
1162compress_image() {
1163 local compressor="$1" IMAGE="$2" target="$3" tmp
1164 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1165
1166 case "$compressor" in
1167 xz)
1168 # don't use -9 here since kernel won't understand it
1169 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1170 ;;
1171 lzma)
1172 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1173 ;;
1174 bzip2)
1175 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1176 ;;
1177 gzip)
1178 gzip -9 < "$IMAGE" > "$tmp" || return $?
1179 ;;
1180 lzo)
1181 lzop -9 < "$IMAGE" > "$tmp" || return $?
1182 ;;
1183 zstd)
1184 zstd -9 < "$IMAGE" > "$tmp" || return $?
1185 ;;
1186 none|no)
1187 cat < "$IMAGE" > "$tmp" || return $?
1188 ;;
1189 esac
1190
1191 mv -f "$tmp" "$target"
1192}
1193
1194# prepend file to image
1195prepend_file_to_image() {
1196 local file="$1" target="$2" tmp
1197 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1198
1199 cat "$file" "$target" > "$tmp" || return $?
1200
1201 mv -f "$tmp" "$target"
1202}
1203
1204if [ -r /etc/sysconfig/geninitrd ]; then
1205 . /etc/sysconfig/geninitrd
1206fi
1207
1208if [ ! -f /proc/mounts ]; then
1209 warn "/proc filesystem not mounted, may cause wrong results or failure."
1210fi
1211
1212geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev swsusp tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd bcache
1213
1214while [ $# -gt 0 ]; do
1215 case $1 in
1216 --fstab=*)
1217 fstab=${1#--fstab=}
1218 ;;
1219 --fstab)
1220 fstab=$2
1221 shift
1222 ;;
1223 --modules-conf=*)
1224 modulefile=${1#--modules-conf=}
1225 ;;
1226 --modules-conf)
1227 modulefile=$2
1228 shift
1229 ;;
1230 --with-bootsplash)
1231 BOOT_SPLASH=yes
1232 ;;
1233 --without-bootsplash)
1234 BOOT_SPLASH=no
1235 ;;
1236 --with-fbsplash)
1237 FB_SPLASH=yes
1238 ;;
1239 --without-fbsplash)
1240 FB_SPLASH=no
1241 ;;
1242 --with-fbcondecor)
1243 FB_CON_DECOR=yes
1244 ;;
1245 --without-fbcondecor)
1246 FB_CON_DECOR=no
1247 ;;
1248 --without-swsusp)
1249 USE_SWSUSP=no
1250 ;;
1251 --with-suspend)
1252 USE_SUSPEND=yes
1253 ;;
1254 --without-suspend)
1255 USE_SUSPEND=no
1256 ;;
1257 --with-suspend2 | --with-tuxonice)
1258 USE_TUXONICE=yes
1259 ;;
1260 --without-suspend2 | --without-tuxonice)
1261 USE_TUXONICE=no
1262 ;;
1263 --lvmversion=*)
1264 LVMTOOLSVERSION=${1#--lvmversion=}
1265 ;;
1266 --lvmtoolsversion=*)
1267 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1268 ;;
1269 --lvmtoolsversion|--lvmversion)
1270 LVMTOOLSVERSION=$2
1271 shift
1272 ;;
1273 --without-udev)
1274 USE_UDEV=no
1275 ;;
1276 --with-udev)
1277 USE_UDEV=yes
1278 ;;
1279 --without-dmraid)
1280 USE_DMRAID=no
1281 ;;
1282 --without-multipath)
1283 USE_MULTIPATH=no
1284 ;;
1285 --with-multipath=*)
1286 USE_MULTIPATH=${1#--with-multipath=}
1287 ;;
1288 --without-blkid)
1289 USE_BLKID=no
1290 ;;
1291 --without-luks)
1292 USE_LUKS=no
1293 ;;
1294 --with=*)
1295 BASICMODULES="$BASICMODULES ${1#--with=}"
1296 ;;
1297 --with)
1298 BASICMODULES="$BASICMODULES $2"
1299 shift
1300 ;;
1301 --version)
1302 echo "$PROGRAM: version $VERSION"
1303 exit 0
1304 ;;
1305 -v)
1306 if [ x"$verbose" = x"-v" ]; then
1307 verbose="-v -v"
1308 else
1309 verbose="-v"
1310 fi
1311 exec 3>&1
1312 ;;
1313 --compress)
1314 COMPRESS=$2
1315 ;;
1316 --compress=*)
1317 COMPRESS="${1#--compress=}"
1318 ;;
1319 --nocompress)
1320 COMPRESS=no
1321 ;;
1322 --nostrip)
1323 STRIP=
1324 ;;
1325 --strip=*)
1326 STRIP="${1#--strip=}"
1327 ;;
1328 --strip)
1329 STRIP=$2
1330 shift
1331 ;;
1332 --ifneeded)
1333 ifneeded=1
1334 ;;
1335 -f)
1336 force=1
1337 ;;
1338 --preload=*)
1339 PREMODS="$PREMODS ${1#--preload=}"
1340 ;;
1341 --preload)
1342 PREMODS="$PREMODS $2"
1343 shift
1344 ;;
1345 --fs=* | --fs)
1346 die "--fs option is obsoleted. Use --initrdfs instead"
1347 ;;
1348 --initrdfs=*)
1349 INITRDFS=${1#--initrdfs=}
1350 ;;
1351 --initrdfs)
1352 INITRDFS=$2
1353 shift
1354 ;;
1355 --image-version)
1356 img_vers=yes
1357 ;;
1358 --ide-only-root)
1359 ide_only_root="yes"
1360 ;;
1361 *)
1362 if [ -z "$target" ]; then
1363 target="$1"
1364 elif [ -z "$kernel" ]; then
1365 kernel="$1"
1366 else
1367 usage
1368 exit 1
1369 fi
1370 ;;
1371 esac
1372
1373 shift
1374done
1375
1376if [ -z "$target" -o -z "$kernel" ]; then
1377 usage
1378 exit 1
1379fi
1380
1381# main()
1382if [ "$(id -u)" != 0 ]; then
1383 die "You need to be root to generate initrd"
1384fi
1385
1386for dir in libx32 lib64 lib; do
1387 initrd_dir=/usr/$dir/initrd
1388 if [ -d "$initrd_dir" ]; then
1389 initrd_dirs="$initrd_dirs $initrd_dir"
1390 fi
1391done
1392
1393kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1394kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1395
1396verbose "# geninitrd $VERSION"
1397debug "Using initrd_dir: $initrd_dir"
1398
1399busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1400
1401# we setup mods after parsing command line args
1402geninitrd_setup_mods
1403
1404if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1405 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1406fi
1407
1408if [ -z "$INITRDFS" ]; then
1409 if [ -n "$FS" ]; then
1410 # FS= can came only via /etc/sysconfig/geninitrd likely?
1411 die "FS configuration option is obsoleted. Use INITRDFS instead"
1412 fi
1413
1414 # default value
1415 if [ "$kernel_version" -ge "002005" ]; then
1416 INITRDFS="initramfs"
1417 else
1418 INITRDFS="rom"
1419 fi
1420fi
1421
1422check_initrd_fs() {
1423 local s sfound sym p prog map=/boot/System.map-$kernel
1424 case "$INITRDFS" in
1425 ext2)
1426 # TODO: symbols to check in case of ext2 used via ext3/4 subsystem
1427 sym=init_ext2_fs
1428 prog=/sbin/mke2fs
1429 ;;
1430 rom|romfs)
1431 sym=init_romfs_fs
1432 prog=/sbin/genromfs
1433 ;;
1434 cram|cramfs)
1435 sym=init_cramfs_fs
1436 prog=/sbin/mkcramfs
1437 ;;
1438 initramfs)
1439 sym=__initramfs_start
1440 prog="/bin/cpio /usr/bin/find"
1441 ;;
1442 *)
1443 die "Filesystem $INITRDFS on initrd is not supported by geninitrd"
1444 ;;
1445 esac
1446
1447 # only one is needed (for cases like ext2 via ext2 or via ext3 or via ext4 subsysytem)
1448 sfound=0
1449 for s in $sym; do
1450 sym_exists $map $s && sfound=1
1451 break
1452 done
1453 if [ "$sfound" -eq "0" ]; then
1454 die "Filesystem $INITRDFS on initrd is not supported by kernel"
1455 fi
1456
1457 for p in $prog; do
1458 [ ! -x "$p" ] && die "$prog is missing"
1459 done
1460}
1461check_initrd_fs
1462
1463if [ -L "$target" ]; then
1464 target=$(readlink -f "$target")
1465fi
1466
1467if [ -n "$img_vers" ]; then
1468 target="$target-$kernel"
1469fi
1470
1471if [ -z "$force" -a -f "$target" ]; then
1472 die "$target already exists."
1473fi
1474
1475if [ ! -d "/lib/modules/$kernel" ]; then
1476 die "/lib/modules/$kernel is not a directory."
1477fi
1478
1479if [ "$kernel_version" -ge "002005" ]; then
1480 modext=".ko"
1481fi
1482
1483cache_modprobe_conf
1484
1485for n in $PREMODS; do
1486 find_module "$n"
1487done
1488
1489if [ "$FBMODULE" ]; then
1490 find_module "$FBMODULE"
1491fi
1492
1493# autodetect USB keyboards
1494find_modules_usbkbd
1495
1496# allow forcing loading SCSI and/or IDE modules
1497# XXX: where ADDSCSI cames from? drop?
1498if is_yes "$ADDSCSI"; then
1499 find_modules_scsi
1500fi
1501
1502# autodetect SATA modules
1503find_modules_sata
1504
1505# XXX: where ADDIDE cames from? drop?
1506if is_yes "$ADDIDE"; then
1507 find_modules_ide
1508fi
1509
1510if is_yes "$USE_SUSPEND"; then
1511 find_modules_suspend
1512fi
1513
1514if is_yes "$USE_SWSUSP"; then
1515 find_modules_swsusp
1516fi
1517
1518find_root "$fstab" || exit
1519verbose "Using $rootdev as device for rootfs"
1520
1521find_modules_for_devpath "$rootdev"
1522
1523# if USE_MULTIPATH is path to device, scan that too
1524# this is to bootstrap multipath setup into initrd.
1525if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1526 find_modules_multipath $USE_MULTIPATH
1527fi
1528
1529find_module "-$rootFs"
1530
1531for n in $BASICMODULES; do
1532 find_module "$n"
1533done
1534
1535if is_yes "$USE_TUXONICE"; then
1536 find_module "-lzf"
1537fi
1538
1539find_modules_uvesafb
1540find_modules_fbsplash
1541
1542if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1543 verbose "No modules are needed -- not building initrd image."
1544 exit 0
1545fi
1546
1547verbose "Building initrd..."
1548DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1549RCFILE="$DESTDIR/linuxrc"
1550> "$RCFILE"
1551chmod a+rx "$RCFILE"
1552ln -s linuxrc $DESTDIR/init
1553
1554# create dirs that we really need
1555inst_d /{lib,bin,sbin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys,tmp}
1556
1557modules_install "$MODULES"
1558
1559# mknod'ing the devices instead of copying them works both with and
1560# without devfs...
1561mknod -m 600 "$DESTDIR/dev/console" c 5 1
1562mknod -m 666 "$DESTDIR/dev/null" c 1 3
1563mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1564mknod -m 666 "$DESTDIR/dev/random" c 1 8
1565mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1566mknod -m 644 "$DESTDIR/dev/kmsg" c 1 11
1567
1568inst_exec $busybox /bin/busybox
1569ln -s busybox $DESTDIR/bin/sh
1570# for older busyboxes who had /bin/initrd-busybox as EXEPATH
1571ln -s busybox $DESTDIR/bin/initrd-busybox
1572
1573add_linuxrc <<EOF
1574#!/bin/sh
1575# initrd generated by geninitrd/$VERSION
1576# on $(LC_ALL=C date)
1577
1578EOF
1579load_font
1580mount_proc
1581
1582kmsg "geninitrd/$VERSION starting"
1583
1584inst_d /lib/geninitrd/
1585inst /lib/geninitrd/functions.initrd /lib/geninitrd/functions.initrd
1586
1587add_linuxrc <<-EOF
1588 . /lib/geninitrd/functions.initrd
1589 # builtin defaults from geninitrd
1590 ROOT=$rootdev
1591 ROOTFS=$rootFs
1592EOF
1593add_linuxrc <<-'EOF'
1594 read CMDLINE < /proc/cmdline
1595
1596 for arg in $CMDLINE; do
1597 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1598 DEBUGINITRD=yes
1599 fi
1600 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1601 DEBUGINITRD=${arg##debug*rd=}
1602 fi
1603 if [ "${arg##root=}" != "${arg}" ]; then
1604 ROOT=${arg##root=}
1605 fi
1606 if [ "${arg##rootfs=}" != "${arg}" ]; then
1607 ROOTFS=${arg##rootfs=}
1608 fi
1609 if [ "${arg##rootflags=}" != "${arg}" ]; then
1610 ROOTFLAGS=${arg##rootflags=}
1611 fi
1612 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1613 ROOTFSFLAGS=${arg##rootfsflags=}
1614 fi
1615 if [ "${arg##init=}" != "${arg}" ]; then
1616 INIT=${arg##init=}
1617 fi
1618 done
1619
1620 # handling of invalid, rootfsflags, option
1621 if [ -n "$ROOTFSFLAGS" ]; then
1622 if [ -n "$ROOTFLAGS" ]; then
1623 ROOTFLAGS="$ROOTFLAGS,$ROOTFSFLAGS"
1624 else
1625 ROOTFLAGS="$ROOTFSFLAGS"
1626 fi
1627 fi
1628
1629 if [ "$DEBUGINITRD" = "sh" ]; then
1630 # export some vars to subshell for debug to work
1631 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFLAGS DEBUGINITRD INIT
1632 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1633 export rootnr attrs majmin major minor device
1634
1635 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1636 debugshell() {
1637EOF
1638if is_yes "$RUN_SULOGIN_ON_ERR"; then
1639add_linuxrc <<-'EOF'
1640 echo "debug shell disabled by RUN_SULOGIN_ON_ERR=yes from /etc/sysconfig/system during initrd generation time"
1641EOF
1642else
1643add_linuxrc <<-'EOF'
1644 sh
1645EOF
1646fi
1647add_linuxrc <<-'EOF'
1648 }
1649 else
1650 debugshell() {
1651 :
1652 }
1653 fi
1654
1655 if [ "$DEBUGINITRD" ]; then
1656 set -x
1657 fi
1658EOF
1659
1660# mount early
1661mount_tmp
1662mount_run
1663
1664modules_add_linuxrc $MODULES
1665
1666# TODO: rewrite for busybox
1667#if [ -n "$loopDev" ]; then
1668# if [ ! -d /initrd ]; then
1669# mkdir /initrd
1670# fi
1671#
1672# cp -a "$loopDev" "$DESTDIR/dev"
1673# cp -a "$rootdev" "$DESTDIR/dev"
1674# echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1675# echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1676# echo "echo Setting up loopback device $rootdev" >> $RCFILE
1677# echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1678#fi
1679
1680if is_yes "$USE_UDEV"; then
1681 initrd_gen_udev
1682else
1683 initrd_gen_mdev
1684fi
1685
1686initrd_gen_uvesafb
1687initrd_gen_luks
1688initrd_gen_dmraid
1689initrd_gen_multipath
1690initrd_gen_blkid
1691
1692if is_yes "$have_nfs"; then
1693 initrd_gen_nfs
1694else
1695 initrd_gen_md
1696 initrd_gen_lvm
1697 initrd_gen_bcache
1698 initrd_gen_blkid
1699 initrd_gen_luks
1700 initrd_gen_setrootdev
1701fi
1702
1703# additional devs always needed
1704[ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1705
1706initrd_gen_stop_udevd
1707initrd_gen_stop_mdev
1708initrd_gen_stop_uvesafb
1709
1710# resume after killing local processes
1711initrd_gen_tuxonice
1712initrd_gen_suspend
1713initrd_gen_swsusp
1714
1715# clean up env
1716add_linuxrc <<-'EOF'
1717if [ ! "$DEBUGINITRD" ]; then
1718 ifs=$IFS
1719 IFS="
1720 "
1721 for i in $(export -p); do
1722 i=${i#declare -x } # ksh/bash
1723 i=${i#export } # busybox
1724
1725 case "$i" in
1726 *=*)
1727 : ;;
1728 *)
1729 continue ;;
1730 esac
1731
1732 i=${i%%=*}
1733
1734 [ -z "$i" ] && continue
1735
1736 case "$i" in
1737 ROOT|PATH|HOME|TERM)
1738 :
1739 ;;
1740 *)
1741 unset $i
1742 ;;
1743 esac
1744 done
1745 IFS=$ifs
1746fi
1747EOF
1748
1749if [ "$INITRDFS" = "initramfs" ]; then
1750 initrd_gen_initramfs_switchroot
1751else
1752 umount_all
1753fi
1754
1755initrd_gen_fbsplash
1756initrd_gen_fbcondecor
1757
1758debug "Current /linuxrc:\n$(sed -e 's,^,| ,' $DESTDIR/linuxrc)"
1759
1760IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1761
1762IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1763verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1764
1765verbose "Creating $INITRDFS image $IMAGE"
1766case "$INITRDFS" in
1767 ext2)
1768 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1769 # NOTE: ext2 label is max 16 chars
1770 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1771 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1772
1773 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1774 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1775 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1776 # We don't need this directory, so let's save space
1777 rm -rf "$tmpmnt"/lost+found
1778
1779 debug "Copy recursively $DESTDIR -> $tmpmnt"
1780 cp -a $DESTDIR/* $tmpmnt
1781 umount "$IMAGE"
1782 rmdir "$tmpmnt"
1783
1784 ;;
1785 rom|romfs)
1786 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1787 ;;
1788 cram|cramfs)
1789 mkcramfs "$DESTDIR" "$IMAGE"
1790 ;;
1791 initramfs)
1792 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1793 ;;
1794 *)
1795 die "Filesystem $INITRDFS not supported by $PROGRAM"
1796esac
1797
1798if [ "$INITRDFS" != "initramfs" ]; then
1799 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1800 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1801 CONFIG_BLK_DEV_RAM_SIZE=4096
1802 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1803 fi
1804
1805 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1806 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1807 fi
1808fi
1809
1810if ! is_no "$COMPRESS"; then
1811 compressor=$(find_compressor "$COMPRESS")
1812 verbose "Compressing $target with $compressor"
1813
1814 # TODO: the image name (specified from kernel.spec) already contains
1815 # extension, which is .gz most of the time.
1816 compress_image "$compressor" "$IMAGE" "$target" || {
1817 if [ $compressor != gzip ]; then
1818 warn "Could not compress with $compressor, retrying with gzip"
1819 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1820 else
1821 die "Could not compress image with $compressor"
1822 fi
1823 }
1824else
1825 cp -a "$IMAGE" "$target"
1826fi
1827
1828# microcode support for lilo
1829if ! is_no "$LILO_MICROCODE"; then
1830 if [ -x /sbin/lilo -a -f "/boot/intel-ucode.img" ]; then
1831 verbose "Prepending $target with microcode image /boot/intel-ucode.img for LILO"
1832 prepend_file_to_image "/boot/intel-ucode.img" "$target"
1833 fi
1834fi
1835
1836# XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1837initrd_gen_bootsplash "$target"
1838
1839rm -rf "$DESTDIR" "$IMAGE"
1840
1841# vim:ts=4:sw=4:noet:fdm=marker
This page took 0.091544 seconds and 4 git commands to generate.