189dd1421SPasha Tatashin#!/bin/bash 289dd1421SPasha Tatashin# SPDX-License-Identifier: GPL-2.0 389dd1421SPasha Tatashin 489dd1421SPasha Tatashinset -ue 589dd1421SPasha Tatashin 689dd1421SPasha TatashinCROSS_COMPILE="${CROSS_COMPILE:-""}" 789dd1421SPasha Tatashin 889dd1421SPasha Tatashintest_dir=$(realpath "$(dirname "$0")") 989dd1421SPasha Tatashinkernel_dir=$(realpath "$test_dir/../../../..") 1089dd1421SPasha Tatashin 1189dd1421SPasha Tatashinworkspace_dir="" 1289dd1421SPasha Tatashinheaders_dir="" 1389dd1421SPasha Tatashininitrd="" 1489dd1421SPasha TatashinKEEP_WORKSPACE=0 1589dd1421SPasha Tatashin 1689dd1421SPasha Tatashinsource "$test_dir/../kselftest/ktap_helpers.sh" 1789dd1421SPasha Tatashin 1889dd1421SPasha Tatashinfunction get_arch_conf() { 1989dd1421SPasha Tatashin local arch=$1 2089dd1421SPasha Tatashin if [[ "$arch" == "arm64" ]]; then 2189dd1421SPasha Tatashin QEMU_CMD="qemu-system-aarch64 -M virt -cpu max" 2289dd1421SPasha Tatashin KERNEL_IMAGE="Image" 2389dd1421SPasha Tatashin KERNEL_CMDLINE="console=ttyAMA0" 2489dd1421SPasha Tatashin elif [[ "$arch" == "x86" ]]; then 2589dd1421SPasha Tatashin QEMU_CMD="qemu-system-x86_64" 2689dd1421SPasha Tatashin KERNEL_IMAGE="bzImage" 2789dd1421SPasha Tatashin KERNEL_CMDLINE="console=ttyS0" 2889dd1421SPasha Tatashin else 2989dd1421SPasha Tatashin echo "Unsupported architecture: $arch" 3089dd1421SPasha Tatashin exit 1 3189dd1421SPasha Tatashin fi 3289dd1421SPasha Tatashin} 3389dd1421SPasha Tatashin 3489dd1421SPasha Tatashinfunction usage() { 3589dd1421SPasha Tatashin cat <<EOF 3689dd1421SPasha Tatashin$0 [-d build_dir] [-j jobs] [-t target_arch] [-T test_name] [-w workspace_dir] [-k] [-h] 3789dd1421SPasha TatashinOptions: 3889dd1421SPasha Tatashin -d) path to the kernel build directory (default: .luo_test_build.<arch>) 3989dd1421SPasha Tatashin -j) number of jobs for compilation 4089dd1421SPasha Tatashin -t) run test for target_arch (aarch64, x86_64) 4189dd1421SPasha Tatashin -T) test name to run (default: luo_kexec_simple) 4289dd1421SPasha Tatashin -w) custom workspace directory (default: creates temp dir) 4389dd1421SPasha Tatashin -k) keep workspace directory after successful test 4489dd1421SPasha Tatashin -h) display this help 4589dd1421SPasha TatashinEOF 4689dd1421SPasha Tatashin} 4789dd1421SPasha Tatashin 4889dd1421SPasha Tatashinfunction cleanup() { 4989dd1421SPasha Tatashin if [ "$KEEP_WORKSPACE" -eq 1 ]; then 5089dd1421SPasha Tatashin echo "# Workspace preserved at: $workspace_dir" 5189dd1421SPasha Tatashin else 5289dd1421SPasha Tatashin rm -fr "$workspace_dir" 5389dd1421SPasha Tatashin fi 5489dd1421SPasha Tatashin 5589dd1421SPasha Tatashin ktap_finished 5689dd1421SPasha Tatashin} 5789dd1421SPasha Tatashin 5889dd1421SPasha Tatashinfunction skip() { 5989dd1421SPasha Tatashin local msg=${1:-""} 6089dd1421SPasha Tatashin ktap_test_skip "$msg" 6189dd1421SPasha Tatashin exit "$KSFT_SKIP" 6289dd1421SPasha Tatashin} 6389dd1421SPasha Tatashin 6489dd1421SPasha Tatashinfunction fail() { 6589dd1421SPasha Tatashin local msg=${1:-""} 6689dd1421SPasha Tatashin ktap_test_fail "$msg" 6789dd1421SPasha Tatashin exit "$KSFT_FAIL" 6889dd1421SPasha Tatashin} 6989dd1421SPasha Tatashin 7089dd1421SPasha Tatashinfunction detect_cross_compile() { 7189dd1421SPasha Tatashin local target=$1 7289dd1421SPasha Tatashin local host=$(uname -m) 7389dd1421SPasha Tatashin 7489dd1421SPasha Tatashin [[ "$host" == "arm64" ]] && host="aarch64" 7589dd1421SPasha Tatashin [[ "$target" == "arm64" ]] && target="aarch64" 7689dd1421SPasha Tatashin 7789dd1421SPasha Tatashin if [[ "$host" == "$target" ]]; then 7889dd1421SPasha Tatashin CROSS_COMPILE="" 7989dd1421SPasha Tatashin return 8089dd1421SPasha Tatashin fi 8189dd1421SPasha Tatashin 8289dd1421SPasha Tatashin if [[ -n "$CROSS_COMPILE" ]]; then 8389dd1421SPasha Tatashin return 8489dd1421SPasha Tatashin fi 8589dd1421SPasha Tatashin 8689dd1421SPasha Tatashin local candidate="" 8789dd1421SPasha Tatashin case "$target" in 8889dd1421SPasha Tatashin aarch64) candidate="aarch64-linux-gnu-" ;; 8989dd1421SPasha Tatashin x86_64) candidate="x86_64-linux-gnu-" ;; 9089dd1421SPasha Tatashin *) skip "Auto-detection for target '$target' not supported. Please set CROSS_COMPILE manually." ;; 9189dd1421SPasha Tatashin esac 9289dd1421SPasha Tatashin 9389dd1421SPasha Tatashin if command -v "${candidate}gcc" &> /dev/null; then 9489dd1421SPasha Tatashin CROSS_COMPILE="$candidate" 9589dd1421SPasha Tatashin else 9689dd1421SPasha Tatashin skip "Compiler '${candidate}gcc' not found. Please install it (e.g., 'apt install gcc-aarch64-linux-gnu') or set CROSS_COMPILE." 9789dd1421SPasha Tatashin fi 9889dd1421SPasha Tatashin} 9989dd1421SPasha Tatashin 10089dd1421SPasha Tatashinfunction build_kernel() { 10189dd1421SPasha Tatashin local build_dir=$1 10289dd1421SPasha Tatashin local make_cmd=$2 10389dd1421SPasha Tatashin local kimage=$3 10489dd1421SPasha Tatashin local target_arch=$4 10589dd1421SPasha Tatashin 10689dd1421SPasha Tatashin local luo_config="$build_dir/luo.config" 10789dd1421SPasha Tatashin local kconfig="$build_dir/.config" 10889dd1421SPasha Tatashin local common_conf="$test_dir/config" 10989dd1421SPasha Tatashin local arch_conf="$test_dir/config.$target_arch" 11089dd1421SPasha Tatashin 11189dd1421SPasha Tatashin echo "# Building kernel in: $build_dir" 11289dd1421SPasha Tatashin 11389dd1421SPasha Tatashin cat "$arch_conf" "$common_conf" | tee "$kconfig" > "$luo_config" 11489dd1421SPasha Tatashin $make_cmd olddefconfig 11589dd1421SPasha Tatashin 11689dd1421SPasha Tatashin # verify that kernel confiration has all necessary options 11789dd1421SPasha Tatashin while read -r opt ; do 11889dd1421SPasha Tatashin grep "$opt" "$kconfig" &>/dev/null || skip "$opt is missing" 11989dd1421SPasha Tatashin done < "$luo_config" 12089dd1421SPasha Tatashin 12189dd1421SPasha Tatashin $make_cmd "$kimage" 12289dd1421SPasha Tatashin $make_cmd headers_install INSTALL_HDR_PATH="$headers_dir" 12389dd1421SPasha Tatashin} 12489dd1421SPasha Tatashin 12589dd1421SPasha Tatashinfunction mkinitrd() { 12689dd1421SPasha Tatashin local build_dir=$1 12789dd1421SPasha Tatashin local kernel_path=$2 12889dd1421SPasha Tatashin local test_name=$3 12989dd1421SPasha Tatashin 13089dd1421SPasha Tatashin # Compile the test binary and the init process 13189dd1421SPasha Tatashin "$CROSS_COMPILE"gcc -static -O2 -nostdinc -nostdlib \ 13289dd1421SPasha Tatashin -I "$headers_dir/include" \ 13389dd1421SPasha Tatashin -I "$kernel_dir/tools/include/nolibc" \ 134*df1a0d06SVipin Sharma -I "$test_dir/lib/include" \ 13589dd1421SPasha Tatashin -o "$workspace_dir/test_binary" \ 136*df1a0d06SVipin Sharma "$test_dir/$test_name.c" "$test_dir/lib/lu_utils.c" 13789dd1421SPasha Tatashin 13889dd1421SPasha Tatashin "$CROSS_COMPILE"gcc -s -static -Os -nostdinc -nostdlib \ 13989dd1421SPasha Tatashin -fno-asynchronous-unwind-tables -fno-ident \ 14089dd1421SPasha Tatashin -fno-stack-protector \ 14189dd1421SPasha Tatashin -I "$headers_dir/include" \ 14289dd1421SPasha Tatashin -I "$kernel_dir/tools/include/nolibc" \ 14389dd1421SPasha Tatashin -o "$workspace_dir/init" "$test_dir/init.c" 14489dd1421SPasha Tatashin 14589dd1421SPasha Tatashin cat > "$workspace_dir/cpio_list_inner" <<EOF 14689dd1421SPasha Tatashindir /dev 0755 0 0 14789dd1421SPasha Tatashindir /proc 0755 0 0 14889dd1421SPasha Tatashindir /debugfs 0755 0 0 14989dd1421SPasha Tatashinnod /dev/console 0600 0 0 c 5 1 15089dd1421SPasha Tatashinfile /init $workspace_dir/init 0755 0 0 15189dd1421SPasha Tatashinfile /test_binary $workspace_dir/test_binary 0755 0 0 15289dd1421SPasha TatashinEOF 15389dd1421SPasha Tatashin 15489dd1421SPasha Tatashin # Generate inner_initrd.cpio 15589dd1421SPasha Tatashin "$build_dir/usr/gen_init_cpio" "$workspace_dir/cpio_list_inner" > "$workspace_dir/inner_initrd.cpio" 15689dd1421SPasha Tatashin 15789dd1421SPasha Tatashin cat > "$workspace_dir/cpio_list" <<EOF 15889dd1421SPasha Tatashindir /dev 0755 0 0 15989dd1421SPasha Tatashindir /proc 0755 0 0 16089dd1421SPasha Tatashindir /debugfs 0755 0 0 16189dd1421SPasha Tatashinnod /dev/console 0600 0 0 c 5 1 16289dd1421SPasha Tatashinfile /init $workspace_dir/init 0755 0 0 16389dd1421SPasha Tatashinfile /kernel $kernel_path 0644 0 0 16489dd1421SPasha Tatashinfile /test_binary $workspace_dir/test_binary 0755 0 0 16589dd1421SPasha Tatashinfile /initrd.img $workspace_dir/inner_initrd.cpio 0644 0 0 16689dd1421SPasha TatashinEOF 16789dd1421SPasha Tatashin 16889dd1421SPasha Tatashin # Generate the final initrd 16989dd1421SPasha Tatashin "$build_dir/usr/gen_init_cpio" "$workspace_dir/cpio_list" > "$initrd" 17089dd1421SPasha Tatashin} 17189dd1421SPasha Tatashin 17289dd1421SPasha Tatashinfunction run_qemu() { 17389dd1421SPasha Tatashin local qemu_cmd=$1 17489dd1421SPasha Tatashin local cmdline=$2 17589dd1421SPasha Tatashin local kernel_path=$3 17689dd1421SPasha Tatashin local serial="$workspace_dir/qemu.serial" 17789dd1421SPasha Tatashin 17889dd1421SPasha Tatashin cmdline="$cmdline liveupdate=on panic=-1" 17989dd1421SPasha Tatashin 18089dd1421SPasha Tatashin echo "# Serial Log: $serial" 18189dd1421SPasha Tatashin timeout 30s \ 18289dd1421SPasha Tatashin $qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \ 18389dd1421SPasha Tatashin -accel tcg -accel hvf -accel kvm \ 18489dd1421SPasha Tatashin -serial file:"$serial" \ 18589dd1421SPasha Tatashin -append "$cmdline" \ 18689dd1421SPasha Tatashin -kernel "$kernel_path" \ 18789dd1421SPasha Tatashin -initrd "$initrd" 18889dd1421SPasha Tatashin 18989dd1421SPasha Tatashin grep "TEST PASSED" "$serial" &> /dev/null || fail "Liveupdate failed" 19089dd1421SPasha Tatashin} 19189dd1421SPasha Tatashin 19289dd1421SPasha Tatashinfunction target_to_arch() { 19389dd1421SPasha Tatashin local target=$1 19489dd1421SPasha Tatashin case $target in 19589dd1421SPasha Tatashin aarch64) echo "arm64" ;; 19689dd1421SPasha Tatashin x86_64) echo "x86" ;; 19789dd1421SPasha Tatashin *) skip "architecture $target is not supported" 19889dd1421SPasha Tatashin esac 19989dd1421SPasha Tatashin} 20089dd1421SPasha Tatashin 20189dd1421SPasha Tatashinfunction main() { 20289dd1421SPasha Tatashin local build_dir="" 20389dd1421SPasha Tatashin local jobs=$(nproc) 20489dd1421SPasha Tatashin local target="$(uname -m)" 20589dd1421SPasha Tatashin local test_name="luo_kexec_simple" 20689dd1421SPasha Tatashin local workspace_arg="" 20789dd1421SPasha Tatashin 20889dd1421SPasha Tatashin set -o errtrace 20989dd1421SPasha Tatashin trap fail ERR 21089dd1421SPasha Tatashin 21189dd1421SPasha Tatashin while getopts 'hd:j:t:T:w:k' opt; do 21289dd1421SPasha Tatashin case $opt in 21389dd1421SPasha Tatashin d) build_dir="$OPTARG" ;; 21489dd1421SPasha Tatashin j) jobs="$OPTARG" ;; 21589dd1421SPasha Tatashin t) target="$OPTARG" ;; 21689dd1421SPasha Tatashin T) test_name="$OPTARG" ;; 21789dd1421SPasha Tatashin w) workspace_arg="$OPTARG" ;; 21889dd1421SPasha Tatashin k) KEEP_WORKSPACE=1 ;; 21989dd1421SPasha Tatashin h) usage; exit 0 ;; 22089dd1421SPasha Tatashin *) echo "Unknown argument $opt"; usage; exit 1 ;; 22189dd1421SPasha Tatashin esac 22289dd1421SPasha Tatashin done 22389dd1421SPasha Tatashin 22489dd1421SPasha Tatashin ktap_print_header 22589dd1421SPasha Tatashin ktap_set_plan 1 22689dd1421SPasha Tatashin trap cleanup EXIT 22789dd1421SPasha Tatashin 22889dd1421SPasha Tatashin if [ -n "$workspace_arg" ]; then 22989dd1421SPasha Tatashin workspace_dir="$(realpath -m "$workspace_arg")" 23089dd1421SPasha Tatashin mkdir -p "$workspace_dir" 23189dd1421SPasha Tatashin else 23289dd1421SPasha Tatashin workspace_dir=$(mktemp -d /tmp/luo-test.XXXXXXXX) 23389dd1421SPasha Tatashin fi 23489dd1421SPasha Tatashin 23589dd1421SPasha Tatashin echo "# Workspace created at: $workspace_dir" 23689dd1421SPasha Tatashin headers_dir="$workspace_dir/usr" 23789dd1421SPasha Tatashin initrd="$workspace_dir/initrd.cpio" 23889dd1421SPasha Tatashin 23989dd1421SPasha Tatashin detect_cross_compile "$target" 24089dd1421SPasha Tatashin 24189dd1421SPasha Tatashin local arch=$(target_to_arch "$target") 24289dd1421SPasha Tatashin 24389dd1421SPasha Tatashin if [ -z "$build_dir" ]; then 24489dd1421SPasha Tatashin build_dir="$kernel_dir/.luo_test_build.$arch" 24589dd1421SPasha Tatashin fi 24689dd1421SPasha Tatashin 24789dd1421SPasha Tatashin mkdir -p "$build_dir" 24889dd1421SPasha Tatashin build_dir=$(realpath "$build_dir") 24989dd1421SPasha Tatashin get_arch_conf "$arch" 25089dd1421SPasha Tatashin 25189dd1421SPasha Tatashin local make_cmd="make -s ARCH=$arch CROSS_COMPILE=$CROSS_COMPILE -j$jobs" 25289dd1421SPasha Tatashin local make_cmd_build="$make_cmd -C $kernel_dir O=$build_dir" 25389dd1421SPasha Tatashin 25489dd1421SPasha Tatashin build_kernel "$build_dir" "$make_cmd_build" "$KERNEL_IMAGE" "$target" 25589dd1421SPasha Tatashin 25689dd1421SPasha Tatashin local final_kernel="$build_dir/arch/$arch/boot/$KERNEL_IMAGE" 25789dd1421SPasha Tatashin mkinitrd "$build_dir" "$final_kernel" "$test_name" 25889dd1421SPasha Tatashin 25989dd1421SPasha Tatashin run_qemu "$QEMU_CMD" "$KERNEL_CMDLINE" "$final_kernel" 26089dd1421SPasha Tatashin ktap_test_pass "$test_name succeeded" 26189dd1421SPasha Tatashin} 26289dd1421SPasha Tatashin 26389dd1421SPasha Tatashinmain "$@" 264