From 5c3f89115196c9917e5e68117e9ac4b89ce2587a Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 10 May 2021 17:38:58 +0100 Subject: [PATCH] arm/fvpboot: add class to write FVP boot configuration The fvpboot class is used to write a machine-readable file that describes how to boot a given machine image inside a FVP, similar to how qemuboot writes files for runqemu. BSPs should set the FVP_* variables as appropriate in their machine configuration, but let the user opt-in to adding fvpboot to IMAGE_CLASSES. Change-Id: I2d1cd86ec4affc1d688a293987890d6a89124d94 Signed-off-by: Ross Burton --- meta-arm/classes/fvpboot.bbclass | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 meta-arm/classes/fvpboot.bbclass diff --git a/meta-arm/classes/fvpboot.bbclass b/meta-arm/classes/fvpboot.bbclass new file mode 100644 index 00000000..18a9d686 --- /dev/null +++ b/meta-arm/classes/fvpboot.bbclass @@ -0,0 +1,80 @@ +# Image class to write .fvpconf files for use with runfvp. If this is desired +# then add fvpboot to IMAGE_CLASSES, and set the variables below in your machine +# configuration as appropriate. + +# Name of recipe providing FVP executable. If unset then the executable must be installed on the host. +FVP_PROVIDER ?= "" +# Name of FVP executable to run +FVP_EXE ?= "" +# Flags for --parameter/-C +FVP_CONFIG ?= "" +# Flags for --data +FVP_DATA ?= "" +# Flags for --application +FVP_APPLICATIONS ?= "" +# Flags to name serial terminals. Flag name is the terminal id (such as +# terminal_0), value is a human-readable name. If the name is not set +# then runfvp will hide the terminal. +FVP_TERMINALS ?= "" +# What terminal should be considered the primary console +FVP_CONSOLE ?= "" +# Arbitrary extra arguments +FVP_EXTRA_ARGS ?= "" + +EXTRA_IMAGEDEPENDS += "${FVP_PROVIDER}" + +inherit image-artifact-names + +addtask do_write_fvpboot_conf after do_rootfs before do_image +python do_write_fvpboot_conf() { + # Note that currently this JSON file is in development and the format may + # change at any point, so it should always be used with a matching runfvp. + + import json, shlex + + if not d.getVar("FVP_EXE"): + return + + conffile = os.path.join(d.getVar("IMGDEPLOYDIR"), d.getVar("IMAGE_NAME") + ".fvpconf") + conffile_link = os.path.join(d.getVar("IMGDEPLOYDIR"), d.getVar("IMAGE_LINK_NAME") + ".fvpconf") + + data = {} + provider = d.getVar("FVP_PROVIDER") + if provider: + data["provider"] = provider + data["fvp-bindir"] = os.path.join(d.getVar("COMPONENTS_DIR"), + d.getVar("BUILD_ARCH"), + provider, + "usr", "bin") + + def getFlags(varname): + flags = d.getVarFlags(varname) + # For unexplained reasons, getVarFlags() returns None if there are no flags + if flags is None: + return {} + # For other reasons, you can't pass expand=True + return {key: d.expand(value) for key, value in flags.items()} + + data["exe"] = d.getVar("FVP_EXE") + data["parameters"] = getFlags("FVP_CONFIG") + data["data"] = shlex.split(d.getVar("FVP_DATA") or "") + data["applications"] = getFlags("FVP_APPLICATIONS") + data["console"] = d.getVar("FVP_CONSOLE") + data["terminals"] = getFlags("FVP_TERMINALS") + data["args"] = shlex.split(d.getVar("FVP_EXTRA_ARGS") or "") + + os.makedirs(os.path.dirname(conffile), exist_ok=True) + with open(conffile, "wt") as f: + json.dump(data, f) + + if conffile_link != conffile: + if os.path.lexists(conffile_link): + os.remove(conffile_link) + os.symlink(os.path.basename(conffile), conffile_link) +} + +def fvpboot_vars(d): + build_vars = ['DEPLOY_DIR_IMAGE', 'IMAGE_NAME', 'IMAGE_LINK_NAME', + 'COMPONENTS_DIR', 'BUILD_ARCH'] + return build_vars + [k for k in d.keys() if k.startswith('FVP_')] +do_write_fvpboot_conf[vardeps] += "${@' '.join(fvpboot_vars(d))}"