blob: 29eab24e073feca5ee40808955224eea27148e38 [file] [log] [blame]
#!/bin/sh
#
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Install kernel and kernel modules from USB. This script is used by ChromeOS
# kernel developers to recover from bad kernel updates.
# If we're not running as root, restart as root.
if [ "${UID:-$(id -u)}" -ne 0 ]; then
exec sudo "$0" "$@"
fi
# Load functions and constants.
. /usr/share/misc/shflags || exit 1
. /usr/share/misc/chromeos-common.sh || exit 1
. /usr/sbin/write_gpt.sh || exit 1
load_base_vars
DEFINE_boolean clean "${FLAGS_TRUE}" "Remove modules for old kernels"
DEFINE_boolean debug "${FLAGS_FALSE}" "Show debug output"
TMPMNT="$(mktemp -d)"
# Parse the command line.
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Be aggressive in our error checking. shflags functions leak non-zero error
# codes, so this has to be set after we're done parsing flags.
set -eu
remove_rootfs_verification() {
local rootdev="$1"
local partition="$2"
local device
device="$(make_partition_dev "${rootdev}" "${partition}")"
# See remove_rootfs_verification() in make_dev_ssd.sh for how the kernel
# config is modified when rootfs verification is off.
if dump_kernel_config "${device}" | grep -q "root=/dev/dm"; then
/usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification -i \
"${rootdev}" --partitions "${partition}"
fi
}
cleanup() {
set +eu
if mount | grep -q "${TMPMNT}"; then
umount "${TMPMNT}"
fi
rmdir "${TMPMNT}"
}
main() {
local device
local partition
local rootdev
local usbdev
local version
trap cleanup EXIT
rootdev="$(get_fixed_dst_drive)"
usbdev="$(rootdev -s -d)"
version="$(uname -r)"
if [ "${FLAGS_debug}" = "${FLAGS_TRUE}" ]; then
set -x
fi
if [ "${rootdev}" = "${usbdev}" ]; then
echo "Error: target and destination are the same: ${rootdev}"
exit 1
fi
# Rootfs verification needs to be removed from the rootdev partitions so that
# we can mount them and push new modules. We remove it from the usbdev so
# when we copy that kernel to rootdev it will boot successfully.
remove_rootfs_verification "${rootdev}" "${PARTITION_NUM_KERN_A}"
remove_rootfs_verification "${rootdev}" "${PARTITION_NUM_KERN_B}"
remove_rootfs_verification "${usbdev}" "${PARTITION_NUM_KERN_A}"
for partition in "${PARTITION_NUM_ROOT_A}" "${PARTITION_NUM_ROOT_B}"; do
device="$(make_partition_dev "${rootdev}" "${partition}")"
mount "${device}" "${TMPMNT}"
if [ "${FLAGS_clean}" = "${FLAGS_TRUE}" ]; then
rm -rf "${TMPMNT}"/lib/modules/*
else
rm -rf "${TMPMNT}"/lib/modules/"${version}"
fi
cp -a /lib/modules/"${version}" "${TMPMNT}"/lib/modules/
umount "${TMPMNT}"
done
device="$(make_partition_dev "${usbdev}" "${PARTITION_NUM_KERN_A}")"
for partition in "${PARTITION_NUM_KERN_A}" "${PARTITION_NUM_KERN_B}"; do
local target_device
target_device="$(make_partition_dev "${rootdev}" "${partition}")"
dd if="${device}" of="${target_device}" bs=4M
done
sync
cleanup
trap - EXIT
echo "------------------------------------------------------------"
echo "Installation to '${rootdev}' complete."
}
main "$@"