mkinitrd

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 81966b4393623e7f701213b369df0d177696d236
Author: emmett1 <emmett1.2miligrams@protonmail.com>
Date:   Sun,  7 Sep 2025 11:55:44 +0800

updated

Diffstat:
AMakefile | 24++++++++++++++++++++++++
Ainit | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amkinitrd | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 277 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,24 @@ +PREFIX = /usr +BINDIR = $(PREFIX)/bin +SHAREDIR = $(PREFIX)/share/mkinitrd +INSTALL = install -D + +DESTDIR ?= + +.PHONY: all install uninstall + +all: + @echo "Nothing to build. Run 'make install' to install files." + +install: + @echo "Installing mkinitrd to $(DESTDIR)$(BINDIR)/mkinitrd" + $(INSTALL) -m 755 mkinitrd $(DESTDIR)$(BINDIR)/mkinitrd + + @echo "Installing init to $(DESTDIR)$(SHAREDIR)/init" + $(INSTALL) -m 644 init $(DESTDIR)$(SHAREDIR)/init + +uninstall: + @echo "Removing installed files from real system..." + rm -f $(BINDIR)/mkinitrd + rm -f $(SHAREDIR)/init + diff --git a/init b/init @@ -0,0 +1,92 @@ +#!/bin/busybox sh + +/bin/busybox --install -s /bin + +NEWROOT=/newroot +init=/sbin/init +root= +rootdelay= +rootfstype=auto +ro="ro" +rootflags= +device= + +mkdir -p $NEWROOT +mount -t proc proc /proc +mount -t sysfs sysfs /sys +mount -t tmpfs run /run +mount -t devtmpfs dev /dev + +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=} ;; + ro ) ro="ro" ;; + rw ) ro="rw" ;; + shell ) shell=1 ;; + esac +done + +# mdev +[ -f /proc/sys/kernel/hotplug ] && \ + echo $(which mdev) > /proc/sys/kernel/hotplug +mdev -s + +# load modules using modalias +find /sys -name 'modalias' -type f -exec cat '{}' + | sort -u | xargs modprobe -b -a 2>/dev/null + +# load modules specific modules +for m in virtio virtio_ring virtio_pci virtio_blk virtio_scsi nvme \ + ata_piix sd_mod sr_mod cdrom loop squashfs isofs overlay mbcache \ + jbd jbd2 ext2 ext3 ext4 xfs btrfs f2fs reiserfs jfs fat vfat exfat ntfs3; do + modprobe "$m" 2>/dev/null +done + +[ "$shell" ] && exec sh + +[ "$rootflags" ] && rootflags="$rootflags," +rootflags="$rootflags$ro" + +case "$root" in + /dev/* ) device=$root ;; + UUID=* ) eval $root; device="$(blkid | grep "$UUID" | cut -d : -f1 | head -n1)" ;; + LABEL=* ) eval $root; device="$(blkid | grep "$LABEL" | cut -d : -f1 | head -n1)" ;; + "" ) echo "!! no root device specified" ; exec sh;; +esac + +if [ "$rootdelay" ]; then + while [ ! -b "$device" ] && [ $i -lt "$rootdelay" ]; do + echo ">> waiting for $device..." + sleep 1 + i=$((i+1)) + done +fi + +while [ ! -b "$device" ] ; do + echo "!! device '$device' not found" + exec sh +done + +if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" $NEWROOT; then + echo "!! failed to mount device '$device'" + exec sh +fi + +[ "$shell" ] && exec sh + +mount --move /sys $NEWROOT/sys +mount --move /proc $NEWROOT/proc +mount --move /dev $NEWROOT/dev +mount --move /run $NEWROOT/run + +# switch to newroot +exec /bin/switch_root $NEWROOT $init $@ + +echo ">> this is the end of initramfs" +echo ">> nothing further, here's the shell" +/bin/busybox sh diff --git a/mkinitrd b/mkinitrd @@ -0,0 +1,161 @@ +#!/bin/sh +# busybox based initramfs script + +add_kmod() { + while [ "$1" ]; do + kmod=$1; shift + path=$(modinfo -k $K -F filename $kmod 2>/dev/null) + [ "$path" ] || continue + [ -f $W/$path ] && continue + add_file $path + for firmware in $(modinfo -k $K -F firmware $kmod); do + [ -f /lib/firmware/$firmware.xz ] && add_file /lib/firmware/$firmware.xz + [ -f /lib/firmware/$firmware ] && add_file /lib/firmware/$firmware + done + for depends in $(modinfo -k $K -F depends $kmod | tr ',' ' '); do + [ "$depends" ] || continue + add_kmod $depends + done + done +} + +add_bin() { + while [ "$1" ]; do + bin=$(which $1); shift + [ "$bin" ] || { + echo "FAILED: $bin: missing binary" + continue + } + add_file "$bin" + [ -L "$bin" ] && bin=$(readlink -f $bin) + case $(file -bi $bin) in + application/x-pie-executable*) + for file in $(ldd $bin | awk '{print $3}'); do + add_file $file + done;; + esac + done +} + +add_file() { + f=$1 + t=$2 + m=$3 + [ -f "$1" ] || { + echo "FAILED: $f: missing file" + return + } + if [ -L "$f" ]; then + add_file $(readlink -f $1) + fi + install $([ "$m" ] && echo "-m $m") -D $f $W${2:-$f} 2>/dev/null + echo "$([ "$?" = 0 ] && echo OK || echo FAILED): $f" +} + +K=$(uname -r) +W=/tmp/mkinitrd-xxx +O=initrd +I=/usr/share/mkinitrd/init + +while [ "$1" ]; do + case $1 in + -k) K=$2; shift;; + -i) I=$2; shift;; + -a) A=1;; + -h) H=1;; + *) O=$1;; + esac + shift +done + +if [ "$H" ]; then + cat <<EOF +mkinitrd: busybox based initramfs generator. + +Usage: $0 [-ah] [-k kernel] [-i init] [ OUTPUT ] + + -a Auto detect kernel modules + -i init Use custom init file (default: /usr/share/mkinitrd/init) + -k kernel kernel version + -h Show this help message +EOF +exit 0 +fi + +if [ "$(id -u)" != 0 ]; then + echo "error: this program need to run as root" + exit 1 +fi + +M=/lib/modules/$K + +if [ ! -d "$M" ]; then + echo "error: kernel modules directory '$M' not found" + exit 1 +fi + +if [ ! -f "$M"/modules.dep ]; then + echo "error: modules.dep file not found, please run 'depmod' first" + exit 1 +fi + +if [ ! "$(command -v busybox)" ]; then + echo "error: busybox not found in PATH, please install busybox" + exit 1 +fi + +# create temporary bin path for busybox's applet +# we trying to use busybox utils as possible +mkdir -p /tmp/busybox-bin.$$ +for a in $(busybox --list); do + ln -s $(command -v busybox) /tmp/busybox-bin.$$/$a +done +export PATH=/tmp/busybox-bin.$$:$PATH + +if [ ! -f "$I" ]; then + echo "error: init file '$I' not found" + exit 1 +fi + +rm -rf $W +mkdir -p $W/$M + +for d in bin dev etc lib proc run sys; do + mkdir -p $W/$d +done +ln -s . $W/usr +ln -s bin $W/sbin +ln -s lib $W/lib64 + +if [ "$A" ]; then + for i in /sys/module/*; do + add_kmod ${i##*/} + echo ${i##*/} >> $W/modules + done +else + for d in \ + crypto fs lib drivers/block drivers/md drivers/ata \ + drivers/firewire drivers/input/keyboard drivers/input/mouse \ + drivers/scsi drivers/message drivers/pcmcia drivers/virtio \ + drivers/usb/host drivers/usb/storage drivers/hid; + do + for f in $(find $M/kernel/$d -name *.ko*); do + f=${f##*/}; f=${f%.ko*} + add_kmod $f + done + done +fi +add_file $M/modules.builtin +add_file $M/modules.order +depmod -b $W $K + +add_bin busybox +add_file $I / 755 + +echo '$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS' > $W/etc/mdev.conf + +( cd $W ; find . | cpio -o -H newc --quiet | gzip -9 ) > "$O" +du -sh "$O" +rm -rf $W /tmp/busybox-bin.$$ + +exit 0