From 858a73f14c129a3c18d9c20800174bb7dfd380e6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 2 Dec 2022 10:47:32 -0700 Subject: [PATCH] full-test: Start of a full testing suite. full-test.sh aims to be a test suite generator for the boot loader. It tries to grab artifacts from the web and then constructs minimal boot environments from that as well as writing qemu-system-* using scripts that facilitates testing all the ways we can boot... At least all the ways that we an boot that qemu can emulate. This is very much a work in progress, and likely could use a good cleanup at some point. Sponsored by: Netflix --- tools/boot/full-test.readme | 40 +++ tools/boot/full-test.sh | 575 ++++++++++++++++++++++++++++++++++++ 2 files changed, 615 insertions(+) create mode 100644 tools/boot/full-test.readme create mode 100644 tools/boot/full-test.sh diff --git a/tools/boot/full-test.readme b/tools/boot/full-test.readme new file mode 100644 index 000000000000..97e79171aa54 --- /dev/null +++ b/tools/boot/full-test.readme @@ -0,0 +1,40 @@ +First, you will need a few things. + +(1) My latest branch at https://github.com/bsdimp/freebsd/tree/boot-linuxboot + (so the boot-linuxboot branch of my freebsd tree, it's sync to Friday). + +(2) a small cache of binaries. You'll need to put these into + ~/stand-test-root/cache. You can find the tarball at + freefall.freebsd.org:~imp/cache.tar. You can just extract this in ~. These are + the linux kernels I'm testing with. + +(3) The latest qemu-system-aarch64 (I think ports/pkg version of emulators/qemu + is recent enough). If not, I know the latest master of qemu project works. + +(4) A recent enough universe that the building of stand will work for all the + architectures that I build. You can hack the ARCHES line near the top of + tools/boot/full-test.sh if need be, but you'll need at least amd64, arm64 and + maybe riscv (I don't have a good way to filter arches in this script yet, since + it's at an early state of development. + +(5) Build the kernel for at least arm64 and use it as an 'override'. I do this + by sudo -E make installkernel + DESTDIR=$HOME/stand-test-root/override/arm64-aarch64 TARGET=arm64 after + building the kernel. The script is designed to use kernels and binaries from + the latest CDs to do the testing, but has a way to override the kernel and + since we need to fix arm64... + +(6) You'll need to build the images. If you've done 1-5 correctly (and I've not + missed anything), then "cd /src; sh tools/boot/full-test.sh" will create + all the images and scripts to run qemu. There should be no errors, though + warnings about zfs.ko etc missing from powerpc is fine (and ignored by the + script already). + +(7) There will be a script to recreate this created in + $HOME/stand-test-root/scripts/arm64-aarch64/linuxboot-test.sh. Just run it with + 'sh'. And extra args are passed to qemu, so '-s -S' for gdb and + '-d trace:gicv3\* -D /tmp/gic.log' for verbose gic tracing (spaces are important). + +There's also a linuxboot-test-raw.sh which boots w/o EDK2+Linux.efi but loads +the kernel directly. and freebsd-test.sh which uses EDK2+loader.efi to boot FreeBSD +w/o kboot at all. diff --git a/tools/boot/full-test.sh b/tools/boot/full-test.sh new file mode 100644 index 000000000000..d8bc5d964f26 --- /dev/null +++ b/tools/boot/full-test.sh @@ -0,0 +1,575 @@ +#!/bin/sh + +# STAND_ROOT is the root of a tree: +# cache - Cached binaries that we have downloaded +# trees - binary trees that we use to make image +# trees/${ARCH}/$thing +# images - bootable images that we use to test +# images/${ARCH}/$thing +# bios - cached bios images (as well as 'vars' files when we start testing +# different booting scenarios in the precense / absence of variables). +# scripts - generated scripts that uses images to run the tests. +# +# Strategy: +# Download FreeBSD release isos, Linux kernels (for the kboot tests) and +# other misc things. We use these to generate dozens of test images that we +# use qemu-system-XXXX to boot. They all boot the same thing at the moment: +# an /etc/rc script that prints the boot method, echos success and then +# halts. + +# What version of FreeBSD to we snag the ISOs from to extract the binaries +# we are testing +FREEBSD_VERSION=13.1 +# eg https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-amd64-bootonly.iso.xz +URLBASE="https://download.freebsd.org/releases" +: ${STAND_ROOT:="${HOME}/stand-test-root"} +CACHE=${STAND_ROOT}/cache +TREES=${STAND_ROOT}/trees +IMAGES=${STAND_ROOT}/images +BIOS=${STAND_ROOT}/bios +SCRIPTS=${STAND_ROOT}/scripts +OVERRIDE=${STAND_ROOT}/override + +# hack -- I have extra junk in my qemu, but it's not needed to recreate things +if [ $(whoami) = imp ]; then + qemu_bin=/home/imp/git/qemu/00-build +else + qemu_bin=/usr/local/bin +fi + +# All the architectures under test +# Note: we can't yet do armv7 because we don't have a good iso for it and would +# need root to extract the files. +ARCHES="amd64:amd64 i386:i386 powerpc:powerpc powerpc:powerpc64 powerpc:powerpc64le powerpc:powerpcspe arm64:aarch64 riscv:riscv64" + +# The smallest FAT32 filesystem is 33292 KB +espsize=33292 + +SRCTOP=$(make -v SRCTOP) + +mkdir -p ${CACHE} ${TREES} ${IMAGES} ${BIOS} + +die() +{ + echo Fatal Error: $* + exit 1 +} + +ma_combo() +{ + local m=$1 + local ma=$2 + local ma_combo="${m}" + + [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}" + echo ${ma_combo} +} + +fetch_one() +{ + local m=$1 + local ma=$2 + local v=$3 + local flavor=$4 + local ma_combo=$(ma_combo $m $ma) + local file="FreeBSD-${v}-RELEASE-${ma_combo}-${flavor}" + local url="${URLBASE}/${m}/${ma}/ISO-IMAGES/${v}/${file}.xz" + + mkdir -p ${CACHE} + [ -r ${CACHE}/${file} ] && echo "Using cached ${file}" && return + cd ${CACHE} + echo "Fetching ${url}" + fetch ${url} || die "Can't fetch ${file} from ${url}" + xz -d ${file}.xz || die "Can't uncompress ${file}.xz" + cd .. +} + +update_freebsd_img_cache() +{ + local a m ma + + for a in $ARCHES; do + m=${a%%:*} + ma=${a##*:} + fetch_one $m $ma ${FREEBSD_VERSION} bootonly.iso + done + + fetch_one arm armv7 ${FREEBSD_VERSION} GENERICSD.img +} + +make_minimal_freebsd_tree() +{ + local m=$1 + local ma=$2 + local v=$3 + local flavor=$4 + local file d + local ma_combo="${m}" + [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}" + + file="FreeBSD-${v}-RELEASE-${ma_combo}-${flavor}" + dir=${TREES}/${ma_combo}/freebsd + rm -rf ${dir} + + # Make a super simple userland. It has just enough to print a santiy value, + # then say test succeeded, and then halt the system. We assume that /bin/sh + # has all the library prereqs for the rest... + mkdir -p ${dir} + # Make required dirs + for d in boot/kernel boot/defaults boot/lua boot/loader.conf.d \ + sbin bin lib libexec etc dev; do + mkdir -p ${dir}/${d} + done + # Pretend we don't have a separate /usr + ln -s . ${dir}/usr + # snag the binaries for my simple /etc/rc file + tar -C ${dir} -xf ${CACHE}/$file sbin/reboot sbin/halt sbin/init bin/sh sbin/sysctl \ + lib/libncursesw.so.9 lib/libc.so.7 lib/libedit.so.8 libexec/ld-elf.so.1 + + # My simple etc/rc + cat > ${dir}/etc/rc < ${dir}/boot.config + cat > ${dir}/boot/loader.conf < ${initrd}) + done +} + +make_linux_esps() +{ + # At the moment, we have just two + for a in amd64:amd64 arm64:aarch64; do + m=${a%%:*} + ma=${a##*:} + ma_combo="${m}" + [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}" + dir=${TREES}/${ma_combo}/linuxboot-esp + initrd=${TREES}/${ma_combo}/initrd.img + mkdir -p ${dir} + case ${ma} in + amd64) bin=x64 cons="console=ttyS0,115200" ;; + aarch64) bin=aa64 ;; + esac + mkdir -p ${dir}/efi/boot + cp ${CACHE}/linux/linux${bin}.efi ${dir} + cp ${CACHE}/linux/shell${bin}.efi ${dir}/efi/boot/boot${bin}.efi + cat > ${dir}/startup.nsh < ${out} < ${out} < ${out2} < ${out3} < ${out} < ${out} < ${out} <