#!/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 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 unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX) DATADIR=/usr/share/mkinitramfs INITIN=/usr/share/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 # Add lvm if present if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi 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 if [ "$library" == "linux-vdso.so.1" ] || [ "$library" == "linux-gate.so.1" ]; then continue fi 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 # 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 # Remove the temporary directory and file rm -rf $WDIR $unsorted printf "done.\n"