tinyramfs/generate
2020-01-07 00:39:15 +03:00

97 lines
3.1 KiB
Bash
Executable File

#!/bin/sh
#
# tiny initramfs generation tool
# debugging
set -x
# check root
if [ "$(id -u)" != 0 ]; then
echo "must be run as root!"
exit 1
fi
# check files
[ -f ./config ] && . ./config || ( echo "config doesn't exists";exit 1 )
[ -x ./busybox ] && ldd ./busybox | grep -q "not a dynamic executable" || ( echo "busybox doesn't exists or dynamically linked. please download or/and build static busybox";exit 1 )
[ -f ./init ] || ( echo "init doesn't exists";exit 1 )
# variables
tmpdir="$(mktemp -d /tmp/initramfs.XXXXXXXX)"
kernel="$(uname -r)"
moddir="/lib/modules"
# structure
for d in bin dev etc usr/lib usr/bin mnt/root proc root sys; do
mkdir -p "$tmpdir/$d"
done
# make libraries and binaries happy
ln -rs "$tmpdir/usr/lib" "$tmpdir/lib"
ln -rs "$tmpdir/usr/lib" "$tmpdir/lib64"
ln -rs "$tmpdir/usr/lib" "$tmpdir/lib32"
ln -rs "$tmpdir/usr/bin" "$tmpdir/bin"
ln -rs "$tmpdir/usr/bin" "$tmpdir/sbin"
# 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 -exec cp --parents "{}" "$tmpdir" ";"
cp "$moddir/$kernel/modules.softdep" "$moddir/$kernel/modules.builtin" "$moddir/$kernel/modules.order" "$tmpdir/$moddir/$kernel"
# create modules.* files
depmod -b "$tmpdir" "$kernel"
# install binaries
for b in $(echo $binaries); do
cp "$(which $b)" "$tmpdir/usr/bin/$b" && chmod +x "$tmpdir/usr/bin/$b"
# check statically linking
ldd "$(which $b)" >/dev/null || continue
# handle .so symlinks for dymanically linked binaries
for l in $(ldd "$(which $b)" | sed -nre 's,.* (/.*lib.*/.*.so.*) .*,\1,p' -e 's,.*(/lib.*/ld.*.so.*) .*,\1,p'); do
if [ -h "$l" ]; then
# regular
cp -n --parents "$(readlink -f $l)" "$tmpdir"
# symlink
cp -n -a --parents "$l" "$tmpdir"
else
cp -n --parents "$(readlink -f $l)" "$tmpdir"
fi
done
done
# install files
cp ./init "$tmpdir/init" && chmod +x "$tmpdir/init"
cp ./busybox "$tmpdir/bin/busybox" && chmod +x "$tmpdir/bin/busybox"
# strip binaries and libraries
# uncomment this if your initramfs are huge
#find "$tmpdir" -type f -executable -exec strip -s "{}" ";"
# initialize config
cat <<EOF > "$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"; then
echo "failed"
exit 1
fi
rm -rf "$tmpdir"
echo "done! check out initramfs-$kernel.img.gz"