mkinitrd

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

init (3613B)


      1 #!/bin/busybox sh
      2 
      3 /bin/busybox --install -s /bin
      4 
      5 NEWROOT=/newroot
      6 init=/sbin/init
      7 root=
      8 rootdelay=
      9 rootfstype=auto
     10 ro="ro"
     11 rootflags=
     12 device=
     13 
     14 mkdir -p $NEWROOT
     15 mount -t proc     proc  /proc
     16 mount -t sysfs    sysfs /sys
     17 mount -t tmpfs    run   /run
     18 mount -t devtmpfs dev   /dev
     19 
     20 read -r cmdline < /proc/cmdline
     21 
     22 for param in $cmdline; do
     23 	case $param in
     24 		init=*      ) init=${param#init=}             ;;
     25 		root=*      ) root=${param#root=}             ;;
     26 		rootdelay=* ) rootdelay=${param#rootdelay=}   ;;
     27 		rootfstype=*) rootfstype=${param#rootfstype=} ;;
     28 		rootflags=* ) rootflags=${param#rootflags=}   ;;
     29 		ro          ) ro="ro"                         ;;
     30 		rw          ) ro="rw"                         ;;
     31 		shell       ) shell=1                         ;;
     32 		liveos      ) live=1                          ;;
     33 	esac
     34 done
     35 
     36 # mdev
     37 [ -f /proc/sys/kernel/hotplug ] && \
     38 	which mdev > /proc/sys/kernel/hotplug
     39 mdev -s
     40 
     41 # load modules using modalias
     42 find /sys -name 'modalias' -type f -exec cat '{}' + | sort -u | xargs modprobe -b -a 2>/dev/null
     43 
     44 # load modules
     45 for m in virtio virtio_ring virtio_pci virtio_blk virtio_scsi nvme \
     46 	ata_piix sd_mod sr_mod cdrom loop squashfs isofs overlay mbcache \
     47 	jbd jbd2 ext2 ext3 ext4 xfs btrfs f2fs reiserfs jfs fat vfat exfat ntfs3; do
     48 	modprobe "$m" 2>/dev/null
     49 done
     50 
     51 [ "$shell" ] && sh
     52 
     53 [ "$rootflags" ] && rootflags="$rootflags,"
     54 rootflags="$rootflags$ro"
     55 
     56 if [ "$live" ]; then
     57 	INITRAMFS=/run/initramfs
     58 	MEDIA=$INITRAMFS/media
     59 	LOWER=$INITRAMFS/lower
     60 	UPPER=$INITRAMFS/upper
     61 	WORK=$INITRAMFS/work
     62 	SFSIMAGE=$MEDIA/liveos/rootfs.sfs
     63 
     64 	mkdir -p $LOWER $MEDIA $UPPER $WORK
     65 
     66 	# figure out media
     67 	if [ -f /proc/sys/dev/cdrom/info ]; then
     68 		CDROM=$(grep name /proc/sys/dev/cdrom/info | awk -F : '{print $2}' | awk '{print $1}')
     69 	fi
     70 
     71 	while [ "$wait" != 10 ]; do
     72 		BLOCK=$(grep -E '[vsh]d' /proc/partitions | awk '{print $4}')
     73 		for i in $CDROM $BLOCK; do
     74 			mount -v -r /dev/"$i" $MEDIA >/dev/null 2>&1 || continue
     75 			[ -d $MEDIA/liveos ] || { umount $MEDIA; continue; }
     76 			MEDIAFOUND=1
     77 			break 2
     78 		done
     79 		wait=$(( wait + 1 ))
     80 		sleep 1
     81 	done
     82 
     83 	if [ ! "$MEDIAFOUND" ]; then
     84 		echo "Media not found even after 10 seconds"
     85 		sh
     86 		echo "Cannot go further"
     87 		sleep 99999
     88 		exit 1
     89 	fi
     90 
     91 	# mount stuff
     92 	loopdevice=$(losetup -f)
     93 	losetup -f $SFSIMAGE
     94 	mount -r "$loopdevice" $LOWER
     95 	mount -t overlay overlay -o lowerdir=$LOWER,upperdir=$UPPER,workdir=$WORK $NEWROOT
     96 	if [ -f $MEDIA/liveos/live.gz ]; then
     97 		tar -xzaf $MEDIA/liveos/live.gz -C $NEWROOT
     98 	fi
     99 else
    100 	case "$root" in
    101 		/dev/*    ) device=$root ;;
    102 		UUID=*    ) eval "$root"; device="$(blkid | grep "$UUID"  | cut -d : -f1 | head -n1)" ;;
    103 		LABEL=*   ) eval "$root"; device="$(blkid | grep "$LABEL" | cut -d : -f1 | head -n1)" ;;
    104 		""        ) echo "!! no root device specified" ; exec sh;;
    105 	esac
    106 
    107 	if [ "$rootdelay" ]; then
    108 		while [ ! -b "$device" ] && [ "$i" -lt "$rootdelay" ]; do
    109 			echo ">> waiting for $device..."
    110 			sleep 1
    111 			i=$((i+1))
    112 		done
    113 	fi
    114 
    115 	while [ ! -b "$device" ] ; do
    116 		echo "!! device '$device' not found"
    117 		exec sh
    118 	done
    119 
    120 	if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" $NEWROOT; then
    121 		echo "!! failed to mount device '$device'"
    122 		exec sh
    123 	fi
    124 
    125 fi
    126 
    127 [ "$shell" ] && sh
    128 
    129 pkill mdev
    130 
    131 mount --move /sys $NEWROOT/sys
    132 mount --move /proc $NEWROOT/proc
    133 mount --move /dev $NEWROOT/dev
    134 mount --move /run $NEWROOT/run
    135 
    136 # execute live script if exist
    137 if [ -f $NEWROOT/"$MEDIA"/liveos/live.sh ]; then
    138 	chroot $NEWROOT sh "$MEDIA"/liveos/live.sh
    139 fi
    140 
    141 # switch to newroot
    142 exec switch_root $NEWROOT "$init" $@
    143 
    144 echo ">> this is the end of initramfs"
    145 echo ">> nothing further, here's the shell"
    146 busybox sh