update-kernel.in 4.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!/bin/sh -e

# update-kernel
#
# Kernel and firmware update script for Alpine installations set up
# with setup-bootable
#
# Copyright (c) 2014 Timo Teräs
# Copyright (c) 2014 Kaarle Ritvanen


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=

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
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

EOF
    exit $1
}

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

DESTDIR=$2


79
[ "$BUILDDIR" -a "$FLAVOR" ] && \
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
80
    usage 1 "Cannot specify both build directory and flavor"
81

82
if [ -z "$DESTDIR" ]; then
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
83 84
    [ "$FLAVOR" ] && \
	usage 1 "Cannot specify flavor when updating the current kernel"
85

86 87 88
    [ "$SUPERUSER" ] || \
	usage 1 "Specify destination directory or run as superuser"

89 90 91 92
    while read MOUNT; do
	set -- $MOUNT
	[ $2 = /.modloop ] || continue
	DESTDIR=$(dirname $(losetup $1 | cut -d " " -f 3))
93
	MNTDIR=$(dirname "$DESTDIR")
94 95 96
	break
    done < /proc/mounts

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
97 98 99 100
    if [ -z "$MNTDIR" ]; then
	error "Module loopback device not mounted"
	exit 1
    fi
101 102 103
fi

remount() {
104
    mount $1 -o remount "$MNTDIR"
105 106 107 108 109 110 111 112 113 114 115
}


ignore_sigs() {
    trap "" $SIGNALS
}

clean_up() {
    set +e
    ignore_sigs

116
    [ "$SUPERUSER" ] && apk del -q $VIRTUAL
117
    rm -fr $TMPDIR
118 119 120 121 122
}

trap clean_up EXIT $SIGNALS


123 124 125
if [ "$SUPERUSER" ]; then
    apk add -qU -t $VIRTUAL mkinitfs squashfs-tools
fi
126

127 128 129
if [ -z "$features" ]; then
    . /etc/mkinitfs/mkinitfs.conf
fi
130

131
if [ -z "$FLAVOR" ]; then
132 133
    FLAVOR=$(uname -r | cut -d - -f 3-)
    [ "$FLAVOR" ] || FLAVOR=vanilla
134 135
fi

136
TMPDIR=$(mktemp -d /tmp/$SCRIPT.XXXXXX)
137
ROOT=$TMPDIR/root
138
BOOT=$ROOT/boot
139
WRAPPER=
140 141

_exec() {
142
    $WRAPPER "$@"
143
}
144

145
_apk() {
146 147
    local cmd=$1
    shift
148 149 150 151 152 153 154 155 156 157 158 159 160

    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

    $wrapper apk $cmd -p $ROOT --keys-dir /etc/apk/keys \
161 162 163
	--repositories-file /etc/apk/repositories $*
}

164 165 166
extra_pkgs() {
    local res=$(_apk search -x $1)
    if [ "$res" ]; then
167
	echo $*
168 169 170
    fi
}

171 172 173
# set up the root and get the APKINDEX for search
_apk add --quiet --initdb --update-cache

174
if [ "$BUILDDIR" ]; then
175
    mkdir -p $BOOT
176
    make -C "$BUILDDIR" firmware_install install modules_install \
177
	INSTALL_MOD_PATH=$ROOT INSTALL_PATH=$BOOT
178 179
else
    if [ -z "$PACKAGES" ]; then
180 181
	PACKAGES="$(extra_pkgs "dahdi-linux-$FLAVOR" dahdi-linux)
		$(extra_pkgs "xtables-addons-$FLAVOR")"
182
    fi
183
    PACKAGES="$PACKAGES linux-$FLAVOR linux-firmware"
184
fi
185
_apk add --quiet --no-scripts alpine-base $PACKAGES
186

187

188 189
KVER_FLAVOR=
[ "$FLAVOR" = vanilla ] || KVER_FLAVOR=-$FLAVOR
190 191
KVER=$(basename $(ls -d $ROOT/lib/modules/*"$KVER_FLAVOR"))
depmod -b $ROOT "$KVER"
192 193 194 195 196 197


STAGING=$TMPDIR/boot
MODLOOP=$TMPDIR/modloop
MODIMG=$FLAVOR.modloop.squashfs

198 199 200
mkdir $MODLOOP $STAGING
cp -a $ROOT/lib/modules $MODLOOP
cp -a $ROOT/lib/firmware $MODLOOP/modules
201
_exec mksquashfs $MODLOOP "$STAGING/$MODIMG" -comp xz
202

203 204
_exec mkinitfs -q -b $ROOT -F "$features base squashfs" \
    -o "$STAGING/$FLAVOR.gz" "$KVER"
205
cp "$BOOT/vmlinuz$KVER_FLAVOR" "$STAGING/$FLAVOR"
206 207


208 209
if [ "$MNTDIR" ]; then
    ignore_sigs
210
    umount /.modloop
211 212
    remount -w
fi
213

214
mv $STAGING/* "$DESTDIR"
215

216 217 218 219
if [ "$MNTDIR" ]; then
    set +e
    sync
    remount -r
220
    mount -o loop "$DESTDIR/$MODIMG" /.modloop
221
fi
222 223

exit 0