mkinitrd

A simple busybox based initramfs generator
git clone https://codeberg.org/emmett1/mkinitrd
Log | Files | Refs

mkinitrd (3441B)


      1 #!/bin/sh
      2 # busybox based initramfs script
      3 
      4 add_kmod() {
      5 	while [ "$1" ]; do
      6 		kmod=$1; shift
      7 		path=$(modinfo -k $K -F filename $kmod 2>/dev/null)
      8 		[ "$path" ] || continue
      9 		[ -f $W/$path ] && continue
     10 		add_file $path
     11 		for firmware in $(modinfo -k $K -F firmware $kmod); do
     12 			[ -f /lib/firmware/$firmware.xz ] && add_file /lib/firmware/$firmware.xz
     13 			[ -f /lib/firmware/$firmware.gz ] && add_file /lib/firmware/$firmware.gz
     14 			[ -f /lib/firmware/$firmware ]    && add_file /lib/firmware/$firmware
     15 		done
     16 		for depends in $(modinfo -k $K -F depends $kmod | tr ',' ' '); do
     17 			[ "$depends" ] || continue
     18 			add_kmod $depends
     19 		done
     20 	done
     21 }
     22 
     23 add_bin() {
     24 	while [ "$1" ]; do
     25 		bin=$(which $1); shift
     26 		[ "$bin" ] || {
     27 			echo "FAILED: $bin: missing binary"
     28 			continue
     29 		}
     30 		add_file "$bin"
     31 		[ -L "$bin" ] && bin=$(readlink -f $bin)
     32 		case $(file -bi $bin) in
     33 			application/x-pie-executable*)
     34 				for file in $(ldd $bin | awk '{print $3}'); do
     35 					add_file $file
     36 				done;;
     37 		esac
     38 	done
     39 }
     40 
     41 add_file() {
     42 	f=$1
     43 	t=$2
     44 	m=$3
     45 	[ -f "$1" ] || {
     46 		echo "FAILED: $f: missing file"
     47 		return
     48 	}
     49 	if [ -L "$f" ]; then
     50 		add_file $(readlink -f $1)
     51 	fi
     52 	install $([ "$m" ] && echo "-m $m") -D $f $W${2:-$f} 2>/dev/null
     53 	echo "$([ "$?" = 0 ] && echo OK || echo FAILED): $f"
     54 }
     55 
     56 K=$(uname -r)
     57 W=/tmp/mkinitrd-xxx
     58 O=initrd
     59 I=/usr/share/mkinitrd/init
     60 
     61 while [ "$1" ]; do
     62 	case $1 in
     63 		-k) K=$2; shift;;
     64 		-i) I=$2; shift;;
     65 		-a) A=1;;
     66 		-h) H=1;;
     67 		 *) O=$1;;
     68 	esac
     69 	shift
     70 done
     71 
     72 if [ "$H" ]; then
     73 	cat <<EOF
     74 mkinitrd: busybox based initramfs generator.
     75 
     76 Usage: $0 [-ah] [-k kernel] [-i init] [ OUTPUT ]
     77 
     78 	-a          Auto detect kernel modules
     79 	-i init     Use custom init file (default: /usr/share/mkinitrd/init)
     80 	-k kernel   kernel version
     81 	-h          Show this help message
     82 EOF
     83 exit 0
     84 fi
     85 
     86 if [ "$(id -u)" != 0 ]; then
     87 	echo "error: this program need to run as root"
     88 	exit 1
     89 fi
     90 
     91 M=/lib/modules/$K
     92 
     93 if [ ! -d "$M" ]; then
     94 	echo "error: kernel modules directory '$M' not found"
     95 	exit 1
     96 fi
     97 
     98 if [ ! -f "$M"/modules.dep ]; then
     99 	echo "error: modules.dep file not found, please run 'depmod' first"
    100 	exit 1
    101 fi
    102 
    103 if [ ! "$(command -v busybox)" ]; then
    104 	echo "error: busybox not found in PATH, please install busybox"
    105 	exit 1
    106 fi
    107 
    108 # create temporary bin path for busybox's applet
    109 # we trying to use busybox utils as possible
    110 mkdir -p /tmp/busybox-bin.$$
    111 for a in $(busybox --list); do
    112 	ln -s $(command -v busybox) /tmp/busybox-bin.$$/$a
    113 done
    114 export PATH=/tmp/busybox-bin.$$:$PATH
    115 
    116 if [ ! -f "$I" ]; then
    117 	echo "error: init file '$I' not found"
    118 	exit 1
    119 fi
    120 
    121 rm -rf $W
    122 mkdir -p $W/$M
    123 
    124 for d in bin dev etc lib proc run sys; do
    125 	mkdir -p $W/$d
    126 done
    127 ln -s . $W/usr
    128 ln -s bin $W/sbin
    129 ln -s lib $W/lib64
    130 
    131 if [ "$A" ]; then
    132 	for i in /sys/module/*; do
    133 		add_kmod ${i##*/}
    134 		echo ${i##*/} >> $W/modules
    135 	done
    136 else
    137 	for d in \
    138 		crypto fs lib drivers/block drivers/md drivers/ata \
    139 		drivers/firewire drivers/input/keyboard drivers/input/mouse \
    140 		drivers/scsi drivers/message drivers/pcmcia drivers/virtio \
    141 		drivers/usb/host drivers/usb/storage drivers/hid drivers/cdrom;
    142 	do
    143 		for f in $(find $M/kernel/$d -name *.ko*); do
    144 			f=${f##*/}; f=${f%.ko*}
    145 			add_kmod $f
    146 		done
    147 	done
    148 fi
    149 add_file $M/modules.builtin
    150 add_file $M/modules.order
    151 depmod -b $W $K
    152 
    153 add_bin busybox
    154 add_file $I / 755
    155 
    156 echo '$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS' > $W/etc/mdev.conf
    157 
    158 ( cd $W ; find . | cpio -o -H newc --quiet | gzip -9 ) > "$O"
    159 du -sh "$O"
    160 rm -rf $W /tmp/busybox-bin.$$
    161 
    162 exit 0