home: hub: mkinitfs

Download patch

ref: 1378536fcf22544533e6df4cbca3c558ffcc01ab
author: Natanael Copa <ncopa@alpinelinux.org>
date: Wed Apr 29 08:18:13 CDT 2009

initial commit

--- /dev/null
+++ b/Makefile
@@ -1,0 +1,36 @@
+
+VERSION		:= 1.1
+
+
+SBIN_FILES	:= mkinitfs bootchartd
+SHARE_FILES	:= initramfs-init
+CONF_FILES	:= mkinitfs.conf \
+		modules.d/ata \
+		modules.d/ide \
+		modules.d/base \
+		modules.d/raid \
+		modules.d/scsi \
+		modules.d/cdrom \
+		modules.d/usb \
+		modules.d/cramfs \
+		files.d/bootchart \
+		files.d/base
+
+DISTFILES	:= $(SBIN_FILES) $(CONF_FILES) $(SHARE_FILES) Makefile
+
+INSTALL		:= install
+
+help:
+	@echo "usage: make install [DESTDIR=]"
+
+install:
+	for i in $(SBIN_FILES); do \
+		$(INSTALL) -Dm755 $$i $(DESTDIR)/sbin/$$i || exit 1;\
+	done
+	for i in $(CONF_FILES); do \
+		$(INSTALL) -Dm644 $$i $(DESTDIR)/etc/mkinitfs/$$i || exit 1;\
+	done
+	for i in $(SHARE_FILES); do \
+		$(INSTALL) -D $$i $(DESTDIR)/usr/share/mkinitfs/$$i || exit 1;\
+	done
+
--- /dev/null
+++ b/files.d/base
@@ -1,0 +1,11 @@
+/bin/busybox
+/bin/sh
+/lib/libcrypt-[0-9]*
+/lib/libcrypt.so.*
+/lib/libm-[0-9]*
+/lib/libm.so.*
+/lib/libuClibc-[0-9]*
+/lib/libc.so.*
+/lib/ld-uClibc-[0-9]*
+/lib/ld-uClibc.so*
+/lib/mdev
--- /dev/null
+++ b/files.d/bootchart
@@ -1,0 +1,8 @@
+/usr/bin/ac
+/usr/bin/last
+/usr/bin/lastcomm
+/usr/sbin/dump-utmp
+/usr/sbin/dump-acct
+/usr/sbin/accton
+/usr/sbin/sa
+
--- /dev/null
+++ b/initramfs-init
@@ -1,0 +1,308 @@
+#!/bin/busybox sh
+
+# this is the init script version
+VERSION=1.1
+NEWROOT=/newroot
+SINGLEMODE=no
+
+/bin/busybox --install -s
+
+# basic environment
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# needed devs
+[ -c /dev/null ] || mknod -m 666 /dev/null c 1 3
+
+# basic mounts
+mount -t proc -o noexec,nosuid,nodev proc /proc
+mount -t sysfs -o noexec,nosuid,nodev sysfs /sys
+
+# some helpers
+ebegin() {
+	echo -n " * $*: "
+}
+eend() {
+	local msg
+	if [ "$1" = 0 ] || [ $# -lt 1 ] ; then
+		echo "ok."
+	else
+		shift
+		echo "failed. $*"
+		echo "initramfs emergency recovery shell launched. Type 'exit' to continue boot"
+		/bin/busybox sh
+	fi
+}
+
+scan_drivers() {
+	if [ "$AUTODETECT" != no ] ; then
+		find /sys -name modalias | xargs sort -u | xargs modprobe -a 2> /dev/null
+	fi
+}
+
+find_ovl() {
+	local mnt="$1"
+	local ovl
+	local lines
+
+	# look for apkovl's on mounted media
+	ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1
+	lines=$(echo "$ovl" | wc -l)
+
+	if [ $lines -gt 1 ] ; then
+		echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2
+		return 1
+	fi
+	echo "$ovl"
+}
+
+retry_mount() {
+	# usb might need some time to settle so we retry a few times
+	for i in $(seq 0 19); do
+		mount $@ 2>&1 && return 0
+		sleep 1
+	done
+	return 1
+}
+
+unpack_apkovl() {
+	local ovl="$1"
+	local dest="$2"
+	local suffix=${ovl##*.}
+	local i
+	if [ "$suffix" = "gz" ]; then
+		tar -C "$dest" -zxf "$ovl"
+		return $?
+	fi
+
+	for i in $ALPINE_MNT/*/*/openssl-[0-9]*.apk $ALPINE_MNT/*/openssl-[0-9]*.apk; do
+		[ -f "$i" ] && tar --numeric-owner -C / -zxf $i && break
+	done
+
+	if ! openssl list-cipher-commands | grep "^$suffix$" > /dev/null; then
+		errstr="Cipher $suffix is not supported"
+		return 1
+	fi
+	local count=0
+	# beep
+	echo -e "\007"
+	while [ $count -lt 3 ]; do
+		openssl enc -d -$suffix -in "$ovl" | tar --numeric-owner \
+			-C "$dest" -zx 2>/dev/null && return 0
+		count=$(( $count + 1 ))
+	done
+	return 1
+}
+
+# gotta start from somewhere :)
+echo "Alpine Init $VERSION"
+
+# read the kernel options
+for i in `cat /proc/cmdline` ; do
+	case $i in
+		s|single|1)
+			SINGLEMODE=yes ;;
+		modules=*)
+			MODULES="`echo ${i#modules=} | tr ',' ' '`";;
+		noautodetect)
+			AUTODETECT=no;;
+		*=*)    eval KOPT_$i ;;
+		*)      eval KOPT_$i=yes ;;
+	esac
+done
+
+# start bootcharting if wanted
+if [ -n "$KOPT_chart" ]; then
+	ebegin "Starting bootchart logging"
+	/sbin/bootchartd start-initfs "$NEWROOT"
+	eend 0
+fi
+
+ALPINE_DEV=${KOPT_alpine_dev%%:*}
+ALPINE_DEV_FS=${KOPT_alpine_dev##*:}
+if [ "$ALPINE_DEV_FS" = "$ALPINE_DEV" ]; then
+	unset ALPINE_DEV_FS
+fi
+ALPINE_MNT=/media/$ALPINE_DEV
+
+# hide kernel messages
+dmesg -n 1
+
+# setup /dev
+ebegin "Starting mdev"
+mount -t tmpfs -o exec,nosuid,mode=0755 mdev /dev
+ln -s sr0 /dev/cdrom
+echo "/sbin/mdev" > /proc/sys/kernel/hotplug
+mdev -s
+RC=$?
+[ -d /dev/pts ] || mkdir -m 755 /dev/pts
+[ -c /dev/ptmx ] || mknod -m 666 /dev/ptmx c 5 2
+mount -t devpts -o gid=5,mode=0620,noexec,nosuid devpts /dev/pts
+[ -d /dev/shm ] || mkdir /dev/shm
+mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm
+eend $RC
+
+# load available drivers to get access to modloop media
+ebegin "Loading boot drivers"
+[ "$MODULES" ] && modprobe -a $MODULES 2> /dev/null
+if [ -f /etc/modules ] ; then
+	sed 's/\#.*//g' < /etc/modules |
+	while read module args; do
+		modprobe -q $module $args
+	done
+fi
+scan_drivers
+scan_drivers
+eend 0
+
+# check if root=... was set
+if [ -n "$KOPT_root" ]; then
+	if [ "$SINGLEMODE" = "yes" ]; then
+		echo "Entering single mode. Type 'exit' to continue booting."
+		sh
+	fi
+	case "$KOPT_root" in
+		/dev/md*) 
+			mknod $KOPT_root b 9 ${KOPT_root#/dev/md}
+			raidautorun "$KOPT_root"
+			;;
+	esac
+	ebegin "Mounting root"
+	retry_mount $KOPT_root $NEWROOT 2>/dev/null
+	eend $?
+	cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
+		if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
+			mkdir -p $NEWROOT/$DIR
+			mount -o move $DIR $NEWROOT/$DIR
+		fi
+	done
+	sync
+	exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
+	echo "initramfs emergency recovery shell launched"
+	exec /bin/busybox sh
+fi
+
+# locate boot media and mount it
+ebegin "Mounting boot media"
+mkdir -p $ALPINE_MNT
+if [ -n "$ALPINE_DEV_FS" ]; then
+	mount_opts="-t $ALPINE_DEV_FS"
+fi
+
+retry_mount $mount_opts /dev/$ALPINE_DEV $ALPINE_MNT >/dev/null 2>&1
+eend $?
+
+ebegin "Mounting loopback device for kernel modules"
+modprobe loop
+if [ -n "$KOPT_modloop" ]; then
+	modloop=$KOPT_modloop
+else
+	modloop=$KOPT_BOOT_IMAGE.cmg
+fi
+mount -o loop,ro -t cramfs $ALPINE_MNT/$modloop /.modloop
+rc=$?
+if [ "$rc" = 0 ]; then
+	rm -rf /lib/modules
+	ln -sf /.modloop/modules /lib
+fi
+eend $?
+
+if [ -d $ALPINE_MNT/firmware ]; then
+	ebegin "Copying firmware from $ALPINE_MNT/firmware"
+	mkdir -p /lib
+	cp -R -a $ALPINE_MNT/firmware /lib/
+	eend $?
+fi
+
+mkdir -p /etc/apk
+for i in $ALPINE_MNT/*/APK_INDEX.gz $ALPINE_MNT/*/*/APK_INDEX.gz; do
+	[ -r "$i" ] && echo ${i%/APK_INDEX.gz} >> /etc/apk/repositories
+done
+
+# early console?
+if [ "$SINGLEMODE" = "yes" ]; then
+	echo "Entering single mode. Type 'exit' to continue booting."
+	sh
+fi
+
+# more drivers
+ebegin "Loading hardware drivers"
+scan_drivers
+eend 0
+
+mount -t tmpfs tmpfs $NEWROOT
+
+# look for apkovl
+if dmesg | grep '^usb-storage: waiting' >/dev/null; then
+	ebegin "Waiting for USB device to settle"
+	while ! dmesg | grep 'usb-storage: device scan complete' >/dev/null; do
+		sleep 1
+	done
+	eend 0
+fi
+for i in usb floppy cdrom; do
+	mount /media/$i 2>/dev/null || continue
+	ovl=$(find_ovl /media/$i)
+	[ -f "$ovl" ] && break
+	umount /media/$i 2>/dev/null
+done
+if ! [ -f "$ovl" ]; then
+	ovl=$(find_ovl $ALPINE_MNT)
+fi
+
+if [ -f "$ovl" ]; then
+	ebegin "Loading user settings from $ovl"
+	unpack_apkovl "$ovl" $NEWROOT
+	eend $? $errstr
+	umount /media/$i 2>/dev/null &
+	pkgs=$(sed 's/\#.*//' $NEWROOT/etc/lbu/packages.list 2>/dev/null)
+fi
+
+# hack so we get openrc
+pkgs="$pkgs openrc"
+
+# install new root
+ebegin "Installing packages to root filesystem"
+if [ -n "$KOPT_chart" ]; then
+	pkgs="$pkgs acct"
+fi
+apkflags="--initdb --quiet --progress --force"
+if [ -z "$KOPT_keep_apk_new" ]; then
+	apkflags="$apkflags --clean-protected"
+fi
+apk add --root /newroot $apkflags $pkgs >/dev/null
+eend $?
+
+# copy alpine release info
+cp $ALPINE_MNT/.alpine-release $NEWROOT/
+ln -sf /.alpine-release $NEWROOT/etc/alpine-release
+
+# if there is no repositories file, then use the default
+if ! [ -f $NEWROOT/etc/apk/repositories ]; then
+	cp /etc/apk/repositories $NEWROOT/etc/apk/repositories
+fi
+
+# setup bootchart for switch_root
+chart_init=""
+if [ -n "$KOPT_chart" ]; then
+	/sbin/bootchartd stop-initfs "$NEWROOT"
+	chart_init="/sbin/bootchartd start-rootfs"
+fi
+
+# switch over to new root
+cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
+	if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
+		mkdir -p $NEWROOT/$DIR
+		mount -o move $DIR $NEWROOT/$DIR
+	fi
+done
+ln -sf /.modloop/modules $NEWROOT/lib/modules
+sync
+
+echo ""
+if [ -x $NEWROOT/sbin/init ]; then
+	exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
+fi
+
+echo "initramfs emergency recovery shell launched"
+exec /bin/busybox sh
+reboot
--- /dev/null
+++ b/mkinitfs
@@ -1,0 +1,179 @@
+#!/bin/sh
+
+_cp() {
+	local i
+	for i in "$@"; do
+		local dest="$tmpdir"/${i%/*}
+		mkdir -p "$dest"
+		cp -flLpR "$i" "$dest" 2>/dev/null || cp -pR "$i" "$dest"
+	done
+}
+
+feature_files() {
+	local dir="$1"
+	local glob file 
+	for f in $features; do
+		if [ ! -f "$dir/$f" ]; then
+			continue
+		fi
+		for glob in $(cat "$dir/$f"); do
+			for file in $glob; do
+				echo $glob
+			done
+		done
+	done
+}
+
+initfs_base() {
+	local i= dirs= glob= file=
+	echo "==> initramfs: copying base files" >&2
+	for i in dev proc sys sbin bin .modloop lib/modules media/cdrom \
+	    media/floppy media/usb newroot; do
+		dirs="$dirs $tmpdir/$i"
+	done
+	mkdir -p $dirs
+
+	for file in $(feature_files "$filelists_dir"); do
+		_cp $file
+	done
+
+	# copy init
+	cd $startdir
+	install -m755 "$init" "$tmpdir"/init
+}
+
+find_kmod_deps() {
+	awk '
+function recursedeps(k,		j) {
+	if (k in visited)
+		return;
+	visited[k] = 1;
+	split(deps[k], dep, " ");
+	for (j in dep)
+		recursedeps(dep[j]);
+	print(k);
+}
+
+BEGIN {
+	if (modulesdep == "")
+		modulesdep="modules.dep";
+	FS = ": ";
+	while ( (getline < modulesdep) > 0) {
+		deps[$1] = $2;
+	}
+}
+
+{
+	mod["/"$0] = 1;
+}
+
+END {
+	for (i in mod)
+		recursedeps(i);
+}' -v modulesdep="$basedir/lib/modules/$kernel/modules.dep"
+}
+
+initfs_kmods() {
+	local glob= file= files= dirs=
+        rm -rf "$tmpdir"/lib/modules
+	cd "$kerneldir" || return 1
+	echo "==> initramfs: copying kernel $kernel modules" >&2
+	files=$(
+	for file in $(feature_files $modulelists_dir); do
+		if ! [ -e ${file} ]; then
+			echo "$file: No such file or directory" >&2
+			continue
+		fi
+		echo $file
+	done | find_kmod_deps)
+	for file in $files; do
+		_cp "$basedir"/lib/modules/$kernel/$file
+	done
+}
+
+initfs_cpio() {
+	echo "==> initramfs: creating $outfile" >&2
+	(cd "$tmpdir" && find . | cpio -o -H newc | gzip) > $outfile
+}
+
+usage() {
+	cat <<EOF
+usage: mkinitfs [-hkL] [-b basedir] [-c configfile] [-i initfile ] 
+                [-o outfile] [-t tempdir] [kernelversion]"
+options:
+	-b  prefix files and kernel modules with basedir
+	-c  use configfile instead of $config
+	-h  print this help
+	-i  use initfile as init instead of $init
+	-k  keep tempdir
+	-L  list available features
+	-o  set another outfile
+	-t  use tempdir when creating initramfs image
+
+EOF
+	exit 1
+}
+
+# main
+
+startdir=$PWD
+config=/etc/mkinitfs/mkinitfs.conf
+init=/usr/share/mkinitfs/initramfs-init
+
+while getopts "b:c:hi:kLo:t:" opt; do
+	case "$opt" in
+		b) basedir="$OPTARG";;
+		c) config="$OPTARG";;
+		h) usage;;
+		i) init=$OPTARG;;
+		k) keeptmp=1;;
+		L) list_features=1;;
+		o) outfile="$OPTARG";;
+		t) tmpdir="$OPTARG";;
+		*) usage;;
+	esac
+done
+shift $(( $OPTIND - 1 ))
+
+. "$config"
+filelists_dir=${filelists_dir:-"/etc/mkinitfs/files.d"}
+modulelists_dir=${modules_dir:-"/etc/mkinitfs/modules.d"}
+
+if [ -n "$list_features" ]; then
+	for i in $filelists_dir $modulelists_dir; do
+		( [ -d "$i" ] && cd $i && ls )
+	done | sort | uniq
+	exit 0
+fi
+
+[ -n "$1" ] && kernel="$1"
+[ -z "$kernel" ] && kernel=$(uname -r)
+kerneldir="$basedir/lib/modules/$kernel"
+if [ -z "$outfile" ]; then
+	outfile="$basedir"/boot/${kernel##*-}.gz
+fi
+
+if [ ! -d "$kerneldir" ]; then
+	echo "$kerneldir does not exist or is not a directory"
+	exit 1
+fi
+
+if [ -z "$tmpdir" ]; then
+	tmpdir=$(mktemp -d /tmp/mkinitfs.XXXXXX)
+else
+	mkdir -p "$tmpdir"
+fi
+
+if [ -z "$keeptmp" ]; then
+	[ -d "$tmpdir" ] && rm -rf "$tmpdir"/*
+fi
+
+initfs_base
+initfs_kmods
+initfs_cpio
+
+# cleanup
+if [ -z "$keeptmp" ]; then
+	[ -d "$tmpdir" ] && rm -rf "$tmpdir"
+fi
+
--- /dev/null
+++ b/modules.d/ata
@@ -1,0 +1,1 @@
+kernel/drivers/ata/*.ko
--- /dev/null
+++ b/modules.d/base
@@ -1,0 +1,1 @@
+kernel/drivers/hid/*
--- /dev/null
+++ b/modules.d/cdrom
@@ -1,0 +1,2 @@
+kernel/drivers/cdrom
+kernel/fs/isofs
--- /dev/null
+++ b/modules.d/cramfs
@@ -1,0 +1,1 @@
+kernel/fs/cramfs
--- /dev/null
+++ b/modules.d/ide
@@ -1,0 +1,1 @@
+kernel/drivers/ide/*.ko
--- /dev/null
+++ b/modules.d/raid
@@ -1,0 +1,1 @@
+kernel/drivers/md/raid*
--- /dev/null
+++ b/modules.d/scsi
@@ -1,0 +1,2 @@
+kernel/drivers/scsi/*
+kernel/drivers/message/fusion
--- /dev/null
+++ b/modules.d/usb
@@ -1,0 +1,3 @@
+kernel/drivers/usb/host
+kernel/drivers/usb/storage
+kernel/fs/fat