3 # STAND_ROOT is the root of a tree:
4 # cache - Cached binaries that we have downloaded
5 # trees - binary trees that we use to make image
7 # images - bootable images that we use to test
8 # images/${ARCH}/$thing
9 # bios - cached bios images (as well as 'vars' files when we start testing
10 # different booting scenarios in the precense / absence of variables).
11 # scripts - generated scripts that uses images to run the tests.
14 # Download FreeBSD release isos, Linux kernels (for the kboot tests) and
15 # other misc things. We use these to generate dozens of test images that we
16 # use qemu-system-XXXX to boot. They all boot the same thing at the moment:
17 # an /etc/rc script that prints the boot method, echos success and then
20 # What version of FreeBSD to we snag the ISOs from to extract the binaries
23 # eg https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-amd64-bootonly.iso.xz
24 URLBASE="https://download.freebsd.org/releases"
25 : ${STAND_ROOT:="${HOME}/stand-test-root"}
26 CACHE=${STAND_ROOT}/cache
27 TREES=${STAND_ROOT}/trees
28 IMAGES=${STAND_ROOT}/images
29 BIOS=${STAND_ROOT}/bios
30 SCRIPTS=${STAND_ROOT}/scripts
31 OVERRIDE=${STAND_ROOT}/override
33 # hack -- I have extra junk in my qemu, but it's not needed to recreate things
34 if [ $(whoami) = imp ]; then
35 qemu_bin=/home/imp/git/qemu/00-build
37 qemu_bin=/usr/local/bin
40 # All the architectures under test
41 # Note: we can't yet do armv7 because we don't have a good iso for it and would
42 # need root to extract the files.
43 ARCHES="amd64:amd64 i386:i386 powerpc:powerpc powerpc:powerpc64 powerpc:powerpc64le powerpc:powerpcspe arm64:aarch64 riscv:riscv64"
45 # The smallest FAT32 filesystem is 33292 KB
48 SRCTOP=$(make -v SRCTOP)
50 mkdir -p ${CACHE} ${TREES} ${IMAGES} ${BIOS}
64 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
74 local ma_combo=$(ma_combo $m $ma)
75 local file="FreeBSD-${v}-RELEASE-${ma_combo}-${flavor}"
76 local url="${URLBASE}/${m}/${ma}/ISO-IMAGES/${v}/${file}.xz"
79 [ -r ${CACHE}/${file} ] && echo "Using cached ${file}" && return
81 echo "Fetching ${url}"
82 fetch ${url} || die "Can't fetch ${file} from ${url}"
83 xz -d ${file}.xz || die "Can't uncompress ${file}.xz"
87 update_freebsd_img_cache()
94 fetch_one $m $ma ${FREEBSD_VERSION} bootonly.iso
97 fetch_one arm armv7 ${FREEBSD_VERSION} GENERICSD.img
100 make_minimal_freebsd_tree()
107 local ma_combo="${m}"
108 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
110 file="FreeBSD-${v}-RELEASE-${ma_combo}-${flavor}"
111 dir=${TREES}/${ma_combo}/freebsd
114 # Make a super simple userland. It has just enough to print a santiy value,
115 # then say test succeeded, and then halt the system. We assume that /bin/sh
116 # has all the library prereqs for the rest...
119 for d in boot/kernel boot/defaults boot/lua boot/loader.conf.d \
120 sbin bin lib libexec etc dev; do
123 # Pretend we don't have a separate /usr
125 # snag the binaries for my simple /etc/rc file
126 tar -C ${dir} -xf ${CACHE}/$file sbin/reboot sbin/halt sbin/init bin/sh sbin/sysctl \
127 lib/libncursesw.so.9 lib/libc.so.7 lib/libedit.so.8 libexec/ld-elf.so.1
130 cat > ${dir}/etc/rc <<EOF
133 sysctl machdep.bootmethod
134 echo "RC COMMAND RUNNING -- SUCCESS!!!!!"
137 chmod +x ${dir}/etc/rc
139 # Check to see if we have overrides here... So we can insert our own kernel
140 # instead of the one from the release.
141 echo "CHECKING ${OVERRIDE}/${ma_combo}/boot"
142 if [ -d ${OVERRIDE}/${ma_combo}/boot ]; then
143 o=${OVERRIDE}/${ma_combo}
147 boot/kernel/acl_nfs4.ko \
148 boot/kernel/cryptodev.ko \
150 boot/kernel/geom_eli.ko; do
151 [ -r $o/$i ] && echo Copying override $i && cp $o/$i ${dir}/$i
154 # Copy the kernel (but not the boot loader, we'll add the one to test later)
155 # This will take care of both UFS and ZFS boots as well as geli
156 # Note: It's OK for device.hints to be missing. It's mostly for legacy platforms.
157 tar -C ${dir} -xf ${CACHE}/$file \
160 boot/kernel/acl_nfs4.ko \
161 boot/kernel/cryptodev.ko \
163 boot/kernel/geom_eli.ko || true
164 # XXX WHAT TO DO ABOUT LINKER HINTS -- PUNT FOR NOW
165 # XXX also, ZFS not supported on 32-bit powerpc platforms
168 # Setup some common settings for serial console, etc
169 echo -h -D -S115200 > ${dir}/boot.config
170 cat > ${dir}/boot/loader.conf <<EOF
171 comconsole_speed=115200
175 kern.cfg.order="acpi,fdt"
179 make_freebsd_minimal_trees()
184 make_minimal_freebsd_tree $m $ma ${FREEBSD_VERSION} bootonly.iso
186 # Note: armv7 isn't done yet as its the odd-man out -- we need to extract things
187 # in a special way, so punt for the moment
190 make_freebsd_test_trees()
196 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
197 dir=${TREES}/${ma_combo}/test-stand
199 mtree -deUW -f ${SRCTOP}/etc/mtree/BSD.root.dist -p ${dir}
200 echo "Creating tree for ${m}:${ma}"
202 # Indirection needed because our build system is too complex
203 # SHELL="make clean" make buildenv TARGET=${m} TARGET_ARCH=${ma}
204 SHELL="make -j 100 all" make buildenv TARGET=${m} TARGET_ARCH=${ma}
205 SHELL="make install DESTDIR=${dir} MK_MAN=no MK_INSTALL_AS_USER=yes WITHOUT_DEBUG_FILES=yes" \
206 make buildenv TARGET=${m} TARGET_ARCH=${ma}
207 rm -rf ${dir}/bin ${dir}/[ac-z]* # Don't care about anything here
213 # At the moment, we have just two
214 for a in amd64:amd64 arm64:aarch64; do
218 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
219 dir=${TREES}/${ma_combo}/linuxboot
220 dir2=${TREES}/${ma_combo}/test-stand
221 dir3=${TREES}/${ma_combo}/freebsd
222 initrd=${TREES}/${ma_combo}/initrd.img
225 cp ${dir2}/boot/loader.kboot ${dir}/init
226 # Copy the boot loader
227 tar -c -f - -C ${dir2} boot | tar -xf - -C ${dir}
228 # Copy the boot kernel
229 tar -c -f - -C ${dir3} boot | tar -xf - -C ${dir}
230 (cd ${dir} ; find . | LC_ALL=C sort | cpio -o -H newc | gzip > ${initrd})
236 # At the moment, we have just two
237 for a in amd64:amd64 arm64:aarch64; do
241 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
242 dir=${TREES}/${ma_combo}/linuxboot-esp
243 initrd=${TREES}/${ma_combo}/initrd.img
246 amd64) bin=x64 cons="console=ttyS0,115200" ;;
249 mkdir -p ${dir}/efi/boot
250 cp ${CACHE}/linux/linux${bin}.efi ${dir}
251 cp ${CACHE}/linux/shell${bin}.efi ${dir}/efi/boot/boot${bin}.efi
252 cat > ${dir}/startup.nsh <<EOF
254 # Tell it to run with out special initrd that then boot FreeBSD
256 \linux${bin} ${cons} initrd=\initrd.img
262 make_linuxboot_images()
264 # ESP variant: In this variant, amd64 and arm64 are both created more or
265 # less the same way. Both are EFI + ACPI implementations
266 for a in amd64:amd64 arm64:aarch64; do
270 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
271 src=${TREES}/${ma_combo}/linuxboot-esp
272 dir=${TREES}/${ma_combo}/freebsd
273 dir2=${TREES}/${ma_combo}/test-stand
274 esp=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}.esp
275 ufs=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}.ufs
276 zfs=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}.zfs
277 img=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}.img
278 img2=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}-zfs.img
280 mkdir -p ${IMAGES}/${ma_combo}
281 makefs -t msdos -o fat_type=32 -o sectors_per_cluster=1 \
282 -o volume_label=EFISYS -s80m ${esp} ${src}
283 makefs -t ffs -B little -s 200m -o label=root ${ufs} ${dir} ${dir2}
284 mkimg -s gpt -p efi:=${esp} -p freebsd-ufs:=${ufs} -o ${img}
285 makefs -t zfs -s 200m \
286 -o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
287 ${zfs} ${dir} ${dir2}
290 -p freebsd-zfs:=${zfs} -o ${img2}
291 rm -f ${esp} # Don't need to keep this around
294 # The raw variant, currently used only on arm64. It boots with the raw interface of qemu
295 # for testing purposes. This means it makes a good test for the DTB variation, but not ACPI
296 # since qemu doesn't currently provide that...
297 for a in arm64:aarch64; do
301 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
302 linux="${CACHE}/linux/vmlinux-${m}*"
303 initrd=${TREES}/${ma_combo}/initrd.img
304 img=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}-raw
305 cp ${linux} ${img}.kernel
306 cp ${initrd} ${img}.initrd
310 make_linuxboot_scripts()
312 # At the moment, we have just two -- and the images we've built so far are just
313 # the hostfs boot. The boot off anything more complex isn't here.
314 for a in amd64:amd64 arm64:aarch64; do
318 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
320 # First off, update the edk firmware
321 bios_code=${BIOS}/edk2-${ma_combo}-code.fd
322 bios_vars=${BIOS}/edk2-${ma_combo}-vars.fd
325 if [ ${bios_code} -ot /usr/local/share/qemu/edk2-x86_64-code.fd ]; then
326 cp /usr/local/share/qemu/edk2-x86_64-code.fd ${bios_code}
327 # vars file works on both 32 and 64 bit x86
328 cp /usr/local/share/qemu/edk2-i386-vars.fd ${bios_vars}
332 if [ ${bios_code} -ot /usr/local/share/qemu/edk2-aarch64-code.fd ]; then
333 # aarch64 vars starts as an empty file
334 dd if=/dev/zero of=${bios_code} bs=1M count=64
335 dd if=/dev/zero of=${bios_vars} bs=1M count=64
336 dd if=/usr/local/share/qemu/edk2-aarch64-code.fd of=${bios_code} conv=notrunc
341 # Now make me a script
342 img=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}.img
343 img2=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}-raw
344 img3=${IMAGES}/${ma_combo}/linuxboot-${ma_combo}-zfs.img
345 out=${SCRIPTS}/${ma_combo}/linuxboot-test.sh
346 out2=${SCRIPTS}/${ma_combo}/linuxboot-test-raw.sh
347 out3=${SCRIPTS}/${ma_combo}/linuxboot-test-zfs.sh
348 cd=${CACHE}/FreeBSD-13.1-RELEASE-arm64-aarch64-bootonly.iso
349 mkdir -p ${SCRIPTS}/${ma_combo}
353 ${qemu_bin}/qemu-system-x86_64 -nographic -m 512M \\
354 -drive file=${img},if=none,id=drive0,cache=writeback,format=raw \\
355 -device virtio-blk,drive=drive0,bootindex=0 \\
356 -drive file=${bios_code},format=raw,if=pflash \\
357 -drive file=${bios_vars},format=raw,if=pflash \\
358 -monitor telnet::4444,server,nowait \\
364 raw=${IMAGES}/${ma_combo}/freebsd-arm64-aarch64.img
366 ${qemu_bin}/qemu-system-aarch64 -nographic -machine virt,gic-version=3 -m 512M -smp 4 \\
368 -drive file=${img},if=none,id=drive0,cache=writeback \\
369 -device virtio-blk,drive=drive0,bootindex=0 \\
370 -drive file=${raw},if=none,id=drive1,cache=writeback \\
371 -device nvme,serial=fboot,drive=drive1,bootindex=1 \\
372 -drive file=${bios_code},format=raw,if=pflash \\
373 -drive file=${bios_vars},format=raw,if=pflash \\
374 -monitor telnet::4444,server,nowait \\
378 # Note: We have to use cortex-a57 for raw mode because the
379 # kernel we use has issues with max.
381 ${qemu_bin}/qemu-system-aarch64 -m 1024 -cpu cortex-a57 -M virt \\
382 -kernel ${img2}.kernel -initrd ${img2}.initrd \\
383 -append "console=ttyAMA0" \\
384 -drive file=${cd},if=none,id=drive0,cache=writeback,format=raw \\
385 -device virtio-blk,drive=drive0,bootindex=0 \\
386 -nographic -monitor telnet::4444,server,nowait \\
390 # Note: We have to use cortex-a57 for raw mode because the
391 # kernel we use has issues with max.
393 ${qemu_bin}/qemu-system-aarch64 -nographic -machine virt,gic-version=3 -m 512M -smp 4 \\
395 -drive file=${img3},if=none,id=drive0,cache=writeback \\
396 -device virtio-blk,drive=drive0,bootindex=0 \\
397 -drive file=${bios_code},format=raw,if=pflash \\
398 -drive file=${bios_vars},format=raw,if=pflash \\
399 -monitor telnet::4444,server,nowait \\
409 # At the moment, we have just three (armv7 could also be here too, but we're not doing that)
410 for a in amd64:amd64 arm64:aarch64 riscv:riscv64; do
414 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
415 dir=${TREES}/${ma_combo}/freebsd-esp
416 dir2=${TREES}/${ma_combo}/test-stand
423 mkdir -p ${dir}/efi/boot
424 cp ${dir2}/boot/loader.efi ${dir}/efi/boot/boot${bin}.efi
428 make_freebsd_images()
430 # ESP variant: In this variant, riscv, amd64 and arm64 are created more or
431 # less the same way. UEFI + ACPI implementations
432 for a in amd64:amd64 arm64:aarch64 riscv:riscv64; do
436 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
437 src=${TREES}/${ma_combo}/freebsd-esp
438 dir=${TREES}/${ma_combo}/freebsd
439 dir2=${TREES}/${ma_combo}/test-stand
440 esp=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.esp
441 ufs=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.ufs
442 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
443 mkdir -p ${IMAGES}/${ma_combo}
445 cat > ${dir2}/etc/fstab <<EOF
446 /dev/ufs/root / ufs rw 1 1
448 makefs -t msdos -o fat_type=32 -o sectors_per_cluster=1 \
449 -o volume_label=EFISYS -s100m ${esp} ${src}
450 makefs -t ffs -B little -s 200m -o label=root ${ufs} ${dir} ${dir2}
451 mkimg -s gpt -p efi:=${esp} -p freebsd-ufs:=${ufs} -o ${img}
452 # rm -f ${esp} ${ufs} # Don't need to keep this around
462 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
463 dir=${TREES}/${ma_combo}/freebsd
464 dir2=${TREES}/${ma_combo}/test-stand
465 ufs=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.ufs
466 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
467 mkdir -p ${IMAGES}/${ma_combo}
469 cat > ${dir2}/etc/fstab <<EOF
470 /dev/ufs/root / ufs rw 1 1
472 makefs -t ffs -B little -s 200m \
473 -o label=root,version=2,bsize=32768,fsize=4096,density=16384 \
474 ${ufs} ${dir} ${dir2}
475 mkimg -s gpt -b ${dir2}/boot/pmbr \
476 -p freebsd-boot:=${dir2}/boot/gptboot \
477 -p freebsd-ufs:=${ufs} \
479 rm -f ${src}/etc/fstab
481 # PowerPC for 32-bit mac
486 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
487 dir=${TREES}/${ma_combo}/freebsd
488 dir2=${TREES}/${ma_combo}/test-stand
489 ufs=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.ufs
490 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
491 mkdir -p ${IMAGES}/${ma_combo}
493 cat > ${dir2}/etc/fstab <<EOF
494 /dev/ufs/root / ufs rw 1 1
496 makefs -t ffs -B big -s 200m \
497 -o label=root,version=2,bsize=32768,fsize=4096,density=16384 \
498 ${ufs} ${dir} ${dir2}
500 -p freebsd-boot:=${dir2}/boot/boot1.hfs \
501 -p freebsd-ufs:=${ufs} \
507 make_freebsd_scripts()
509 # At the moment, we have just two
510 for a in amd64:amd64 arm64:aarch64; do
514 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
516 # First off, update the edk firmware
517 bios_code=${BIOS}/edk2-${ma_combo}-code.fd
518 bios_vars=${BIOS}/edk2-${ma_combo}-vars.fd
521 if [ ${bios_code} -ot /usr/local/share/qemu/edk2-x86_64-code.fd ]; then
522 cp /usr/local/share/qemu/edk2-x86_64-code.fd ${bios_code}
523 # vars file works on both 32 and 64 bit x86
524 cp /usr/local/share/qemu/edk2-i386-vars.fd ${bios_vars}
528 if [ ${bios_code} -ot /usr/local/share/qemu/edk2-aarch64-code.fd ]; then
529 # aarch64 vars starts as an empty file
530 dd if=/dev/zero of=${bios_code} bs=1M count=64
531 dd if=/dev/zero of=${bios_vars} bs=1M count=64
532 dd if=/usr/local/share/qemu/edk2-aarch64-code.fd of=${bios_code} conv=notrunc
537 # Now make me a script
538 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
539 out=${SCRIPTS}/${ma_combo}/freebsd-test.sh
540 mkdir -p ${SCRIPTS}/${ma_combo}
544 ${qemu_bin}/qemu-system-x86_64 -nographic -m 512M \\
545 -drive file=${img},if=none,id=drive0,cache=writeback,format=raw \\
546 -device virtio-blk,drive=drive0,bootindex=0 \\
547 -drive file=${bios_code},format=raw,if=pflash \\
548 -drive file=${bios_vars},format=raw,if=pflash \\
549 -monitor telnet::4444,server,nowait \\
555 raw=${IMAGES}/${ma_combo}/nvme-test-empty.raw
557 ${qemu_bin}/qemu-system-aarch64 -nographic -machine virt,gic-version=3 -m 512M \\
558 -cpu cortex-a57 -drive file=${img},if=none,id=drive0,cache=writeback -smp 4 \\
559 -device virtio-blk,drive=drive0,bootindex=0 \\
560 -drive file=${bios_code},format=raw,if=pflash \\
561 -drive file=${bios_vars},format=raw,if=pflash \\
562 -drive file=${raw},if=none,id=drive1,cache=writeback,format=raw \\
563 -device nvme,serial=deadbeef,drive=drive1 \\
564 -monitor telnet::4444,server,nowait \\
576 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
577 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
578 out=${SCRIPTS}/${ma_combo}/freebsd-test.sh
579 mkdir -p ${SCRIPTS}/${ma_combo}
581 ${qemu_bin}/qemu-system-ppc -m 1g -M mac99,via=pmu \\
582 -vga none -nographic \\
583 -drive file=${img},if=virtio \\
584 -prom-env "boot-device=/pci@f2000000/scsi/disk@0:,\\\\\\:tbxi" \\
585 -monitor telnet::4444,server,nowait \\
594 [ "${m}" != "${ma}" ] && ma_combo="${m}-${ma}"
595 img=${IMAGES}/${ma_combo}/freebsd-${ma_combo}.img
596 out=${SCRIPTS}/${ma_combo}/freebsd-test.sh
597 mkdir -p ${SCRIPTS}/${ma_combo}
599 ${qemu_bin}/qemu-system-i386 -m 1g \\
600 -vga none -nographic \\
601 -drive file=${img},format=raw \\
603 -monitor telnet::4444,server,nowait \\
608 # The smallest FAT32 filesystem is 33292 KB
612 echo "src/stand test in ${STAND_ROOT}"
613 update_freebsd_img_cache
614 make_freebsd_minimal_trees
615 make_freebsd_test_trees
621 make_linuxboot_images
622 make_linuxboot_scripts