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=

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"
	    ;;
62
	-h|--help)
63
	    echo "$SCRIPT @VERSION@" >&2
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" ] && \
80
    usage 1 "Cannot specify both build directory and flavor"
81

82
if [ -z "$DESTDIR" ]; then
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

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