mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
184 lines
3.8 KiB
Bash
184 lines
3.8 KiB
Bash
![]() |
#!/bin/bash
|
||
|
# SPDX-License-Identifier: GPL-2.0
|
||
|
|
||
|
set -ue
|
||
|
|
||
|
CROSS_COMPILE="${CROSS_COMPILE:-""}"
|
||
|
|
||
|
test_dir=$(realpath "$(dirname "$0")")
|
||
|
kernel_dir=$(realpath "$test_dir/../../../..")
|
||
|
|
||
|
tmp_dir=$(mktemp -d /tmp/kho-test.XXXXXXXX)
|
||
|
headers_dir="$tmp_dir/usr"
|
||
|
initrd_dir="$tmp_dir/initrd"
|
||
|
initrd="$tmp_dir/initrd.cpio"
|
||
|
|
||
|
source "$test_dir/../kselftest/ktap_helpers.sh"
|
||
|
|
||
|
function usage() {
|
||
|
cat <<EOF
|
||
|
$0 [-d build_dir] [-j jobs] [-t target_arch] [-h]
|
||
|
Options:
|
||
|
-d) path to the kernel build directory
|
||
|
-j) number of jobs for compilation, similar to -j in make
|
||
|
-t) run test for target_arch, requires CROSS_COMPILE set
|
||
|
supported targets: aarch64, x86_64
|
||
|
-h) display this help
|
||
|
EOF
|
||
|
}
|
||
|
|
||
|
function cleanup() {
|
||
|
rm -fr "$tmp_dir"
|
||
|
ktap_finished
|
||
|
}
|
||
|
trap cleanup EXIT
|
||
|
|
||
|
function skip() {
|
||
|
local msg=${1:-""}
|
||
|
|
||
|
ktap_test_skip "$msg"
|
||
|
exit "$KSFT_SKIP"
|
||
|
}
|
||
|
|
||
|
function fail() {
|
||
|
local msg=${1:-""}
|
||
|
|
||
|
ktap_test_fail "$msg"
|
||
|
exit "$KSFT_FAIL"
|
||
|
}
|
||
|
|
||
|
function build_kernel() {
|
||
|
local build_dir=$1
|
||
|
local make_cmd=$2
|
||
|
local arch_kconfig=$3
|
||
|
local kimage=$4
|
||
|
|
||
|
local kho_config="$tmp_dir/kho.config"
|
||
|
local kconfig="$build_dir/.config"
|
||
|
|
||
|
# enable initrd, KHO and KHO test in kernel configuration
|
||
|
tee "$kconfig" > "$kho_config" <<EOF
|
||
|
CONFIG_BLK_DEV_INITRD=y
|
||
|
CONFIG_KEXEC_HANDOVER=y
|
||
|
CONFIG_TEST_KEXEC_HANDOVER=y
|
||
|
CONFIG_DEBUG_KERNEL=y
|
||
|
CONFIG_DEBUG_VM=y
|
||
|
$arch_kconfig
|
||
|
EOF
|
||
|
|
||
|
make_cmd="$make_cmd -C $kernel_dir O=$build_dir"
|
||
|
$make_cmd olddefconfig
|
||
|
|
||
|
# verify that kernel confiration has all necessary options
|
||
|
while read -r opt ; do
|
||
|
grep "$opt" "$kconfig" &>/dev/null || skip "$opt is missing"
|
||
|
done < "$kho_config"
|
||
|
|
||
|
$make_cmd "$kimage"
|
||
|
$make_cmd headers_install INSTALL_HDR_PATH="$headers_dir"
|
||
|
}
|
||
|
|
||
|
function mkinitrd() {
|
||
|
local kernel=$1
|
||
|
|
||
|
mkdir -p "$initrd_dir"/{dev,debugfs,proc}
|
||
|
sudo mknod "$initrd_dir/dev/console" c 5 1
|
||
|
|
||
|
"$CROSS_COMPILE"gcc -s -static -Os -nostdinc -I"$headers_dir/include" \
|
||
|
-fno-asynchronous-unwind-tables -fno-ident -nostdlib \
|
||
|
-include "$test_dir/../../../include/nolibc/nolibc.h" \
|
||
|
-o "$initrd_dir/init" "$test_dir/init.c" \
|
||
|
|
||
|
cp "$kernel" "$initrd_dir/kernel"
|
||
|
|
||
|
pushd "$initrd_dir" &>/dev/null
|
||
|
find . | cpio -H newc --create > "$initrd" 2>/dev/null
|
||
|
popd &>/dev/null
|
||
|
}
|
||
|
|
||
|
function run_qemu() {
|
||
|
local qemu_cmd=$1
|
||
|
local cmdline=$2
|
||
|
local kernel=$3
|
||
|
local serial="$tmp_dir/qemu.serial"
|
||
|
|
||
|
cmdline="$cmdline kho=on panic=-1"
|
||
|
|
||
|
$qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \
|
||
|
-accel kvm -accel hvf -accel tcg \
|
||
|
-serial file:"$serial" \
|
||
|
-append "$cmdline" \
|
||
|
-kernel "$kernel" \
|
||
|
-initrd "$initrd"
|
||
|
|
||
|
grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed"
|
||
|
}
|
||
|
|
||
|
function target_to_arch() {
|
||
|
local target=$1
|
||
|
|
||
|
case $target in
|
||
|
aarch64) echo "arm64" ;;
|
||
|
x86_64) echo "x86" ;;
|
||
|
*) skip "architecture $target is not supported"
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
function main() {
|
||
|
local build_dir="$kernel_dir/.kho"
|
||
|
local jobs=$(($(nproc) * 2))
|
||
|
local target="$(uname -m)"
|
||
|
|
||
|
# skip the test if any of the preparation steps fails
|
||
|
set -o errtrace
|
||
|
trap skip ERR
|
||
|
|
||
|
while getopts 'hd:j:t:' opt; do
|
||
|
case $opt in
|
||
|
d)
|
||
|
build_dir="$OPTARG"
|
||
|
;;
|
||
|
j)
|
||
|
jobs="$OPTARG"
|
||
|
;;
|
||
|
t)
|
||
|
target="$OPTARG"
|
||
|
;;
|
||
|
h)
|
||
|
usage
|
||
|
exit 0
|
||
|
;;
|
||
|
*)
|
||
|
echo Unknown argument "$opt"
|
||
|
usage
|
||
|
exit 1
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
|
||
|
ktap_print_header
|
||
|
ktap_set_plan 1
|
||
|
|
||
|
if [[ "$target" != "$(uname -m)" ]] && [[ -z "$CROSS_COMPILE" ]]; then
|
||
|
skip "Cross-platform testing needs to specify CROSS_COMPILE"
|
||
|
fi
|
||
|
|
||
|
mkdir -p "$build_dir"
|
||
|
local arch=$(target_to_arch "$target")
|
||
|
source "$test_dir/$arch.conf"
|
||
|
|
||
|
# build the kernel and create initrd
|
||
|
# initrd includes the kernel image that will be kexec'ed
|
||
|
local make_cmd="make ARCH=$arch CROSS_COMPILE=$CROSS_COMPILE -j$jobs"
|
||
|
build_kernel "$build_dir" "$make_cmd" "$QEMU_KCONFIG" "$KERNEL_IMAGE"
|
||
|
|
||
|
local kernel="$build_dir/arch/$arch/boot/$KERNEL_IMAGE"
|
||
|
mkinitrd "$kernel"
|
||
|
|
||
|
run_qemu "$QEMU_CMD" "$KERNEL_CMDLINE" "$kernel"
|
||
|
|
||
|
ktap_test_pass "KHO succeeded"
|
||
|
}
|
||
|
|
||
|
main "$@"
|