| 1 | #!/bin/sh |
| 2 | |
| 3 | # this is the init script version |
| 4 | VERSION=1.0 |
| 5 | NEWROOT=/newroot |
| 6 | SINGLEMODE=no |
| 7 | |
| 8 | # basic environment |
| 9 | export PATH=/usr/bin:/bin:/usr/sbin:/sbin |
| 10 | |
| 11 | # basic mounts |
| 12 | mount -t proc -o noexec,nosuid,nodev proc /proc |
| 13 | mount -t sysfs -o noexec,nosuid,nodev sysfs /sys |
| 14 | |
| 15 | # some helpers |
| 16 | ebegin() { |
| 17 | echo -n " * $*: " |
| 18 | } |
| 19 | eend() { |
| 20 | local msg |
| 21 | if [ "$1" = 0 ] || [ $# -lt 1 ] ; then |
| 22 | echo "ok." |
| 23 | else |
| 24 | shift |
| 25 | echo "failed. $*" |
| 26 | echo "initramfs emergency recovery shell launched" |
| 27 | exec /bin/busybox sh |
| 28 | fi |
| 29 | } |
| 30 | |
| 31 | scan_drivers() { |
| 32 | if [ "$AUTODETECT" != no ] ; then |
| 33 | find /sys -name modalias | xargs sort | while read a ; do |
| 34 | modprobe $a 2>/dev/null \ |
| 35 | || echo $a >> /tmp/hwdrivers.failed |
| 36 | done |
| 37 | fi |
| 38 | } |
| 39 | |
| 40 | find_ovl() { |
| 41 | local mnt="$1" |
| 42 | local ovl |
| 43 | local lines |
| 44 | |
| 45 | # look for apkovl's on mounted media |
| 46 | ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1 |
| 47 | lines=$(echo "$ovl" | wc -l) |
| 48 | |
| 49 | if [ $lines -gt 1 ] ; then |
| 50 | echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2 |
| 51 | return 1 |
| 52 | fi |
| 53 | echo "$ovl" |
| 54 | } |
| 55 | |
| 56 | # gotta start from somewhere :) |
| 57 | echo "Alpine Init $VERSION" |
| 58 | |
| 59 | # read the kernel options |
| 60 | for i in `cat /proc/cmdline` ; do |
| 61 | case $i in |
| 62 | s|single|1) |
| 63 | SINGLEMODE=yes ;; |
| 64 | modules=*) |
| 65 | MODULES="`echo ${i#modules=} | tr ',' ' '`";; |
| 66 | noautodetect) |
| 67 | AUTODETECT=no;; |
| 68 | *=*) eval KOPT_$i ;; |
| 69 | *) eval KOPT_$i=yes ;; |
| 70 | esac |
| 71 | done |
| 72 | |
| 73 | ALPINE_DEV=${KOPT_alpine_dev%%:*} |
| 74 | ALPINE_MNT=/media/$ALPINE_DEV |
| 75 | |
| 76 | # hide kernel messages |
| 77 | dmesg -n 1 |
| 78 | |
| 79 | # setup /dev |
| 80 | ebegin "Starting mdev" |
| 81 | mount -t tmpfs -o exec,nosuid,mode=0755 mdev /dev |
| 82 | mknod -m 666 /dev/null c 1 3 |
| 83 | ln -s sr0 /dev/cdrom |
| 84 | echo "/sbin/mdev" > /proc/sys/kernel/hotplug |
| 85 | mdev -s |
| 86 | RC=$? |
| 87 | [ -d /dev/pts ] || mkdir -m 755 /dev/pts |
| 88 | [ -c /dev/ptmx ] || mknod -m 666 /dev/ptmx c 5 2 |
| 89 | mount -t devpts -o gid=5,mode=0620,noexec,nosuid devpts /dev/pts |
| 90 | [ -d /dev/shm ] || mkdir /dev/shm |
| 91 | mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm |
| 92 | eend $RC |
| 93 | |
| 94 | # load available drivers to get access to modloop media |
| 95 | ebegin "Loading boot drivers" |
| 96 | [ "$MODULES" ] && modprobe $MODULES 2> /dev/null |
| 97 | if [ -f /etc/modules ] ; then |
| 98 | sed 's/\#.*//g' < /etc/modules | |
| 99 | while read module args; do |
| 100 | modprobe -q $module $args |
| 101 | done |
| 102 | fi |
| 103 | scan_drivers |
| 104 | scan_drivers |
| 105 | eend 0 |
| 106 | |
| 107 | # locate boot media and mount it |
| 108 | ebegin "Mounting boot media" |
| 109 | mount $ALPINE_MNT >/dev/null 2>&1 |
| 110 | eend $? |
| 111 | ebegin "Mounting loopback device for kernel modules" |
| 112 | modprobe loop |
| 113 | mount -o loop,ro -t cramfs /media/$ALPINE_DEV/$(dirname ${KOPT_BOOT_IMAGE:-""})/modloop.cmg /.modloop |
| 114 | rc=$? |
| 115 | if [ "$rc" = 0 ]; then |
| 116 | rm -rf /lib/modules |
| 117 | ln -sf /.modloop/modules /lib |
| 118 | fi |
| 119 | if [ -d $ALPINE_MNT/firmware ]; then |
| 120 | mkdir -p /lib/firmware |
| 121 | cp -a $ALPINE_MNT/firmware/* /lib/firmware/ |
| 122 | fi |
| 123 | eend $? |
| 124 | |
| 125 | # early console? |
| 126 | if [ "$SINGLEMODE" = "yes" ]; then |
| 127 | echo "Entering single mode. Type 'exit' to continue booting." |
| 128 | sh |
| 129 | fi |
| 130 | |
| 131 | # more drivers |
| 132 | ebegin "Loading hardware drivers" |
| 133 | scan_drivers |
| 134 | eend 0 |
| 135 | |
| 136 | mount -t tmpfs tmpfs $NEWROOT |
| 137 | |
| 138 | # look for apkovl |
| 139 | for i in usb floppy cdrom; do |
| 140 | mount /media/$i 2>/dev/null || continue |
| 141 | ovl=$(find_ovl /media/$i) |
| 142 | [ -f "$ovl" ] && break |
| 143 | umount /media/$i 2>/dev/null |
| 144 | done |
| 145 | |
| 146 | if [ -f "$ovl" ]; then |
| 147 | ebegin "Loading user settings from $ovl" |
| 148 | tar -C $NEWROOT -zxf "$ovl" |
| 149 | eend $? |
| 150 | umount /media/$i 2>/dev/null |
| 151 | pkgs=$(sed 's/\#.*//' $NEWROOT/etc/lbu/packages.list 2>/dev/null) |
| 152 | fi |
| 153 | |
| 154 | # install new root |
| 155 | ebegin "Installing packages to root filesystem" |
| 156 | apk add --root /newroot --repository /media/$ALPINE_DEV/apks \ |
| 157 | --initdb --quiet --progress $pkgs |
| 158 | eend $? |
| 159 | |
| 160 | # copy alpine release info |
| 161 | cp /media/$ALPINE_DEV/.alpine-release $NEWROOT/ |
| 162 | ln -sf /.alpine-release $NEWROOT/etc/alpine-release |
| 163 | |
| 164 | # if there is no repositories file, then use the default |
| 165 | if ! [ -f $NEWROOT/etc/apk/repositories ]; then |
| 166 | echo /media/$ALPINE_DEV/apks > $NEWROOT/etc/apk/repositories |
| 167 | fi |
| 168 | |
| 169 | # switch over to new root |
| 170 | cat /proc/mounts | while read DEV DIR TYPE OPTS ; do |
| 171 | if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then |
| 172 | mkdir -p $NEWROOT/$DIR |
| 173 | mount -o move $DIR $NEWROOT/$DIR |
| 174 | fi |
| 175 | done |
| 176 | sync |
| 177 | |
| 178 | ln -sf /.modloop/modules $NEWROOT/lib/modules |
| 179 | |
| 180 | echo -e "\nStarting $(cut -f1 $NEWROOT/.alpine-release)" |
| 181 | if [ -x $NEWROOT/sbin/init ]; then |
| 182 | exec /bin/busybox switch_root $NEWROOT /sbin/init $KOPT_init_args |
| 183 | fi |
| 184 | |
| 185 | echo "initramfs emergency recovery shell launched" |
| 186 | exec /bin/busybox sh |
| 187 | reboot |