tests/vm: Added a new script for ubuntu.aarch64.

ubuntu.aarch64 provides a script to create an Ubuntu 18.04 VM.
Another new file is also added aarch64vm.py, which is a module with
common methods used by aarch64 VMs, such as how to create the
flash images.

Signed-off-by: Robert Foley <robert.foley@linaro.org>
Reviewed-by: Peter Puhov <peter.puhov@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20200601211421.1277-6-robert.foley@linaro.org>
Message-Id: <20200701135652.1366-10-alex.bennee@linaro.org>
This commit is contained in:
Robert Foley 2020-07-01 14:56:21 +01:00 committed by Alex Bennée
parent e56833b48b
commit 13336606a5
5 changed files with 217 additions and 0 deletions

20
configure vendored
View File

@ -418,6 +418,7 @@ prefix="/usr/local"
mandir="\${prefix}/share/man" mandir="\${prefix}/share/man"
datadir="\${prefix}/share" datadir="\${prefix}/share"
firmwarepath="\${prefix}/share/qemu-firmware" firmwarepath="\${prefix}/share/qemu-firmware"
efi_aarch64=""
qemu_docdir="\${prefix}/share/doc/qemu" qemu_docdir="\${prefix}/share/doc/qemu"
bindir="\${prefix}/bin" bindir="\${prefix}/bin"
libdir="\${prefix}/lib" libdir="\${prefix}/lib"
@ -1109,6 +1110,8 @@ for opt do
;; ;;
--firmwarepath=*) firmwarepath="$optarg" --firmwarepath=*) firmwarepath="$optarg"
;; ;;
--efi-aarch64=*) efi_aarch64="$optarg"
;;
--host=*|--build=*|\ --host=*|--build=*|\
--disable-dependency-tracking|\ --disable-dependency-tracking|\
--sbindir=*|--sharedstatedir=*|\ --sbindir=*|--sharedstatedir=*|\
@ -1791,6 +1794,7 @@ Advanced options (experts only):
--sysconfdir=PATH install config in PATH$confsuffix --sysconfdir=PATH install config in PATH$confsuffix
--localstatedir=PATH install local state in PATH (set at runtime on win32) --localstatedir=PATH install local state in PATH (set at runtime on win32)
--firmwarepath=PATH search PATH for firmware files --firmwarepath=PATH search PATH for firmware files
--efi-aarch64=PATH PATH of efi file to use for aarch64 VMs.
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix] --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
--with-pkgversion=VERS use specified string as sub-version of the package --with-pkgversion=VERS use specified string as sub-version of the package
--enable-debug enable common debug build options --enable-debug enable common debug build options
@ -3627,6 +3631,20 @@ EOF
fi fi
fi fi
############################################
# efi-aarch64 probe
# Check for efi files needed by aarch64 VMs.
# By default we will use the efi included with QEMU.
# Allow user to override the path for efi also.
if ! test -f "$efi_aarch64"; then
if test -f $source_path/pc-bios/edk2-aarch64-code.fd.bz2; then
# valid after build
efi_aarch64=$PWD/pc-bios/edk2-aarch64-code.fd
else
efi_aarch64=""
fi
fi
########################################## ##########################################
# libcap-ng library probe # libcap-ng library probe
if test "$cap_ng" != "no" ; then if test "$cap_ng" != "no" ; then
@ -6875,6 +6893,7 @@ if test "$docs" != "no"; then
echo "sphinx-build $sphinx_build" echo "sphinx-build $sphinx_build"
fi fi
echo "genisoimage $genisoimage" echo "genisoimage $genisoimage"
echo "efi_aarch64 $efi_aarch64"
echo "python_yaml $python_yaml" echo "python_yaml $python_yaml"
echo "slirp support $slirp $(echo_version $slirp $slirp_version)" echo "slirp support $slirp $(echo_version $slirp $slirp_version)"
if test "$slirp" != "no" ; then if test "$slirp" != "no" ; then
@ -7974,6 +7993,7 @@ echo "PYTHON=$python" >> $config_host_mak
echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
echo "EFI_AARCH64=$efi_aarch64" >> $config_host_mak
echo "PYTHON_YAML=$python_yaml" >> $config_host_mak echo "PYTHON_YAML=$python_yaml" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak echo "CC=$cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then if $iasl -h > /dev/null 2>&1; then

View File

@ -5,6 +5,9 @@
IMAGES := freebsd netbsd openbsd centos fedora IMAGES := freebsd netbsd openbsd centos fedora
ifneq ($(GENISOIMAGE),) ifneq ($(GENISOIMAGE),)
IMAGES += ubuntu.i386 centos IMAGES += ubuntu.i386 centos
ifneq ($(EFI_AARCH64),)
IMAGES += ubuntu.aarch64
endif
endif endif
IMAGES_DIR := $(HOME)/.cache/qemu-vm/images IMAGES_DIR := $(HOME)/.cache/qemu-vm/images
@ -23,6 +26,11 @@ vm-help vm-test:
ifneq ($(GENISOIMAGE),) ifneq ($(GENISOIMAGE),)
@echo " vm-build-centos - Build QEMU in CentOS VM, with Docker" @echo " vm-build-centos - Build QEMU in CentOS VM, with Docker"
@echo " vm-build-ubuntu.i386 - Build QEMU in ubuntu i386 VM" @echo " vm-build-ubuntu.i386 - Build QEMU in ubuntu i386 VM"
ifneq ($(EFI_AARCH64),)
@echo " vm-build-ubuntu.aarch64 - Build QEMU in ubuntu aarch64 VM"
else
@echo " (to build centos/ubuntu aarch64 images use configure --efi-aarch64)"
endif
else else
@echo " (install genisoimage to build centos/ubuntu images)" @echo " (install genisoimage to build centos/ubuntu images)"
endif endif
@ -65,6 +73,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \
$(if $(V)$(DEBUG), --debug) \ $(if $(V)$(DEBUG), --debug) \
$(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \ $(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
--image "$@" \ --image "$@" \
--force \ --force \
--build-image $@, \ --build-image $@, \
@ -80,6 +89,7 @@ vm-build-%: $(IMAGES_DIR)/%.img
$(if $(J),--jobs $(J)) \ $(if $(J),--jobs $(J)) \
$(if $(V),--verbose) \ $(if $(V),--verbose) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
--image "$<" \ --image "$<" \
$(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \
--snapshot \ --snapshot \
@ -102,6 +112,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img
$(if $(J),--jobs $(J)) \ $(if $(J),--jobs $(J)) \
$(if $(V)$(DEBUG), --debug) \ $(if $(V)$(DEBUG), --debug) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
--image "$<" \ --image "$<" \
--interactive \ --interactive \
false, \ false, \

106
tests/vm/aarch64vm.py Normal file
View File

@ -0,0 +1,106 @@
#!/usr/bin/env python3
#
# VM testing aarch64 library
#
# Copyright 2020 Linaro
#
# Authors:
# Robert Foley <robert.foley@linaro.org>
#
# This code is licensed under the GPL version 2 or later. See
# the COPYING file in the top-level directory.
#
import os
import sys
import subprocess
import basevm
from qemu.accel import kvm_available
# This is the config needed for current version of QEMU.
# This works for both kvm and tcg.
CURRENT_CONFIG = {
'cpu' : "max",
'machine' : "virt,gic-version=max",
}
# The minimum minor version of QEMU we will support with aarch64 VMs is 3.
# QEMU versions less than 3 have various issues running these VMs.
QEMU_AARCH64_MIN_VERSION = 3
# The DEFAULT_CONFIG will default to a version of
# parameters that works for backwards compatibility.
DEFAULT_CONFIG = {'kvm' : {'cpu' : "host",
'machine' : "virt,gic-version=host"},
'tcg' : {'cpu' : "cortex-a57",
'machine' : "virt"},
}
def get_config_defaults(vmcls, default_config):
"""Fetch the configuration defaults for this VM,
taking into consideration the defaults for
aarch64 first, followed by the defaults for this VM."""
config = default_config
config.update(aarch_get_config_defaults(vmcls))
return config
def aarch_get_config_defaults(vmcls):
"""Set the defaults for current version of QEMU."""
config = CURRENT_CONFIG
args, argv = basevm.parse_args(vmcls)
qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path)
qemu_version = basevm.get_qemu_version(qemu_path)
if qemu_version < QEMU_AARCH64_MIN_VERSION:
error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\
"The major version must be at least {}.\n"\
"To continue with the current build of QEMU, "\
"please restart with QEMU_LOCAL=1 .\n"
print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION))
exit(1)
if qemu_version == QEMU_AARCH64_MIN_VERSION:
# We have an older version of QEMU,
# set the config values for backwards compatibility.
if kvm_available('aarch64'):
config.update(DEFAULT_CONFIG['kvm'])
else:
config.update(DEFAULT_CONFIG['tcg'])
return config
def create_flash_images(flash_dir="./", efi_img=""):
"""Creates the appropriate pflash files
for an aarch64 VM."""
flash0_path = get_flash_path(flash_dir, "flash0")
flash1_path = get_flash_path(flash_dir, "flash1")
fd_null = open(os.devnull, 'w')
subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path),
"bs=1M", "count=64"],
stdout=fd_null, stderr=subprocess.STDOUT)
# A reliable way to get the QEMU EFI image is via an installed package or
# via the bios included with qemu.
if not os.path.exists(efi_img):
sys.stderr.write("*** efi argument is invalid ({})\n".format(efi_img))
sys.stderr.write("*** please check --efi-aarch64 argument or "\
"install qemu-efi-aarch64 package\n")
exit(3)
subprocess.check_call(["dd", "if={}".format(efi_img),
"of={}".format(flash0_path),
"conv=notrunc"],
stdout=fd_null, stderr=subprocess.STDOUT)
subprocess.check_call(["dd", "if=/dev/zero",
"of={}".format(flash1_path),
"bs=1M", "count=64"],
stdout=fd_null, stderr=subprocess.STDOUT)
fd_null.close()
def get_pflash_args(flash_dir="./"):
"""Returns a string that can be used to
boot qemu using the appropriate pflash files
for aarch64."""
flash0_path = get_flash_path(flash_dir, "flash0")
flash1_path = get_flash_path(flash_dir, "flash1")
pflash_args_str = "-drive file={},format=raw,if=pflash "\
"-drive file={},format=raw,if=pflash"
pflash_args = pflash_args_str.format(flash0_path, flash1_path)
return pflash_args.split(" ")
def get_flash_path(flash_dir, name):
return os.path.join(flash_dir, "{}.img".format(name))

View File

@ -92,6 +92,7 @@ class BaseVM(object):
self._guest = None self._guest = None
self._genisoimage = args.genisoimage self._genisoimage = args.genisoimage
self._build_path = args.build_path self._build_path = args.build_path
self._efi_aarch64 = args.efi_aarch64
# Allow input config to override defaults. # Allow input config to override defaults.
self._config = DEFAULT_CONFIG.copy() self._config = DEFAULT_CONFIG.copy()
if config != None: if config != None:
@ -496,6 +497,14 @@ def get_qemu_path(arch, build_path=None):
qemu_path = "qemu-system-" + arch qemu_path = "qemu-system-" + arch
return qemu_path return qemu_path
def get_qemu_version(qemu_path):
"""Get the version number from the current QEMU,
and return the major number."""
output = subprocess.check_output([qemu_path, '--version'])
version_line = output.decode("utf-8")
version_num = re.split(' |\(', version_line)[3].split('.')[0]
return int(version_num)
def parse_config(config, args): def parse_config(config, args):
""" Parse yaml config and populate our config structure. """ Parse yaml config and populate our config structure.
The yaml config allows the user to override the The yaml config allows the user to override the
@ -573,6 +582,9 @@ def parse_args(vmcls):
parser.add_option("--config", "-c", default=None, parser.add_option("--config", "-c", default=None,
help="Provide config yaml for configuration. "\ help="Provide config yaml for configuration. "\
"See config_example.yaml for example.") "See config_example.yaml for example.")
parser.add_option("--efi-aarch64",
default="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",
help="Path to efi image for aarch64 VMs.")
parser.disable_interspersed_args() parser.disable_interspersed_args()
return parser.parse_args() return parser.parse_args()

68
tests/vm/ubuntu.aarch64 Executable file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env python3
#
# Ubuntu aarch64 image
#
# Copyright 2020 Linaro
#
# Authors:
# Robert Foley <robert.foley@linaro.org>
# Originally based on ubuntu.i386 Fam Zheng <famz@redhat.com>
#
# This code is licensed under the GPL version 2 or later. See
# the COPYING file in the top-level directory.
#
import sys
import basevm
import aarch64vm
import ubuntuvm
DEFAULT_CONFIG = {
'cpu' : "cortex-a57",
'machine' : "virt,gic-version=3",
'install_cmds' : "apt-get update,"\
"apt-get build-dep -y --arch-only qemu,"\
"apt-get install -y libfdt-dev pkg-config language-pack-en",
# We increase beyond the default time since during boot
# it can take some time (many seconds) to log into the VM
# especially using softmmu.
'ssh_timeout' : 60,
}
class UbuntuAarch64VM(ubuntuvm.UbuntuVM):
name = "ubuntu.aarch64"
arch = "aarch64"
image_name = "ubuntu-18.04-server-cloudimg-arm64.img"
image_link = "https://cloud-images.ubuntu.com/releases/18.04/release/" + image_name
image_sha256="0fdcba761965735a8a903d8b88df8e47f156f48715c00508e4315c506d7d3cb1"
BUILD_SCRIPT = """
set -e;
cd $(mktemp -d);
sudo chmod a+r /dev/vdb;
tar --checkpoint=.10 -xf /dev/vdb;
./configure {configure_opts};
make --output-sync {target} -j{jobs} {verbose};
"""
def boot(self, img, extra_args=None):
aarch64vm.create_flash_images(self._tmpdir, self._efi_aarch64)
default_args = aarch64vm.get_pflash_args(self._tmpdir)
if extra_args:
extra_args.extend(default_args)
else:
extra_args = default_args
# We always add these performance tweaks
# because without them, we boot so slowly that we
# can time out finding the boot efi device.
if '-smp' not in extra_args and \
'-smp' not in self._config['extra_args'] and \
'-smp' not in self._args:
# Only add if not already there to give caller option to change it.
extra_args.extend(["-smp", "8"])
# We have overridden boot() since aarch64 has additional parameters.
# Call down to the base class method.
super(UbuntuAarch64VM, self).boot(img, extra_args=extra_args)
if __name__ == "__main__":
defaults = aarch64vm.get_config_defaults(UbuntuAarch64VM, DEFAULT_CONFIG)
sys.exit(basevm.main(UbuntuAarch64VM, defaults))