update-kernel.in 4.12 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 140 141 142 143
WRAPPER=eval

_exec() {
    $WRAPPER "$1"
}
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 167 168 169 170 171 172 173 174
add_pkgs() {
    _apk add -q --no-scripts $*
}

extra_pkgs() {
    local res=$(_apk search -x $1)
    if [ "$res" ]; then
	add_pkgs $*
    fi
}

175 176
add_pkgs -U --initdb alpine-base $PACKAGES
if [ "$BUILDDIR" ]; then
177
    mkdir -p $BOOT
178
    make -C "$BUILDDIR" firmware_install install modules_install \
179
	INSTALL_MOD_PATH=$ROOT INSTALL_PATH=$BOOT
180 181 182 183 184 185
else
    add_pkgs "linux-$FLAVOR" linux-firmware
    if [ -z "$PACKAGES" ]; then
	extra_pkgs "dahdi-linux-$FLAVOR" dahdi-linux
	extra_pkgs "xtables-addons-$FLAVOR"
    fi
186
fi
187

188

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


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

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

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


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

215
mv $STAGING/* "$DESTDIR"
216

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

exit 0