commit 81966b4393623e7f701213b369df0d177696d236
Author: emmett1 <emmett1.2miligrams@protonmail.com>
Date: Sun, 7 Sep 2025 11:55:44 +0800
updated
Diffstat:
A | Makefile | | | 24 | ++++++++++++++++++++++++ |
A | init | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | mkinitrd | | | 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