update-kernel.in 4.41 KB
Newer Older
1 2 3 4 5 6 7 8
#!/bin/sh -e

# update-kernel
#
# Kernel and firmware update script for Alpine installations set up
# with setup-bootable
#
# Copyright (c) 2014 Timo Teräs
9
# Copyright (c) 2014-2015 Kaarle Ritvanen
10 11 12 13 14


SCRIPT=update-kernel
VIRTUAL=.tmp-$SCRIPT

15 16 17
SUPERUSER=
[ $(id -u) -eq 0 ] && SUPERUSER=Y

18
BUILDDIR=
19
FLAVOR=
20
MNTDIR=
21 22 23 24 25
PACKAGES=
SIGNALS="HUP INT TERM"
TMPDIR=
features=

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
error() {
    echo "$SCRIPT: $1" >&2
}

usage() {
    [ "$2" ] && error "$2"
    local opts="[-F <feature>]... [-p <package>]..."
    cat >&2 <<EOF

Syntax: $SCRIPT $opts [<dest_dir>]
        $SCRIPT -f <flavor> $opts <dest_dir>
        $SCRIPT -b <build_dir> $opts [<dest_dir>]

Options: -b|--build <build_dir>  Install custom-built kernel
         -f|--flavor <flavor>    Install kernel of specified flavor
         -F|--feature <feature>  Enable initfs feature
         -p|--package <package>  Additional module or firmware package
43
         -v|--verbose            Verbose output
44 45 46 47 48

EOF
    exit $1
}

49 50 51
QUIET_OPT="--quiet"
OPTS=$(getopt -l build-dir:,flavor:,feature:,help,package:,verbose -n $SCRIPT \
    -o b:f:F:hp:v -- "$@") || usage 1
52 53 54
eval set -- "$OPTS"
while :; do
    case "$1" in
55 56
	-b|--build-dir)
	    BUILDDIR=$2
57
	    shift
58
	    ;;
59 60
	-f|--flavor)
	    FLAVOR=$2
61
	    shift
62 63 64
	    ;;
	-F|--feature)
	    features="$features $2"
65
	    shift
66
	    ;;
67
	-h|--help)
68
	    echo "$SCRIPT @VERSION@" >&2
69 70
	    usage 0
	    ;;
71 72
	-p|--package)
	    PACKAGES="$PACKAGES $2"
73 74 75 76
	    shift
	    ;;
	-v|--verbose)
	    QUIET_OPT=
77 78 79 80 81
	    ;;
	--)
	    break
	    ;;
    esac
82
    shift
83 84 85 86 87
done

DESTDIR=$2


88
[ "$BUILDDIR" -a "$FLAVOR" ] && \
89
    usage 1 "Cannot specify both build directory and flavor"
90

91
if [ -z "$DESTDIR" ]; then
92 93
    [ "$FLAVOR" ] && \
	usage 1 "Cannot specify flavor when updating the current kernel"
94

95 96 97
    [ "$SUPERUSER" ] || \
	usage 1 "Specify destination directory or run as superuser"

98 99 100 101
    while read MOUNT; do
	set -- $MOUNT
	[ $2 = /.modloop ] || continue
	DESTDIR=$(dirname $(losetup $1 | cut -d " " -f 3))
102
	MNTDIR=$(dirname "$DESTDIR")
103 104 105
	break
    done < /proc/mounts

106 107 108 109
    if [ -z "$MNTDIR" ]; then
	error "Module loopback device not mounted"
	exit 1
    fi
110 111 112
fi

remount() {
113
    mount $1 -o remount "$MNTDIR"
114 115 116 117 118 119 120 121 122 123 124
}


ignore_sigs() {
    trap "" $SIGNALS
}

clean_up() {
    set +e
    ignore_sigs

125
    [ "$SUPERUSER" ] && apk del $QUIET_OPT $VIRTUAL
126
    rm -fr $TMPDIR
127 128 129 130 131
}

trap clean_up EXIT $SIGNALS


132
if [ "$SUPERUSER" ]; then
Natanael Copa's avatar
Natanael Copa committed
133
    apk add $QUIET_OPT --update-cache -t $VIRTUAL mkinitfs squashfs-tools
134
fi
135

136 137 138
if [ -z "$features" ]; then
    . /etc/mkinitfs/mkinitfs.conf
fi
139

140
if [ -z "$FLAVOR" ]; then
141 142
    FLAVOR=$(uname -r | cut -d - -f 3-)
    [ "$FLAVOR" ] || FLAVOR=vanilla
143 144
fi

145
TMPDIR=$(mktemp -d /tmp/$SCRIPT.XXXXXX)
146
ROOT=$TMPDIR/root
147
BOOT=$ROOT/boot
148
WRAPPER=
149 150

_exec() {
151
    $WRAPPER "$@"
152
}
153

154
_apk() {
155 156
    local cmd=$1
    shift
157 158 159 160 161 162 163 164 165 166 167 168

    local wrapper=
    if [ -z "$SUPERUSER" ]; then
	local opt=
	local fake_env=$TMPDIR/fake-env
	if [ -f $fake_env ]; then
	    opt="-i $fake_env"
	    WRAPPER="fakeroot $opt --"
	fi
	wrapper="fakeroot $opt -s $fake_env --"
    fi

169
    $wrapper apk $cmd $QUIET_OPT -p $ROOT --keys-dir /etc/apk/keys \
170 171 172
	--repositories-file /etc/apk/repositories $*
}

173 174 175
extra_pkgs() {
    local res=$(_apk search -x $1)
    if [ "$res" ]; then
176
	echo $*
177 178 179
    fi
}

180
# set up the root and get the APKINDEX for search
181
_apk add --initdb --update-cache
182

183
if [ "$BUILDDIR" ]; then
184
    mkdir -p $BOOT
185
    make -C "$BUILDDIR" firmware_install install modules_install \
186
	INSTALL_MOD_PATH=$ROOT INSTALL_PATH=$BOOT
187 188
else
    if [ -z "$PACKAGES" ]; then
189 190
	PACKAGES="$(extra_pkgs "dahdi-linux-$FLAVOR" dahdi-linux)
		$(extra_pkgs "xtables-addons-$FLAVOR")"
191
    fi
192
    PACKAGES="$PACKAGES linux-$FLAVOR linux-firmware"
193
fi
194
_apk add --no-scripts alpine-base $PACKAGES
195

196

197 198
KVER_FLAVOR=
[ "$FLAVOR" = vanilla ] || KVER_FLAVOR=-$FLAVOR
199 200
KVER=$(basename $(ls -d $ROOT/lib/modules/*"$KVER_FLAVOR"))
depmod -b $ROOT "$KVER"
201 202 203 204


STAGING=$TMPDIR/boot
MODLOOP=$TMPDIR/modloop
205
MODIMG=modloop-$FLAVOR
206

207 208 209
mkdir $MODLOOP $STAGING
cp -a $ROOT/lib/modules $MODLOOP
cp -a $ROOT/lib/firmware $MODLOOP/modules
210
_exec mksquashfs $MODLOOP "$STAGING/$MODIMG" -comp xz
211

212
_exec mkinitfs -q -b $ROOT -F "$features base squashfs" \
213
    -o "$STAGING/initramfs-$FLAVOR" "$KVER"
214 215 216 217

for file in System.map config vmlinuz; do
    cp "$BOOT/$file$KVER_FLAVOR" $STAGING
done
218 219


220 221
if [ "$MNTDIR" ]; then
    ignore_sigs
222
    umount /.modloop
223 224
    remount -w
fi
225

226
mv $STAGING/* "$DESTDIR"
227

228 229 230 231
if [ "$MNTDIR" ]; then
    set +e
    sync
    remount -r
232
    mount -o loop "$DESTDIR/$MODIMG" /.modloop
233
fi
234 235

exit 0