#!/bin/sh # # tiny initramfs generation tool # debugging set -x # check root and files if [ "$(id -u)" != 0 ]; then echo "must be run as root" exit 1 elif [ ! -e ./config ]; then echo "config doesn't exists" exit 1 elif [ ! -e ./init ]; then echo "init doesn't exists" exit 1 elif [ ! -n "$(ldd ./busybox | grep "not a dynamic executable")" ]; then echo "busybox doesn't exists or dynamically linked. please download or/and build static busybox" exit 1 fi # source config . ./config # variables tmpdir="$(mktemp -d /tmp/initramfs.XXXXXXXX)" kernel="$(uname -r)" moddir="/lib/modules" # structure for d in dev etc usr/lib usr/bin mnt/root proc root sys; do mkdir -p "$tmpdir/$d" done # symlinks for s in lib lib64 bin sbin; do case "$s" in lib*) ( cd "$tmpdir" && ln -s "usr/lib" "$s" ) ;; *bin) ( cd "$tmpdir" && ln -s "usr/bin" "$s" ) ;; esac done # TODO parse fstab | crypttab #while [ "$use_fstab" -eq 1 ] && read fs dir type opts; do thing; done < /etc/fstab # TODO rewrite drivers installing | handle $drivers config var # install drivers find \ "$moddir/$kernel/kernel/drivers/virtio" \ "$moddir/$kernel/kernel/arch" \ "$moddir/$kernel/kernel/crypto" \ "$moddir/$kernel/kernel/fs" \ "$moddir/$kernel/kernel/lib" \ "$moddir/$kernel/kernel/drivers/block" \ "$moddir/$kernel/kernel/drivers/ata" \ "$moddir/$kernel/kernel/drivers/md" \ "$moddir/$kernel/kernel/drivers/scsi" \ "$moddir/$kernel/kernel/drivers/usb/storage" \ "$moddir/$kernel/kernel/drivers/usb/host" \ -type f | cpio -pd "$tmpdir" 2>/dev/null # install list of drivers cp "$moddir/$kernel/modules.softdep" "$moddir/$kernel/modules.builtin" "$moddir/$kernel/modules.order" "$tmpdir/$moddir/$kernel" # generate dependencies list of drivers depmod -b "$tmpdir" "$kernel" # install and strip binaries and libraries for b in $(echo $binaries); do cp "$(command -v $b)" "$tmpdir/usr/bin" chmod +x "$tmpdir/usr/bin/$b" strip -s "$tmpdir/usr/bin/$b" # check statically linking ldd "$(command -v $b)" >/dev/null || continue # handle libraries symlinks for dymanically linked binaries for l in $(ldd "$(command -v $b)" | sed -nre 's,.* (/.*lib.*/.*.so.*) .*,\1,p' -e 's,.*(/lib.*/ld.*.so.*) .*,\1,p'); do # check symlink if [ -h "$l" ]; then # check file exists if [ ! -e "$tmpdir/usr/lib/${l##*/}" ] && [ ! -e "$tmpdir/usr/lib/$(readlink $l)" ]; then # regular cp "$(readlink -f $l)" "$tmpdir/usr/lib" strip -s "$tmpdir/usr/lib/$(readlink $l)" # symlink cp -a "$l" "$tmpdir/usr/lib" fi else if [ ! -e "$tmpdir/usr/lib/$(readlink $l)" ]; then cp "$(readlink -f $l)" "$tmpdir/usr/lib" strip -s "$tmpdir/usr/lib/$(readlink $l)" fi fi done done # install files cp ./init "$tmpdir/init" && chmod +x "$tmpdir/init" cp ./busybox "$tmpdir/usr/bin/busybox" && chmod +x "$tmpdir/usr/bin/busybox" # initialize config cat < "$tmpdir/config" root="$root" rootfstype="$rootfstype" rootflags="$rootflags" drivers="$drivers" #use_lvm="$use_lvm" #lvm_discard="$lvm_discard" #use_luks="$use_luks" #luks_header="$luks_header" #luks_keyfile="$luks_keyfile" #luks_discard="$luks_discard" EOF # packing if ! ( cd "$tmpdir" && find . | cpio --create --verbose --format=newc | gzip --best ) > "./initramfs-$kernel.img.gz" 2>/dev/null; then echo "failed" exit 1 fi # remove tmpdir rm -rf "$tmpdir" echo "done! check out initramfs-$kernel.img.gz"