First look for firmware files in the source directory and then, if not found, look for them in locations where Debian installs them. Prefer to use the unified firmware file and, if not found, use the pflash firmware files split in to code and variables. By looking for files in the source directory first, system firmware files can be overridden and it can be ensured that the tests can be run regardless of the distro or where the system firmware files are stored. If no firmware files are found, print an error message and exit with error. If a firmware VARS file is found, use it with snapshot mode enabled, which makes the VARS writable to the virtual machine, but does not write back the changes to the file. This allows using the readonly system VARS file without copying it or using it in readonly mode, which causes the ARM machine to fail. This also gives tests effectively their own ephemeral VARS file that can be written to without causing side-effects for other tests. Signed-off-by: Glenn Washburn <development@efficientek.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
718 lines
21 KiB
Plaintext
718 lines
21 KiB
Plaintext
#! @BUILD_SHEBANG@
|
|
set -e
|
|
|
|
# Run GRUB script in a Qemu instance
|
|
# Copyright (C) 2009,2010 Free Software Foundation, Inc.
|
|
#
|
|
# GRUB is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# GRUB is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Initialize some variables.
|
|
prefix="@prefix@"
|
|
exec_prefix="@exec_prefix@"
|
|
datarootdir="@datarootdir@"
|
|
builddir="@builddir@"
|
|
srcdir="@srcdir@"
|
|
PACKAGE_NAME=@PACKAGE_NAME@
|
|
PACKAGE_TARNAME=@PACKAGE_TARNAME@
|
|
PACKAGE_VERSION=@PACKAGE_VERSION@
|
|
|
|
# Force build directory components
|
|
PATH="${builddir}:$PATH"
|
|
export PATH
|
|
|
|
trim=0
|
|
trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c
|
|
|
|
# Usage: usage
|
|
# Print the usage.
|
|
usage () {
|
|
cat <<EOF
|
|
Usage: $0 [OPTION] [SOURCE]
|
|
Run GRUB script in a Qemu instance.
|
|
|
|
-h, --help print this message and exit
|
|
-v, --version print the version information and exit
|
|
--boot=[fd|hd|cd|net] boot method for Qemu instance
|
|
--modules=MODULES pre-load specified modules MODULES
|
|
--qemu=FILE Name of qemu binary
|
|
--disk=FILE Attach FILE as a disk
|
|
--qemu-opts=OPTIONS extra options to pass to Qemu instance
|
|
--files=FILES add files to the image
|
|
--mkrescue-arg=ARGS additional arguments to grub-mkrescue
|
|
--timeout=SECONDS set timeout
|
|
--trim trim firmware output
|
|
|
|
$0 runs input GRUB script or SOURCE file in a Qemu instance and prints
|
|
its output.
|
|
|
|
Report bugs to <bug-grub@gnu.org>.
|
|
EOF
|
|
}
|
|
|
|
# Exec given argv and only show its output on STDERR if it returns an
|
|
# error status.
|
|
exec_show_error () {
|
|
v=`$@ 2>&1`
|
|
ret=$?
|
|
if [ "$ret" != 0 ]; then
|
|
echo "$v" >&2
|
|
exit $ret
|
|
fi
|
|
}
|
|
|
|
work_directory=${WORKDIR:-`mktemp -d "${TMPDIR:-/tmp}/grub-shell.XXXXXXXXXX"`} || exit 1
|
|
|
|
. "${builddir}/grub-core/modinfo.sh"
|
|
qemuopts=
|
|
serial_port=com0
|
|
serial_null=
|
|
halt_cmd=halt
|
|
pseries=n
|
|
disk="hda "
|
|
case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
|
|
*-emu)
|
|
device_map="$work_directory/device.map"
|
|
boot=emu
|
|
console=console
|
|
disk=0
|
|
# To skip "Welcome to GRUB" and color setttings
|
|
trim=1
|
|
serial_port=
|
|
;;
|
|
powerpc-ieee1275)
|
|
boot=hd
|
|
qemu=qemu-system-ppc
|
|
console=console
|
|
serial_port=escc-ch-b
|
|
serial_null="-serial null"
|
|
netbootext=elf
|
|
trim=1
|
|
qemuopts="-M mac99,via=pmu $qemuopts"
|
|
;;
|
|
|
|
sparc64-ieee1275)
|
|
boot=cd
|
|
qemu=qemu-system-sparc64
|
|
console=
|
|
serial_port=ieee1275/ttya
|
|
trim=1
|
|
qemuopts="$qemuopts -no-reboot"
|
|
halt_cmd=reboot
|
|
;;
|
|
|
|
mips-qemu_mips)
|
|
boot=mips_qemu
|
|
qemu=qemu-system-mips
|
|
qemuopts="-M mips $qemuopts"
|
|
console=vga_text
|
|
;;
|
|
mips-arc)
|
|
boot=cd
|
|
qemu=qemu-system-mips64
|
|
qemuopts="-M indy $qemuopts"
|
|
serial_port=arc/serial0/line0
|
|
console=
|
|
trim=1
|
|
;;
|
|
mipsel-arc)
|
|
boot=cd
|
|
qemu=qemu-system-mips64el
|
|
qemuopts="-M magnum $qemuopts -no-reboot"
|
|
serial_port=arc/multi0/serial0
|
|
console=console
|
|
halt_cmd=reboot
|
|
trim=1
|
|
;;
|
|
mipsel-qemu_mips)
|
|
boot=mipsel_qemu
|
|
qemu=qemu-system-mipsel
|
|
qemuopts="-M mips $qemuopts"
|
|
console=vga_text
|
|
;;
|
|
mipsel-loongson)
|
|
boot=mipsel_fulong2e
|
|
qemu=qemu-system-mips64el
|
|
qemuopts="-M fulong2e $qemuopts"
|
|
console=
|
|
trim=1
|
|
;;
|
|
i386-coreboot)
|
|
boot=coreboot
|
|
qemu=qemu-system-i386
|
|
console=vga_text
|
|
;;
|
|
i386-multiboot)
|
|
boot=cd
|
|
qemu=qemu-system-i386
|
|
console=vga_text;;
|
|
|
|
i386-ieee1275)
|
|
boot=hd
|
|
qemu=qemu-system-i386
|
|
console=console
|
|
trim=1
|
|
disk="hdb "
|
|
;;
|
|
i386-qemu)
|
|
boot=qemu
|
|
qemu=qemu-system-i386
|
|
console=vga_text;;
|
|
|
|
i386-pc)
|
|
boot=cd
|
|
qemu=qemu-system-i386
|
|
console=console
|
|
netbootext=0
|
|
;;
|
|
|
|
i386-efi)
|
|
qemu=qemu-system-i386
|
|
boot=cd
|
|
console=console
|
|
trim=1
|
|
pflash=${srcdir}/OVMF32.fd
|
|
pflash_code=${srcdir}/OVMF32_CODE.fd
|
|
pflash_vars=${srcdir}/OVMF32_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
if [ -f "$pflash_vars" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
fi
|
|
else
|
|
pflash=/usr/share/qemu/OVMF32.fd
|
|
pflash_code=/usr/share/OVMF/OVMF32_CODE_4M.secboot.fd
|
|
pflash_vars=/usr/share/OVMF/OVMF32_VARS_4M.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
else
|
|
echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
qemuopts="-machine q35 $qemuopts"
|
|
;;
|
|
x86_64-efi)
|
|
qemu=qemu-system-x86_64
|
|
boot=cd
|
|
console=console
|
|
trim=1
|
|
pflash=${srcdir}/OVMF.fd
|
|
pflash_code=${srcdir}/OVMF_CODE.fd
|
|
pflash_vars=${srcdir}/OVMF_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
if [ -f "$pflash_vars" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
fi
|
|
else
|
|
pflash=/usr/share/qemu/OVMF.fd
|
|
pflash_code=/usr/share/OVMF/OVMF_CODE.fd
|
|
pflash_vars=/usr/share/OVMF/OVMF_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
else
|
|
echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
;;
|
|
arm64-efi)
|
|
qemu=qemu-system-aarch64
|
|
boot=hd
|
|
console=console
|
|
trim=1
|
|
pflash=${srcdir}/AAVMF.fd
|
|
pflash_code=${srcdir}/AAVMF_CODE.fd
|
|
pflash_vars=${srcdir}/AAVMF_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
if [ -f "$pflash_vars" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
fi
|
|
else
|
|
pflash=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd
|
|
pflash_code=/usr/share/AAVMF/AAVMF_CODE.fd
|
|
pflash_vars=/usr/share/AAVMF/AAVMF_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
else
|
|
echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
qemuopts="-machine virt -cpu cortex-a57 $qemuopts"
|
|
disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
|
|
serial_port=
|
|
;;
|
|
arm-efi)
|
|
qemu=qemu-system-arm
|
|
boot=hd
|
|
console=console
|
|
trim=1
|
|
pflash=${srcdir}/AAVMF32.fd
|
|
pflash_code=${srcdir}/AAVMF32_CODE.fd
|
|
pflash_vars=${srcdir}/AAVMF32_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
if [ -f "$pflash_vars" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
fi
|
|
else
|
|
pflash=/usr/share/AAVMF/AAVMF32.fd
|
|
pflash_code=/usr/share/AAVMF/AAVMF32_CODE.fd
|
|
pflash_vars=/usr/share/AAVMF/AAVMF32_VARS.fd
|
|
if [ -f "$pflash" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts"
|
|
elif [ -f "$pflash_code" ]; then
|
|
qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts"
|
|
qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts"
|
|
else
|
|
echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
qemuopts="-machine virt $qemuopts"
|
|
disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
|
|
serial_port=efi0
|
|
;;
|
|
loongarch64-efi)
|
|
qemu=qemu-system-loongarch64
|
|
boot=hd
|
|
console=console
|
|
trim=1
|
|
qemuopts="-machine virt -cpu la464-loongarch-cpu -smp 4 -nographic -m 3G \
|
|
-bios QEMU_EFI.fd -L ${srcdir} -L /usr/share/edk2/loongarch64 \
|
|
-L /usr/share/qemu-efi-loongarch64 $qemuopts"
|
|
disk="device virtio-blk-pci,drive=hd1 -drive if=none,id=hd1,file="
|
|
serial_port=
|
|
;;
|
|
*)
|
|
boot=hd
|
|
qemu=qemu-system-i386
|
|
console=console;;
|
|
esac
|
|
|
|
case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
|
|
# Only add the RNG device for EFI platforms because we currently only
|
|
# support Stack Smashing protection on EFI.
|
|
*-efi)
|
|
qemuopts="$qemuopts -device virtio-rng-pci" ;;
|
|
esac
|
|
|
|
timeout=${GRUB_SHELL_DEFAULT_TIMEOUT:-60}
|
|
mkimage_extra_arg=
|
|
debug=${GRUB_SHELL_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG}
|
|
|
|
# Check the arguments.
|
|
for option in "$@"; do
|
|
case "$option" in
|
|
-h | --help)
|
|
usage
|
|
exit 0 ;;
|
|
-v | --version)
|
|
echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
|
|
exit 0 ;;
|
|
--trim)
|
|
trim=1 ;;
|
|
--trim=*)
|
|
trim=2
|
|
trim_head=`echo "$option" | sed -e 's/--trim=//' -e 's/,/ /g'`
|
|
;;
|
|
--no-trim)
|
|
trim=0 ;;
|
|
--debug)
|
|
debug=$((debug+1)) ;;
|
|
--debug=*)
|
|
debug=$((`echo "$option" | sed -e 's/--debug=//'`)) ;;
|
|
--modules=*)
|
|
ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'`
|
|
modules="$modules $ms" ;;
|
|
--files=*)
|
|
fls=`echo "$option" | sed -e 's/--files=//' -e 's/,/ /g'`
|
|
files="$files $fls" ;;
|
|
--mkrescue-arg=*)
|
|
mkr=`echo "$option" | sed -e 's/--mkrescue-arg=//' -e 's/,/ /g'`
|
|
mkrescue_args="$mkrescue_args $mkr" ;;
|
|
--pseries)
|
|
qemu=qemu-system-ppc64
|
|
serial_port=ieee1275/hvterm
|
|
serial_null=
|
|
qemuopts="$(echo $qemuopts | sed -E 's/-M [^ ]+//') -M pseries -no-reboot"
|
|
trim=1
|
|
pseries=y
|
|
;;
|
|
--serial=*)
|
|
serial_port=`echo "$option" | sed -e 's/--serial=//'`;;
|
|
--qemu=*)
|
|
qemu=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;;
|
|
--qemu-opts=*)
|
|
qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
|
|
qemuopts="$qemuopts $qs" ;;
|
|
--disk=*)
|
|
dsk=`echo "$option" | sed -e 's/--disk=//'`
|
|
if [ ${grub_modinfo_platform} = emu ]; then
|
|
echo "(hd$disk) $dsk" >> "$device_map"
|
|
disk="$((disk+1))"
|
|
else
|
|
if [ "$disk" = error ]; then
|
|
echo "Too many disks" 1>&2
|
|
exit 1;
|
|
fi
|
|
qemuopts="$qemuopts -$disk$dsk"
|
|
if [ "$disk" = "hda " ]; then
|
|
disk="hdb ";
|
|
elif [ "$disk" = "hdb " ]; then
|
|
# CDROM is hdc
|
|
disk="hdd "
|
|
elif [ "$disk" = "hdd " ]; then
|
|
# CDROM is hdc
|
|
disk=error
|
|
fi
|
|
fi
|
|
;;
|
|
--timeout=*)
|
|
timeout=`echo "$option" | sed -e 's/--timeout=//'`
|
|
;;
|
|
|
|
# Intentionally undocumented
|
|
--grub-mkimage-extra)
|
|
mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
|
|
--grub-mkimage-extra=*)
|
|
mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
|
|
|
|
--boot=*)
|
|
dev=`echo "$option" | sed -e 's/--boot=//'`
|
|
if [ "$dev" = "fd" ] ; then boot=fd;
|
|
elif [ "$dev" = "hd" ] ; then boot=hd;
|
|
elif [ "$dev" = "cd" ] ; then boot=cd;
|
|
elif [ "$dev" = "net" ] ; then boot=net;
|
|
elif [ "$dev" = "qemu" ] ; then boot=qemu;
|
|
elif [ "$dev" = "coreboot" ] ; then boot=coreboot;
|
|
elif [ "$dev" = "mips_qemu" ] ; then boot=mips_qemu;
|
|
elif [ "$dev" = "mipsel_qemu" ] ; then boot=mipsel_qemu;
|
|
elif [ "$dev" = "mipsel_fulong2e" ] ; then boot=mipsel_fulong2e;
|
|
else
|
|
echo "Unrecognized boot method \`$dev'" 1>&2
|
|
usage
|
|
exit 1
|
|
fi ;;
|
|
-*)
|
|
echo "Unrecognized option \`$option'" 1>&2
|
|
usage
|
|
exit 1 ;;
|
|
*)
|
|
if [ "x${source}" != x ] ; then
|
|
echo "too many parameters at the end" 1>&2
|
|
usage
|
|
exit 1
|
|
fi
|
|
source="${option}" ;;
|
|
esac
|
|
done
|
|
|
|
[ "${debug:-0}" -gt 1 ] && set -x
|
|
|
|
if [ "x${source}" = x ] ; then
|
|
tmpfile="$work_directory/testcase.cfg"
|
|
while read REPLY; do
|
|
echo "$REPLY" >> ${tmpfile}
|
|
done
|
|
source=${tmpfile}
|
|
fi
|
|
|
|
cfgfile="$work_directory/grub.cfg"
|
|
cat <<EOF >${cfgfile}
|
|
grubshell=yes
|
|
halt_cmd=${halt_cmd}
|
|
export halt_cmd
|
|
enable_progress_indicator=0
|
|
export enable_progress_indicator
|
|
if [ "${grub_modinfo_platform}" == efi ]; then
|
|
gdbinfo
|
|
fi
|
|
EOF
|
|
|
|
|
|
if [ "${grub_modinfo_platform}" != emu ]; then
|
|
echo insmod serial >>${cfgfile}
|
|
fi
|
|
|
|
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ]; then
|
|
echo insmod escc >>${cfgfile}
|
|
fi
|
|
if [ "${serial_port}" != "" ]; then
|
|
echo "serial ${serial_port}" >>${cfgfile}
|
|
term="serial_${serial_port}"
|
|
else
|
|
term=console
|
|
fi
|
|
|
|
cat <<EOF >>${cfgfile}
|
|
terminfo -g 1024x1024 ${term} dumb
|
|
terminal_input ${term}
|
|
terminal_output ${term}
|
|
EOF
|
|
|
|
if [ $trim = 1 ]; then
|
|
echo "echo; echo $trim_head" >>${cfgfile}
|
|
fi
|
|
|
|
rom_directory="$work_directory/rom_directory"
|
|
mkdir -p "$rom_directory"
|
|
|
|
for mod in ${modules}
|
|
do
|
|
echo "insmod ${mod}" >> ${cfgfile}
|
|
done
|
|
|
|
cat <<EOF >>${cfgfile}
|
|
source "\$prefix/testcase.cfg"
|
|
# Stop serial output to suppress "ACPI shutdown failed" error.
|
|
EOF
|
|
# Attempt to switch to console on i386-ieee1275 causes "screen not found" message
|
|
if [ x$console != x ] && [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != xi386-ieee1275 ]; then
|
|
echo "terminal_output $console" >>${cfgfile}
|
|
fi
|
|
echo "${halt_cmd}" >>${cfgfile}
|
|
|
|
test -z "$debug" || echo "GRUB script: ${cfgfile}" >&2
|
|
test -z "$debug" || echo "GRUB testcase script: ${tmpfile}" >&2
|
|
|
|
goutfile="$work_directory/grub-qemu.log"
|
|
test -z "$debug" || echo "GRUB output log: ${goutfile}" >&2
|
|
test -z "$debug" || echo "Boot device: ${boot}" >&2
|
|
|
|
isofile="$work_directory/grub.iso"
|
|
test -z "$debug" || echo "GRUB ISO file: ${isofile}" >&2
|
|
test -z "$debug" || echo "GRUB ROM directory: ${rom_directory}" >&2
|
|
|
|
if test -z "$debug"; then
|
|
qemuopts="${qemuopts} -nographic -monitor file:/dev/null"
|
|
# SeaBIOS 1.11.0 added support for VGA emulation over a serial port. If
|
|
# this is configured in SeaBIOS, then -nographic causes some extra junk to
|
|
# end up on the serial console, which interferes with our tests. This
|
|
# workaround unfortunately causes qemu to issue a warning 'externally
|
|
# provided fw_cfg item names should be prefixed with "opt/"', but there
|
|
# doesn't seem to be a better option.
|
|
#
|
|
# SeaBIOS is used for i386, except on EFI.
|
|
if [ ${grub_modinfo_target_cpu} == 'i386' ] && [ ${grub_modinfo_platform} != 'efi' ]; then
|
|
qemuopts="${qemuopts} -fw_cfg name=etc/sercon-port,string=0"
|
|
fi
|
|
fi
|
|
|
|
if [ x$boot != xnet ] && [ x$boot != xemu ]; then
|
|
pkgdatadir="${builddir}" \
|
|
exec_show_error "${builddir}/grub-mkrescue" \
|
|
${debug:+$([ "$debug" -gt 2 ] && echo -n "--verbose")} \
|
|
"--output=${isofile}" \
|
|
"--override-directory=${builddir}/grub-core" \
|
|
--rom-directory="${rom_directory}" \
|
|
--locale-directory="${srcdir}/po" \
|
|
--themes-directory="${srcdir}/themes" \
|
|
$mkimage_extra_arg ${mkrescue_args} \
|
|
"/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
|
|
${files} || exit $?
|
|
fi
|
|
if [ x$boot = xhd ]; then
|
|
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then
|
|
device="device virtio-blk-device,drive=hd0 -drive if=none,id=hd0,file="
|
|
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = loongarch64-efi ]; then
|
|
device="device virtio-blk-pci,drive=grubdisk -drive if=none,id=grubdisk,file="
|
|
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc ]; then
|
|
device="hdb "
|
|
else
|
|
device="hda "
|
|
fi
|
|
bootdev="-boot c"
|
|
fi
|
|
if [ x$boot = xcd ]; then
|
|
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then
|
|
device="device virtio-blk-device,drive=cd0 -drive if=none,id=cd0,media=cdrom,file="
|
|
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = loongarch64-efi ]; then
|
|
device="device virtio-blk-pci,drive=grubcd -drive if=none,id=grubcd,media=cdrom,file="
|
|
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ] && [ x$pseries != xy ] ; then
|
|
device="-drive if=ide,media=cdrom,file="
|
|
else
|
|
device="cdrom "
|
|
fi
|
|
bootdev="-boot d"
|
|
fi
|
|
if [ x$boot = xfd ]; then
|
|
device="fda "
|
|
bootdev="-boot a"
|
|
fi
|
|
|
|
if [ x$boot = xqemu ]; then
|
|
bootdev="-bios ${rom_directory}/qemu.img"
|
|
device="cdrom "
|
|
fi
|
|
|
|
if [ x$boot = xmipsel_qemu ]; then
|
|
bootdev="-kernel ${rom_directory}/mipsel-qemu_mips.elf"
|
|
device="cdrom "
|
|
fi
|
|
|
|
if [ x$boot = xmipsel_fulong2e ]; then
|
|
bootdev="-kernel ${rom_directory}/mipsel-loongson.elf -append machtype=lemote-fuloong-2e"
|
|
device="cdrom "
|
|
fi
|
|
|
|
if [ x$boot = xmips_qemu ]; then
|
|
bootdev="-kernel ${rom_directory}/mips-qemu_mips.elf"
|
|
device="cdrom "
|
|
fi
|
|
|
|
if [ x$boot = xcoreboot ]; then
|
|
imgfile="$work_directory/coreboot.img"
|
|
cp "${GRUB_COREBOOT_ROM}" "${imgfile}"
|
|
"${GRUB_CBFSTOOL}" "${imgfile}" add-payload -f "${rom_directory}/coreboot.elf" -n fallback/payload
|
|
bootdev="-bios ${imgfile}"
|
|
device="cdrom "
|
|
test -z "$debug" || echo "Coreboot image: ${imgfile}" >&2
|
|
fi
|
|
|
|
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mipsel-arc ]; then
|
|
case "$boot" in
|
|
hd)
|
|
bootdev="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/disk" ;;
|
|
*)
|
|
bootdev="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/cdrom";;
|
|
esac
|
|
fi
|
|
|
|
do_trim ()
|
|
{
|
|
if [ $trim = 1 ] || [ $trim = 2 ]; then
|
|
awk '{ if (have_head == 1) print $0; } /^'"$trim_head"'/ { have_head=1; }'
|
|
else
|
|
cat
|
|
fi
|
|
}
|
|
|
|
copy_extra_files() {
|
|
_destdir="$1"
|
|
shift
|
|
|
|
# FIXME support '=' in file names
|
|
for _file in "$@"; do
|
|
_target="${_file%=*}"
|
|
_source="${_file#*=}"
|
|
[ -n "$_source" ] || _source="$_target"
|
|
_target="$_destdir/$_target"
|
|
_targetdir="$(dirname "$_target")"
|
|
[ -d "$_targetdir" ] || mkdir -p "$_targetdir"
|
|
cp "$_source" "$_target"
|
|
done
|
|
}
|
|
|
|
setup_qemu_logger() {
|
|
cat < "$work_directory/qemu-pipe" | tr -d "\r" | tee "${goutfile}" | do_trim &
|
|
}
|
|
|
|
ret=0
|
|
mkfifo "$work_directory/qemu-pipe"
|
|
if [ x$boot = xnet ]; then
|
|
netdir="$work_directory/netdir"
|
|
mkdir -p "$netdir"
|
|
pkgdatadir="${builddir}" "${builddir}/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
|
|
cp "${cfgfile}" "$netdir/boot/grub/grub.cfg"
|
|
cp "${source}" "$netdir/boot/grub/testcase.cfg"
|
|
[ -z "$files" ] || copy_extra_files "$netdir" $files
|
|
cat >"$work_directory/run.sh" <<EOF
|
|
#! @BUILD_SHEBANG@
|
|
GRUB_QEMU_OPTS=\${GRUB_QEMU_OPTS:-"$GRUB_QEMU_OPTS"}
|
|
qemuopts="${qemuopts}"
|
|
exec "${qemu}" \${qemuopts} \${GRUB_QEMU_OPTS} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic "\$@"
|
|
EOF
|
|
elif [ x$boot = xemu ]; then
|
|
rootdir="$work_directory/rootdir"
|
|
grubdir="$rootdir/boot/grub"
|
|
mkdir -p "$grubdir/fonts"
|
|
mkdir -p "$grubdir/themes"
|
|
mkdir -p "$grubdir/locale"
|
|
test -f "${builddir}/"unicode.pf2 && cp "${builddir}/"unicode.pf2 "$grubdir/fonts/unicode.pf2"
|
|
cp -R "${srcdir}/themes/starfield" "$grubdir/themes/starfield"
|
|
for file in "${srcdir}/po/"*.gmo; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$grubdir/locale/"
|
|
fi
|
|
done
|
|
cp "${cfgfile}" "$grubdir/grub.cfg"
|
|
cp "${source}" "$grubdir/testcase.cfg"
|
|
[ -z "$files" ] || copy_extra_files "$rootdir" $files
|
|
roottar="$work_directory/root.tar"
|
|
(cd "$rootdir"; tar cf "$roottar" .)
|
|
cat >"$work_directory/run.sh" <<EOF
|
|
#! @BUILD_SHEBANG@
|
|
SDIR=\$(realpath -e \${0%/*})
|
|
exec "$(realpath -e "${builddir}")/grub-core/grub-emu" -m "\$SDIR/${device_map##*/}" --memdisk "\$SDIR/${roottar##*/}" -r memdisk -d "/boot/grub"
|
|
EOF
|
|
else
|
|
cat >"$work_directory/run.sh" <<EOF
|
|
#! @BUILD_SHEBANG@
|
|
SDIR=\$(realpath -e \${0%/*})
|
|
GRUB_QEMU_OPTS=\${GRUB_QEMU_OPTS:-"$GRUB_QEMU_OPTS"}
|
|
qemuopts="${qemuopts}"
|
|
cd "\$SDIR"
|
|
exec "${qemu}" \${qemuopts} \${GRUB_QEMU_OPTS} ${serial_null} -serial file:/dev/stdout -${device}"\${SDIR}/${isofile##*/}" ${bootdev} "\$@"
|
|
EOF
|
|
fi
|
|
|
|
if [ -f "$work_directory/run.sh" ]; then
|
|
setup_qemu_logger
|
|
chmod +x "$work_directory/run.sh"
|
|
timeout -s KILL $timeout "$work_directory/run.sh" > "$work_directory/qemu-pipe" || ret=$?
|
|
fi
|
|
|
|
wait
|
|
rm -f "$work_directory/qemu-pipe"
|
|
|
|
if [ "$ret" -ne 0 ]; then
|
|
# If QEMU failure, keep generated files to reproduce
|
|
exit $ret
|
|
fi
|
|
|
|
if [ x$boot = xcoreboot ]; then
|
|
test -n "$debug" || rm -f "${imgfile}"
|
|
elif [ x$boot = xemu ]; then
|
|
test -n "$debug" || rm -rf "$rootdir"
|
|
test -n "$debug" || rm -f "$roottar"
|
|
fi
|
|
test -n "$debug" || rm -f "${isofile}"
|
|
test -n "$debug" || rm -rf "${rom_directory}"
|
|
test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}" "${goutfile}"
|
|
test -n "$debug" || rm -f "$work_directory/run.sh"
|
|
|
|
exit $ret
|
|
|
|
|