9.3 KiB
cat > /sbin/mkinitramfs << "EOF" #!/bin/bash
This file based in part on the mkinitramfs script for the LFS LiveCD
written by Alexander E. Patrakov and Jeremy Huntwork.
copy() { local file
if [ "$2" = "lib" ]; then file=$(PATH=/lib:/usr/lib type -p $1) else file=$(type -p $1) fi
if [ -n "$file" ] ; then cp $file $WDIR/$2 else echo "Missing required file: $1 for directory $2" rm -rf $WDIR exit 1 fi }
if [ -z $1 ] ; then INITRAMFS_FILE=initrd.img-no-kmods else KERNEL_VERSION=$1 INITRAMFS_FILE=initrd.img-$KERNEL_VERSION fi
if [ -n "$KERNEL_VERSION" ] && [ ! -d "/lib/modules/$1" ] ; then echo "No modules directory named $1" exit 1 fi
mkdir -p /usr/share/mkinitramfs && cat > /usr/share/mkinitramfs/init.in << "EOF" #!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
problem() { printf "Encountered a problem!\n\nDropping you to a shell.\n\n" sh }
no_device() { printf "The device %s, which is supposed to contain the\n" $1 printf "root file system, does not exist.\n" printf "Please fix this problem and exit this shell.\n\n" }
no_mount() { printf "Could not mount device %s\n" $1 printf "Sleeping forever. Please reboot and fix the kernel command line.\n\n" printf "Maybe the device is formatted with an unsupported file system?\n\n" printf "Or maybe filesystem type autodetection went wrong, in which case\n" printf "you should add the rootfstype=... parameter to the kernel command line.\n\n" printf "Available partitions:\n" }
do_mount_root() { mkdir /.root [ -n "$rootflags" ] && rootflags="$rootflags," rootflags="$rootflags$ro"
case "$root" in /dev/* ) device=$root ;; UUID=* ) eval $root; device="/dev/disk/by-uuid/$UUID" ;; PARTUUID=) eval $root; device="/dev/disk/by-partuuid/$PARTUUID" ;; LABEL= ) eval $root; device="/dev/disk/by-label/$LABEL" ;; "" ) echo "No root device specified." ; problem ;; esac
while [ ! -b "$device" ] ; do no_device $device problem done
if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then no_mount $device cat /proc/partitions while true ; do sleep 10000 ; done else echo "Successfully mounted device $root" fi }
do_try_resume() { case "$resume" in UUID=* ) eval $resume; resume="/dev/disk/by-uuid/$UUID" ;; LABEL=*) eval $resume; resume="/dev/disk/by-label/$LABEL" ;; esac
if $noresume || ! [ -b "$resume" ]; then return; fi
ls -lH "$resume" | ( read x x x x maj min x echo -n ${maj%,}:$min > /sys/power/resume ) }
init=/sbin/init root= rootdelay= rootfstype=auto ro="ro" rootflags= device= resume= noresume=false
mount -n -t devtmpfs devtmpfs /dev mount -n -t proc proc /proc mount -n -t sysfs sysfs /sys mount -n -t tmpfs tmpfs /run
read -r cmdline < /proc/cmdline
for param in $cmdline ; do case $param in init=* ) init=${param#init=} ;; root=* ) root=${param#root=} ;; rootdelay=* ) rootdelay=${param#rootdelay=} ;; rootfstype=) rootfstype=${param#rootfstype=} ;; rootflags= ) rootflags=${param#rootflags=} ;; resume=* ) resume=${param#resume=} ;; noresume ) noresume=true ;; ro ) ro="ro" ;; rw ) ro="rw" ;; esac done
udevd location depends on version
if [ -x /sbin/udevd ]; then UDEVD=/sbin/udevd elif [ -x /lib/udev/udevd ]; then UDEVD=/lib/udev/udevd elif [ -x /lib/systemd/systemd-udevd ]; then UDEVD=/lib/systemd/systemd-udevd else echo "Cannot find udevd nor systemd-udevd" problem fi
${UDEVD} --daemon --resolve-names=never udevadm trigger udevadm settle
if [ -f /etc/mdadm.conf ] ; then mdadm -As ; fi if [ -x /sbin/vgchange ] ; then /sbin/vgchange -a y > /dev/null ; fi if [ -n "$rootdelay" ] ; then sleep "$rootdelay" ; fi
do_try_resume # This function will not return if resuming from disk do_mount_root
killall -w ${UDEVD##*/}
exec switch_root /.root "$init" "$@"
EOF
printf "Creating $INITRAMFS_FILE... "
binfiles="sh cat cp dd killall ls mkdir mknod mount " binfiles="$binfiles umount sed sleep ln rm uname" binfiles="$binfiles readlink basename"
Systemd installs udevadm in /bin. Other udev implementations have it in /sbin
if [ -x /bin/udevadm ] ; then binfiles="$binfiles udevadm"; fi
sbinfiles="modprobe blkid switch_root"
#Optional files and locations for f in mdadm mdmon udevd udevadm; do if [ -x /sbin/$f ] ; then sbinfiles="$sbinfiles $f"; fi done
Add lvm if present (cannot be done with the others because it
also needs dmsetup
if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi
unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)
DATADIR=/usr/share/mkinitramfs INITIN=init.in
Create a temporary working directory
WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)
Create base directory structure
mkdir -p $WDIR/{bin,dev,lib/firmware,run,sbin,sys,proc,usr} mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d} touch $WDIR/etc/modprobe.d/modprobe.conf ln -s lib $WDIR/lib64 ln -s ../bin $WDIR/usr/bin
Create necessary device nodes
mknod -m 640 $WDIR/dev/console c 5 1 mknod -m 664 $WDIR/dev/null c 1 3
Install the udev configuration files
if [ -f /etc/udev/udev.conf ]; then cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf fi
for file in $(find /etc/udev/rules.d/ -type f) ; do cp $file $WDIR/etc/udev/rules.d done
Install any firmware present
cp -a /lib/firmware $WDIR/lib
Copy the RAID configuration file if present
if [ -f /etc/mdadm.conf ] ; then cp /etc/mdadm.conf $WDIR/etc fi
Install the init file
install -m0755 $DATADIR/$INITIN $WDIR/init
if [ -n "$KERNEL_VERSION" ] ; then if [ -x /bin/kmod ] ; then binfiles="$binfiles kmod" else binfiles="$binfiles lsmod" sbinfiles="$sbinfiles insmod" fi fi
Install basic binaries
for f in $binfiles ; do if [ -e /bin/$f ]; then d="/bin"; else d="/usr/bin"; fi ldd $d/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted copy $d/$f bin done
for f in $sbinfiles ; do ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted copy $f sbin done
Add udevd libraries if not in /sbin
if [ -x /lib/udev/udevd ] ; then ldd /lib/udev/udevd | sed "s/\t//" | cut -d " " -f1 >> $unsorted elif [ -x /lib/systemd/systemd-udevd ] ; then ldd /lib/systemd/systemd-udevd | sed "s/\t//" | cut -d " " -f1 >> $unsorted fi
Add module symlinks if appropriate
if [ -n "$KERNEL_VERSION" ] && [ -x /bin/kmod ] ; then ln -s kmod $WDIR/bin/lsmod ln -s kmod $WDIR/bin/insmod fi
Add lvm symlinks if appropriate
Also copy the lvm.conf file
if [ -x /sbin/lvm ] ; then ln -s lvm $WDIR/sbin/lvchange ln -s lvm $WDIR/sbin/lvrename ln -s lvm $WDIR/sbin/lvextend ln -s lvm $WDIR/sbin/lvcreate ln -s lvm $WDIR/sbin/lvdisplay ln -s lvm $WDIR/sbin/lvscan
ln -s lvm $WDIR/sbin/pvchange ln -s lvm $WDIR/sbin/pvck ln -s lvm $WDIR/sbin/pvcreate ln -s lvm $WDIR/sbin/pvdisplay ln -s lvm $WDIR/sbin/pvscan
ln -s lvm $WDIR/sbin/vgchange ln -s lvm $WDIR/sbin/vgcreate ln -s lvm $WDIR/sbin/vgscan ln -s lvm $WDIR/sbin/vgrename ln -s lvm $WDIR/sbin/vgck
Conf file(s)
cp -a /etc/lvm $WDIR/etc fi
Install libraries
sort $unsorted | uniq | while read library ; do
linux-vdso and linux-gate are pseudo libraries and do not correspond to a file
libsystemd-shared is in /lib/systemd, so it is not found by copy, and
it is copied below anyway
copy $library lib done
if [ -d /lib/udev ]; then cp -a /lib/udev $WDIR/lib fi if [ -d /lib/systemd ]; then cp -a /lib/systemd $WDIR/lib fi if [ -d /lib/elogind ]; then cp -a /lib/elogind $WDIR/lib fi
Install the kernel modules if requested
if [ -n "$KERNEL_VERSION" ]; then
find
/lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib}
/lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire}
/lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio}
/lib/modules/$KERNEL_VERSION/kernel/drivers/usb/{host,storage}
-type f 2> /dev/null | cpio --make-directories -p --quiet $WDIR
cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order}
$WDIR/lib/modules/$KERNEL_VERSION
depmod -b $WDIR $KERNEL_VERSION fi
( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) > $INITRAMFS_FILE
Prepare early loading of microcode if available
if ls /lib/firmware/intel-ucode/* >/dev/null 2>&1 || ls /lib/firmware/amd-ucode/* >/dev/null 2>&1; then
first empty WDIR to reuse it
rm -r $WDIR/*
DSTDIR=$WDIR/kernel/x86/microcode mkdir -p $DSTDIR
if [ -d /lib/firmware/amd-ucode ]; then cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin fi
if [ -d /lib/firmware/intel-ucode ]; then cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin fi
( cd $WDIR; find . | cpio -o -H newc --quiet ) > microcode.img cat microcode.img $INITRAMFS_FILE > tmpfile mv tmpfile $INITRAMFS_FILE rm microcode.img fi
Remove the temporary directories and files
rm -rf $WDIR $unsorted printf "done.\n"
EOF
chmod 0755 /sbin/mkinitramfs