Add loongarch64 as an optional boot-test.sh arch

D59889 brings up a FreeBSD/loongarch64 EFI loader, none of it in
this tree yet. Add a disabled config entry (excluded from -A, usable
via -a once the port lands) using the confirmed QEMU virt/la464
recipe; hw/loongarch/virt.c defaults to virtio-blk/net, so the
existing generic EFI+GPT builder needs no arch-specific QEMU code.

loongarch64 has never had a FreeBSD release, so
install_minimal_userland's ISO extraction can never find one. Split
it into ISO and installworld-cross-build paths, selected by a new
no_release capability, so archs without a release can still get a
minimal userland.

Differential Revision:	https://reviews.freebsd.org/D59923
This commit is contained in:
Warner Losh committed 2026-10-19 01:03:19 -06:00
1 parent ee96770ee3
commit 041802b362
2 files changed
+86 -27

No files matched your search

+12
View File
@@ -92,6 +92,18 @@
"target_arch": "powerpc64le", "target_arch": "powerpc64le",
"kernconf": "GENERIC64LE", "kernconf": "GENERIC64LE",
"timeout": 180 "timeout": 180
},
"loongarch64": {
"qemu_bin": "qemu-system-loongarch64",
"qemu_machine": "-machine virt",
"qemu_extra": "-cpu la464,ptw=on -smp 8 -device virtio-rng-pci",
"efi_firmware": "/usr/local/share/qemu/edk2-loongarch64-code.fd",
"efi_bootname": "bootloongarch64",
"caps": ["efi", "zfs", "no_release"],
"target": "loongarch",
"target_arch": "loongarch64",
"timeout": 120,
"disabled": true
} }
} }
} }
+74 -27
View File
@@ -20,7 +20,9 @@
# -a ARCH Architecture to test; repeat -a to test several # -a ARCH Architecture to test; repeat -a to test several
# (default: host arch) # (default: host arch)
# Supported: amd64, aarch64, armv7, riscv64, powerpc, powerpc64, # Supported: amd64, aarch64, armv7, riscv64, powerpc, powerpc64,
# powerpc64le # powerpc64le, loongarch64
# (loongarch64 is disabled/excluded from -A until the LoongArch
# port lands in-tree; usable directly via -a once it has)
# -A Test every supported architecture # -A Test every supported architecture
# -b Skip build/install phase (reuse existing tree) # -b Skip build/install phase (reuse existing tree)
# -B Skip build/install and image creation (reuse existing images) # -B Skip build/install and image creation (reuse existing images)
@@ -82,6 +84,9 @@ have_file() {
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Test whether the current arch declares a capability, e.g. "has efi". # Test whether the current arch declares a capability, e.g. "has efi".
# "no_release" is special: it means the arch has never had a FreeBSD
# release, so there's no ISO to pull a minimal userland from -- see
# install_minimal_userland_world().
has() { has() {
case " ${ARCH_CAPS} " in case " ${ARCH_CAPS} " in
*" $1 "*) return 0 ;; *" $1 "*) return 0 ;;
@@ -317,41 +322,83 @@ find_iso() {
die "No ISO found for ${ARCH}: ${isoname} not found" die "No ISO found for ${ARCH}: ${isoname} not found"
} }
install_minimal_userland() { # Paths (binaries + their libraries + rtld) to pull into DESTDIR for a minimal
# userland. Library *names* are discovered via ldd on the HOST's own copies of
# USERLAND_BINS: those paths (e.g. /lib/libc.so.7) are the same across
# architectures, only the file contents differ, so this works even when the
# files themselves are about to come from a foreign-arch source.
userland_extract_list() {
local host_bins=""
for b in ${USERLAND_BINS}; do
host_bins="${host_bins} /${b}"
done
local lib_paths=$(ldd ${host_bins} 2>/dev/null \
| awk 'NF == 4 { print $3 }' | sort -u)
local list=""
for b in ${USERLAND_BINS}; do
list="${list} ./${b}"
done
for l in ${lib_paths}; do
list="${list} .${l}"
done
list="${list} ./libexec/ld-elf.so.1"
# Some architectures (e.g., armv7) need libgcc_s.so.1 even though the host
# binaries don't. Always try to extract it. We'll ignore it if not there.
list="${list} ./lib/libgcc_s.so.1"
echo "${list}"
}
# Extract the minimal userland from a release ISO -- the normal path for any
# arch that has actually shipped a FreeBSD release.
install_minimal_userland_iso() {
# Split the declaration from the assignment: `local iso=$(find_iso)` would # Split the declaration from the assignment: `local iso=$(find_iso)` would
# swallow find_iso's exit status (local returns 0), so its die() -- which # swallow find_iso's exit status (local returns 0), so its die() -- which
# runs in the $() subshell -- would not stop this script. # runs in the $() subshell -- would not stop this script.
local iso local iso
iso=$(find_iso) || exit 1 iso=$(find_iso) || exit 1
echo " Extracting minimal userland from release ISO ${iso}..." echo " Extracting minimal userland from release ISO ${iso}..."
tar -C ${DESTDIR} -xf ${iso} $(userland_extract_list) \
# Determine library paths from host equivalents of our binaries
local host_bins=""
for b in ${USERLAND_BINS}; do
host_bins="${host_bins} /${b}"
done
lib_paths=$(ldd ${host_bins} 2>/dev/null \
| awk 'NF == 4 { print $3 }' | sort -u)
# Build the list of paths to extract: binaries + libraries + rtld
local extract_list=""
for b in ${USERLAND_BINS}; do
extract_list="${extract_list} ./${b}"
done
for l in ${lib_paths}; do
extract_list="${extract_list} .${l}"
done
extract_list="${extract_list} ./libexec/ld-elf.so.1"
# Some architectures (e.g., armv7) need libgcc_s.so.1 even though the host
# binaries don't. Always try to extract it. We'll ignore it if not there.
extract_list="${extract_list} ./lib/libgcc_s.so.1"
# Extract the files from the tarball.
tar -C ${DESTDIR} -xf ${iso} ${extract_list} \
>> ${LOGDIR}/installuserland.log 2>&1 || true >> ${LOGDIR}/installuserland.log 2>&1 || true
} }
# Cross-build the minimal userland via installworld instead of an ISO -- for
# architectures that have never had a FreeBSD release (no_release cap), so no
# ISO exists or ever will for the current version. Assumes buildworld has
# already been done for TARGET/TARGET_ARCH, same precondition build_tree
# already has for buildkernel.
install_minimal_userland_world() {
echo " Cross-installing minimal userland via installworld (no release for ${ARCH})..."
local worlddir=${OUTDIR}/world
rm -rf ${worlddir}
mkdir -p ${worlddir}
(cd ${SRCTOP} && ${MK} installworld \
DESTDIR=${worlddir} \
MK_MAN=no \
MK_TESTS=no \
MK_DEBUG_FILES=no \
MK_INSTALL_AS_USER=yes) > ${LOGDIR}/installworld.log 2>&1 \
|| die "installworld failed (see ${LOGDIR}/installworld.log)"
local item src
for item in $(userland_extract_list); do
src=${worlddir}/${item#.}
[ -f "${src}" ] || continue
mkdir -p ${DESTDIR}/$(dirname ${item#.})
cp -p ${src} ${DESTDIR}/${item#.}
done
rm -rf ${worlddir}
}
install_minimal_userland() {
if has no_release; then
install_minimal_userland_world
else
install_minimal_userland_iso
fi
}
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Phase 1: Build the boot tree # Phase 1: Build the boot tree
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------