mirror of
https://github.com/zerotier/edge.git
synced 2026-05-22 16:25:05 -07:00
313 lines
6.5 KiB
Bash
Executable File
313 lines
6.5 KiB
Bash
Executable File
#!/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-2015 Kaarle Ritvanen
|
|
|
|
|
|
SCRIPT=update-kernel
|
|
VIRTUAL=.tmp-$SCRIPT
|
|
|
|
SUPERUSER=
|
|
[ $(id -u) -eq 0 ] && SUPERUSER=Y
|
|
if [ -z "$SUPERUSER" ] && [ -z "$FAKEROOTKEY" ]; then
|
|
exec fakeroot "$0" "$@"
|
|
fi
|
|
|
|
ARCH=
|
|
BUILDDIR=
|
|
FLAVOR=
|
|
MEDIA=
|
|
MNTDIR=
|
|
PACKAGES=
|
|
MKINITFS_ARGS=
|
|
REPOSITORIES_FILE=/etc/apk/repositories
|
|
SIGNALS="HUP INT TERM"
|
|
TMPDIR=
|
|
features=
|
|
|
|
error() {
|
|
echo "$SCRIPT: $1" >&2
|
|
}
|
|
|
|
usage() {
|
|
[ "$2" ] && error "$2"
|
|
local opts="[-F <feature>]... [-p <package>]..."
|
|
local dest_args="[-a <arch>] <dest_dir>"
|
|
cat >&2 <<-__EOF__
|
|
|
|
Syntax: $SCRIPT $opts [$dest_args]
|
|
$SCRIPT -f <flavor> $opts $dest_args
|
|
$SCRIPT -b <build_dir> $opts [$dest_args]
|
|
|
|
Options: -a|--arch <arch> Install kernel for specified architecture
|
|
-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
|
|
-v|--verbose Verbose output
|
|
-k|--apk-pubkey <key> Include given key in initramfs
|
|
-K|--hostkeys Include host keys in initramfs
|
|
-C|--compression Initramfs compression (see mkinitfs for options)
|
|
-M|--media Boot media directory layout
|
|
--repositories-file <f> apk repositories file
|
|
|
|
__EOF__
|
|
exit $1
|
|
}
|
|
|
|
QUIET_OPT="--quiet"
|
|
OPTS=$(getopt -l arch:,build-dir:,flavor:,feature:,help,package:,verbose,apk-pubkey:,hostkeys,compression:,media,repositories-file: \
|
|
-n $SCRIPT -o a:b:f:F:hp:vk:KC:M -- "$@") || usage 1
|
|
|
|
eval set -- "$OPTS"
|
|
while :; do
|
|
case "$1" in
|
|
-a|--arch)
|
|
shift
|
|
ARCH=$1
|
|
;;
|
|
-b|--build-dir)
|
|
shift
|
|
BUILDDIR=$1
|
|
;;
|
|
-f|--flavor)
|
|
shift
|
|
FLAVOR=$1
|
|
;;
|
|
-F|--feature)
|
|
shift
|
|
features="$features $1"
|
|
;;
|
|
-h|--help)
|
|
echo "$SCRIPT 3.8.0-r0" >&2
|
|
usage 0
|
|
;;
|
|
-p|--package)
|
|
shift
|
|
PACKAGES="$PACKAGES $1"
|
|
;;
|
|
-v|--verbose)
|
|
QUIET_OPT=
|
|
;;
|
|
-k|--apk-pubkey)
|
|
shift
|
|
APK_PUBKEY="$1"
|
|
;;
|
|
-K|--hostkeys)
|
|
MKINITFS_ARGS="$MKINITFS_ARGS -K"
|
|
;;
|
|
-C|--compression)
|
|
shift
|
|
MKINITFS_ARGS="$MKINITFS_ARGS -C $1"
|
|
;;
|
|
-M|--media)
|
|
MEDIA=yes
|
|
;;
|
|
--repositories-file)
|
|
shift
|
|
REPOSITORIES_FILE=$1
|
|
;;
|
|
--)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
DESTDIR=$2
|
|
|
|
|
|
[ "$BUILDDIR" -a "$FLAVOR" ] && \
|
|
usage 1 "Cannot specify both build directory and flavor"
|
|
|
|
if [ -z "$DESTDIR" ]; then
|
|
[ "$ARCH" ] && \
|
|
usage 1 "Cannot specify architecture when updating the current kernel"
|
|
|
|
[ "$FLAVOR" ] && \
|
|
usage 1 "Cannot specify flavor when updating the current kernel"
|
|
|
|
[ "$SUPERUSER" ] || \
|
|
usage 1 "Specify destination directory or run as superuser"
|
|
|
|
while read MOUNT; do
|
|
set -- $MOUNT
|
|
[ $2 = /.modloop ] || continue
|
|
DESTDIR=$(dirname $(busybox losetup $1 | cut -d " " -f 3))
|
|
MNTDIR=$(dirname "$DESTDIR")
|
|
break
|
|
done < /proc/mounts
|
|
|
|
if [ -z "$MNTDIR" ]; then
|
|
error "Module loopback device not mounted"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
remount() {
|
|
mount $1 -o remount "$MNTDIR"
|
|
}
|
|
|
|
|
|
ignore_sigs() {
|
|
trap "" $SIGNALS
|
|
}
|
|
|
|
clean_up() {
|
|
set +e
|
|
ignore_sigs
|
|
|
|
if [ "$SUPERUSER" ] && [ -z "$FAKEROOTKEY" ]; then
|
|
apk del $QUIET_OPT $VIRTUAL
|
|
fi
|
|
rm -fr $TMPDIR
|
|
}
|
|
|
|
trap clean_up EXIT $SIGNALS
|
|
|
|
|
|
if [ "$SUPERUSER" ] && [ -z "$FAKEROOTKEY" ]; then
|
|
apk add $QUIET_OPT --update-cache -t $VIRTUAL mkinitfs squashfs-tools kmod
|
|
fi
|
|
|
|
if [ -z "$features" ]; then
|
|
. /etc/mkinitfs/mkinitfs.conf
|
|
fi
|
|
|
|
if [ -z "$FLAVOR" ]; then
|
|
FLAVOR=$(uname -r | cut -d - -f 3-)
|
|
[ "$FLAVOR" ] || FLAVOR=vanilla
|
|
fi
|
|
|
|
[ "$ARCH" ] || ARCH=$(apk --print-arch)
|
|
|
|
TMPDIR=$(mktemp -d /tmp/$SCRIPT.XXXXXX)
|
|
ROOT=$TMPDIR/root
|
|
BOOT=$ROOT/boot
|
|
|
|
_apk() {
|
|
local cmd=$1
|
|
shift
|
|
|
|
apk $cmd $QUIET_OPT -p $ROOT --arch "$ARCH" \
|
|
--keys-dir /etc/apk/keys \
|
|
--repositories-file "$REPOSITORIES_FILE" $*
|
|
}
|
|
|
|
extra_pkgs() {
|
|
local res=$(_apk search -x $1)
|
|
if [ "$res" ]; then
|
|
echo $*
|
|
fi
|
|
}
|
|
|
|
# set up the root and get the APKINDEX for search
|
|
_apk add --initdb --update-cache
|
|
|
|
if [ "$BUILDDIR" ]; then
|
|
case "$ARCH" in
|
|
arm*|aarch64*) _install="zinstall dtbs_install" ;;
|
|
*) _install="install" ;;
|
|
esac
|
|
|
|
mkdir -p $BOOT
|
|
make -C "$BUILDDIR" $_install firmware_install modules_install \
|
|
INSTALL_MOD_PATH=$ROOT \
|
|
INSTALL_PATH=$BOOT \
|
|
INSTALL_DTBS_PATH='$ROOT/usr/lib/linux-$(KERNELRELEASE)'
|
|
else
|
|
if [ -z "$PACKAGES" ]; then
|
|
PACKAGES="$(extra_pkgs "dahdi-linux-$FLAVOR" dahdi-linux)
|
|
$(extra_pkgs "xtables-addons-$FLAVOR")"
|
|
fi
|
|
PACKAGES="$PACKAGES linux-$FLAVOR linux-firmware"
|
|
fi
|
|
_apk add --no-scripts alpine-base $PACKAGES
|
|
|
|
if [ -n "$APK_PUBKEY" ]; then
|
|
mkdir -p "$ROOT"/etc/apk/keys
|
|
cp "$APK_PUBKEY" "$ROOT"/etc/apk/keys/
|
|
fi
|
|
|
|
KVER_FLAVOR=
|
|
[ "$FLAVOR" = vanilla ] || KVER_FLAVOR=-$FLAVOR
|
|
KVER=$(basename $(ls -d $ROOT/lib/modules/*"$KVER_FLAVOR"))
|
|
DTBDIR=$ROOT/usr/lib/linux-$KVER
|
|
depmod -b $ROOT "$KVER"
|
|
|
|
|
|
STAGING=$TMPDIR/boot
|
|
MODLOOP=$TMPDIR/modloop
|
|
MODIMG=modloop-$FLAVOR
|
|
|
|
mkdir $MODLOOP $STAGING
|
|
cp -a $ROOT/lib/modules $MODLOOP
|
|
mkdir -p $MODLOOP/modules/firmware
|
|
find $ROOT/lib/modules -type f -name "*.ko" | xargs modinfo -F firmware | sort -u | while read FW; do
|
|
if [ -e "$ROOT/lib/firmware/$FW" ]; then
|
|
install -pD $ROOT/lib/firmware/$FW $MODLOOP/modules/firmware/$FW
|
|
# include nvram files if firmware is needed.
|
|
if [ -e "$ROOT/lib/firmware/${FW%.*}.txt" ]; then
|
|
install -pD $ROOT/lib/firmware/${FW%.*}.txt $MODLOOP/modules/firmware/${FW%.*}.txt
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# include bluetooth firmware in modloop
|
|
if [ -d "$MODLOOP/modules/firmware/brcm" ]; then
|
|
for _btfw in "$ROOT"/lib/firmware/brcm/*.hcd; do
|
|
install -pD "$_btfw" \
|
|
"$MODLOOP"/modules/firmware/brcm/"${_btfw##*/}"
|
|
done
|
|
fi
|
|
|
|
mksquashfs $MODLOOP "$STAGING/$MODIMG" -comp xz -exit-on-error
|
|
|
|
mkinitfs $MKINITFS_ARGS -q -b $ROOT -F "$features base squashfs" \
|
|
-o "$STAGING/initramfs-$FLAVOR" "$KVER"
|
|
|
|
for file in System.map config vmlinuz; do
|
|
if [ -f "$BOOT/$file-$FLAVOR" ]; then
|
|
cp "$BOOT/$file-$FLAVOR" $STAGING
|
|
else
|
|
cp "$BOOT/$file" $STAGING
|
|
fi
|
|
done
|
|
|
|
if [ "$MNTDIR" ]; then
|
|
ignore_sigs
|
|
umount /.modloop
|
|
remount -w
|
|
fi
|
|
|
|
mkdir -p "$DESTDIR"/${MEDIA:+boot/}
|
|
mv $STAGING/* "$DESTDIR"/${MEDIA:+boot/}
|
|
|
|
if [ -d "$DTBDIR" ]; then
|
|
_opwd=$PWD
|
|
case "$MEDIA,$FLAVOR" in
|
|
yes,rpi*) _dtb="$DESTDIR/" ;;
|
|
yes,*) _dtb="$DESTDIR/boot/dtbs" ;;
|
|
*,*) _dtb="$DESTDIR/dtbs" ;;
|
|
esac
|
|
mkdir -p "$_dtb"
|
|
_dtb=$(realpath "$_dtb")
|
|
cd "$DTBDIR"
|
|
find -type f \( -name "*.dtb" -o -name "*.dtbo" \) | cpio -pudm "$_dtb" 2> /dev/null
|
|
cd "$_opwd"
|
|
fi
|
|
|
|
if [ "$MNTDIR" ]; then
|
|
set +e
|
|
sync
|
|
remount -r
|
|
mount -o loop "$DESTDIR/$MODIMG" /.modloop
|
|
fi
|
|
|
|
exit 0
|