aboutsummaryrefslogtreecommitdiffstats
path: root/initramfs-init
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2009-04-29 13:18:13 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2009-04-29 13:18:13 +0000
commit1378536fcf22544533e6df4cbca3c558ffcc01ab (patch)
tree5f9ca9ad44b6432214f453482edc75136efc6a77 /initramfs-init
downloadmkinitfs-1378536fcf22544533e6df4cbca3c558ffcc01ab.tar.bz2
mkinitfs-1378536fcf22544533e6df4cbca3c558ffcc01ab.tar.xz
initial commit
Diffstat (limited to 'initramfs-init')
-rwxr-xr-xinitramfs-init308
1 files changed, 308 insertions, 0 deletions
diff --git a/initramfs-init b/initramfs-init
new file mode 100755
index 0000000..d9a9d68
--- /dev/null
+++ b/initramfs-init
@@ -0,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