diff options
author | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
---|---|---|
committer | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
commit | 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf (patch) | |
tree | cd70a267a5ef105ba32f200aa088e281fbd85747 /bsp/meta-arm/meta-arm-autonomy | |
parent | 4204309872da5cb401cbb2729d9e2d4869a87f42 (diff) |
basesystem-jjsandbox/ToshikazuOhiwa/master-jj
recipes
Diffstat (limited to 'bsp/meta-arm/meta-arm-autonomy')
61 files changed, 4191 insertions, 0 deletions
diff --git a/bsp/meta-arm/meta-arm-autonomy/README.md b/bsp/meta-arm/meta-arm-autonomy/README.md new file mode 100644 index 00000000..785f278b --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/README.md @@ -0,0 +1,92 @@ +meta-arm-autonomy Yocto Layer +============================= + +Introduction +------------ +This layer provides an hypervisor based solution (currently based on Xen) for +autonomous system. It contains recipes and classes to build host and guests +systems. + +To start using this layer, please check the +[Quick Start Guide](documentation/arm-autonomy-quickstart.md). + +Dependencies +------------ +This layer depends on several other Yocto layers: +* meta-openembedded (https://git.openembedded.org/meta-openembedded) +* poky (https://git.yoctoproject.org/poky) +* meta-virtualization (https://git.yoctoproject.org/meta-virtualization) + +Distribution Features +--------------------- +This layer is adding the following Yocto DISTRO_FEATURES: + +* arm-autonomy-host: this feature activates functionalities required to build + an autonomy host system. It is doing the following: + - add 'xen' and 'ipv4' to DISTRO_FEATURES. + - add xen backend drivers to linux kernel configuration. + - To reduce the root filesystem image size the kernel image is not installed. + +* arm-autonomy-guest: this feature activates functionalities to run as guest + of an autonomy system. It is doing the following: + - add 'ipv4' to DISTRO_FEATURES. + - add xen frontend drivers to linux kernel configuration. + - add console on hvc0 during init. + +Bitbake variables +----------------- +Some recipes and classes in this layer are introducing variables which can be +modified by the user in local.conf. +Each recipe introducing such variables has a chapter "Bitbake parameters" in +its documentation. + +Those documentation files should be checked for variables: +- [xen-devicetree](documentation/xen-devicetree.md) +- [xenguest-manager](documentation/xenguest-manager.md) +- [xenguest-network-bridge](documentation/xenguest-network-bridge.md) + +BSPs +---- +This layer is adding the following machines: + +* arm64-autonomy-guest: this machines creates a minimal BSP suitable to be used + as an autonomy guest. It is in fact only activating ARM64 architecture and + SMP in the linux kernel and is enabling the DISTRO_FEATURE + arm-autonomy-guest. + +Images +------ +This layer is adding the following images: + +* arm-autonomy-host-image-minimal: this image includes all elements required + to create a minimal arm-autonomy-host system. This includes xen and tools to + manage xen guests. This image depends on 'arm-autonomy-host' distribution + feature. + +Recipes and classes +------------------- +This layer is adding the following recipes and classes: + +* [xen-devicetree](documentation/xen-devicetree.md): this is a recipe to modify + a device tree blob to add information required to boot xen and a Dom0 linux. + +* [xenguest-mkimage](documentation/xenguest-mkimage.md): this is a tool to + create and modify images to be used as Xen guests. + +* [xenguest-manager](documentation/xenguest-manager.md): this is a tool to + create/remove/start/stop xen guest generated using xenguest-mkimage. + +* [xenguest-network-bridge](documentation/xenguest-network-bridge.md): this + recipe add tools and init scripts to create a bridge connected to the + external network on the host and allow guests to be connected to it. + +Contributing +------------ +This project has not put in place a process for contributions currently. If you +would like to contribute, please contact the maintainers + + +Maintainer(s) +------------- +* Bertrand Marquis <bertrand.marquis@arm.com> +* Filipe Rinaldi <filipe.rinaldi@arm.com> diff --git a/bsp/meta-arm/meta-arm-autonomy/classes/arm-autonomy-features.bbclass b/bsp/meta-arm/meta-arm-autonomy/classes/arm-autonomy-features.bbclass new file mode 100644 index 00000000..15549d89 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/classes/arm-autonomy-features.bbclass @@ -0,0 +1,5 @@ +# Include arm-autonomy distro config files if the distro features are set + +require ${@bb.utils.contains('DISTRO_FEATURES', 'arm-autonomy-host', '${ARM_AUTONOMY_DISTRO_CFGDIR}/arm-autonomy-host.inc', '', d)} +require ${@bb.utils.contains('DISTRO_FEATURES', 'arm-autonomy-guest', '${ARM_AUTONOMY_DISTRO_CFGDIR}/arm-autonomy-guest.inc', '', d)} + diff --git a/bsp/meta-arm/meta-arm-autonomy/classes/image_types_xenguest.bbclass b/bsp/meta-arm/meta-arm-autonomy/classes/image_types_xenguest.bbclass new file mode 100644 index 00000000..195d6ed2 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/classes/image_types_xenguest.bbclass @@ -0,0 +1,108 @@ +# Create a xenguest image with kernel and filesystem produced by Yocto +# This will create a .xenguest file that the xenguest-manager can use. + +inherit xenguest-image + +# We are creating our guest in a local subdirectory +# force the value so that we are not impacted if the user is changing it +XENGUEST_IMAGE_DEPLOY_DIR = "${WORKDIR}/tmp-xenguest" + +# Name of deployed file (keep standard image name and add .xenguest) +XENGUEST_IMAGE_DEPLOY ??= "${IMAGE_NAME}" + +# Add kernel XENGUEST_IMAGE_KERNEL from DEPLOY_DIR_IMAGE to image +xenguest_image_add_kernel() { + srcfile="${1:-}" + if [ -z "${srcfile}" ]; then + srcfile="${DEPLOY_DIR_IMAGE}/${XENGUEST_IMAGE_KERNEL}" + fi + call_xenguest_mkimage partial --xen-kernel=$srcfile +} + +# Add rootfs file to the image +xenguest_image_add_rootfs() { + call_xenguest_mkimage partial \ + --disk-add-file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${IMAGE_TYPEDEP_xenguest}:rootfs.${IMAGE_TYPEDEP_xenguest} +} + +# Pack xenguest image +xenguest_image_pack() { + mkdir -p ${IMGDEPLOYDIR} + rm -f ${IMGDEPLOYDIR}/${XENGUEST_IMAGE_DEPLOY}.xenguest + call_xenguest_mkimage pack \ + ${IMGDEPLOYDIR}/${XENGUEST_IMAGE_DEPLOY}.xenguest +} + +# +# Task finishing the bootimg +# We need this task to actually create the symlinks +# +python do_bootimg_xenguest() { + subtasks = d.getVarFlag('do_bootimg_xenguest', 'subtasks') + + bb.build.exec_func('xenguest_image_clone', d) + if subtasks: + for tk in subtasks.split(): + bb.build.exec_func(tk, d) + bb.build.exec_func('xenguest_image_pack', d) + bb.build.exec_func('create_symlinks', d) +} +# This is used to add sub-tasks to do_bootimg_xenguest +do_bootimg_xenguest[subtasks] = "" +# Those are required by create_symlinks to find our image +do_bootimg_xenguest[subimages] = "xenguest" +do_bootimg_xenguest[imgsuffix] = "." +do_bootimg_xenguest[depends] += "xenguest-base-image:do_deploy" +# Need to have rootfs so all recipes have deployed their content +do_bootimg_xenguest[depends] += "${PN}:do_rootfs" + +# This set in python anonymous after, just set a default value here +IMAGE_TYPEDEP_xenguest ?= "tar" + +# We must not be built at rootfs build time because we need the kernel +IMAGE_TYPES_MASKED += "xenguest" +IMAGE_TYPES += "xenguest" + +python __anonymous() { + # Do not do anything if we are not in the want FSTYPES + if bb.utils.contains_any('IMAGE_FSTYPES', 'xenguest', '1', '0', d): + + # Check the coherency of the configuration + rootfs_needed = False + rootfs_file = '' + kernel_needed = False + + rootfs_file = xenguest_image_rootfs_file(d) + if rootfs_file: + rootfs_needed = True + + if d.getVar('XENGUEST_IMAGE_KERNEL') and not d.getVar('INITRAMFS_IMAGE'): + # If INITRAMFS_IMAGE is set, even if INITRAMFS_IMAGE_BUNDLE is not + # set to 1 to bundle the initramfs with the kernel, kernel.bbclass + # is setting a dependency on ${PN}:do_image_complete. We cannot + # in this case depend on do_deploy as it would create a circular + # dependency: + # do_image_complete would depend on kernel:do_deploy which would + # depend on ${PN}:do_image_complete + # In the case INITRAMFS_IMAGE_BUNDLE = 1, the kernel-xenguest class + # will handle the creation of a xenguest image with the kernel. + # In the other case the kernel can be added manually to the image. + kernel_needed = True + + bb.build.addtask('do_bootimg_xenguest', 'do_image_complete', None, d) + + if rootfs_needed: + # tell do_bootimg_xenguest to call add_rootfs + d.appendVarFlag('do_bootimg_xenguest', 'subtasks', ' xenguest_image_add_rootfs') + # do_bootimg_xenguest will need the tar file + d.appendVarFlag('do_bootimg_xenguest', 'depends', ' %s:do_image_tar' % (d.getVar('PN'))) + # set our TYPEDEP to the proper compression + d.setVar('IMAGE_TYPEDEP_xenguest', 'tar' + (rootfs_file.split('.tar', 1)[1] or '')) + + if kernel_needed: + # Tell do_bootimg_xenguest to call xenguest_image_add_kernel + d.appendVarFlag('do_bootimg_xenguest', 'subtasks', ' xenguest_image_add_kernel') + # we will need kernel do_deploy + d.appendVarFlag('do_bootimg_xenguest', 'depends', ' virtual/kernel:do_deploy') +} + diff --git a/bsp/meta-arm/meta-arm-autonomy/classes/kernel-xenguest.bbclass b/bsp/meta-arm/meta-arm-autonomy/classes/kernel-xenguest.bbclass new file mode 100644 index 00000000..a4954aaa --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/classes/kernel-xenguest.bbclass @@ -0,0 +1,34 @@ +# Create a xenguest image containing the kernel with initramfs when +# initramfs is activated +# This is done using kernel-fitimage as model +# To activate this, kernel-xenguest must be added to KERNEL_CLASSES + +inherit xenguest-image + +# use a local copy to pack all together +XENGUEST_IMAGE_DEPLOY_DIR = "${WORKDIR}/tmp-xenguest" + +python __anonymous () { + # only if xenguest image type is present + if bb.utils.contains('IMAGE_FSTYPES', 'xenguest', '1', '0', d): + # only if initramfs bundle is activated + if d.getVar('INITRAMFS_IMAGE') and d.getVar('INITRAMFS_IMAGE_BUNDLE') == "1": + if not bb.utils.contains('KERNEL_IMAGETYPES', 'Image', '1', '0', d): + bb.fatal("xenguest image type with initramfs require Image kernel image type") + bb.build.addtask('do_assemble_xenguest_initramfs', 'do_deploy', 'do_bundle_initramfs', d) +} + +do_assemble_xenguest_initramfs() { + xenguest_image_clone + call_xenguest_mkimage partial --xen-kernel=${B}/${KERNEL_OUTPUT_DIR}/Image.initramfs + rm -f ${B}/${KERNEL_OUTPUT_DIR}/Image-initramfs.xenguest + call_xenguest_mkimage pack ${B}/${KERNEL_OUTPUT_DIR}/Image-initramfs.xenguest +} +do_assemble_xenguest_initramfs[depends] += "${INITRAMFS_IMAGE}:do_image_complete" + +kernel_do_deploy_append() { + if [ -f "${B}/${KERNEL_OUTPUT_DIR}/Image-initramfs.xenguest" ]; then + install -m 0644 ${B}/${KERNEL_OUTPUT_DIR}/Image-initramfs.xenguest "$deployDir/Image-${INITRAMFS_NAME}.xenguest" + ln -snf Image-${INITRAMFS_NAME}.xenguest $deployDir/Image-${INITRAMFS_LINK_NAME}.xenguest + fi +} diff --git a/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image-extra.bbclass b/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image-extra.bbclass new file mode 100644 index 00000000..502a083f --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image-extra.bbclass @@ -0,0 +1,102 @@ +# This class must be used to extend the xenguest image +# It provides variables to add init scripts, a dtb, xen files or disk files. +# +# The class is extending deploy function so you recipe must inherit deploy and +# have a do_deploy function (even if it is empty) + +# Use standard xenguest-image +inherit xenguest-image + +# Add a DTB file for the guest +# Only one file should be added, if this is set multiple times or in several +# recipes, the last recipe setting it will prevail. +XENGUEST_EXTRA_DTB ??= "" + +# Append something to the guest xen configuration +# All files here will be merged together in the final xen configuration +# This can contain several files or be used in several recipes +XENGUEST_EXTRA_XENCONFIG ??= "" + +# Add a xenguest init, init-pre or init-post script +XENGUEST_EXTRA_INIT_PRE ??= "" +XENGUEST_EXTRA_INIT ??= "" +XENGUEST_EXTRA_INIT_POST ??= "" + +# Add xenguest files, (to be used in extra xen config for example) +# several files may be added, space separated, the path will be kept on the +# generated xenguest image (if dir1/file1 is added, it can be used as +# dir1/file1 file in the xen configuration). +XENGUEST_EXTRA_FILES ??= "" + +# Add xenguest disk files (to be used as disk partition content) +# several files may be added, space separated, the path will be kept on the +# generated xenguest image (if dir1/file1 is added, it can be used as +# dir1/file1 file in the disk content parameters). +XENGUEST_EXTRA_DISK_FILES ??= "" + +do_deploy_append() { + if [ -z "${XENGUEST_IMAGE_DEPLOY_DIR}" -o \ + -z "${XENGUEST_IMAGE_DEPLOY_SUBDIR}" ]; then + die "Configuration error: XENGUEST_IMAGE_DEPLOY_DIR or XENGUEST_IMAGE_DEPLOY_SUBDIR is empty" + fi + rm -rf ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} + mkdir -p ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} + + if [ -n "${XENGUEST_EXTRA_DTB}" ]; then + if [ ! -f ${XENGUEST_EXTRA_DTB} ]; then + die "xenguest-image: DTB file ${XENGUEST_EXTRA_DTB} does not exist" + fi + call_xenguest_mkimage partial --xen-device-tree=${XENGUEST_EXTRA_DTB} + fi + + if [ -n "${XENGUEST_EXTRA_XENCONFIG}" ]; then + for f in ${XENGUEST_EXTRA_XENCONFIG}; do + if [ ! -f $f ]; then + die "xenguest-image: Xen config $f does not exist" + fi + call_xenguest_mkimage partial --xen-append=$f + done + fi + + if [ -n "${XENGUEST_EXTRA_INIT_PRE}" ]; then + if [ ! -f ${XENGUEST_EXTRA_INIT_PRE} ]; then + die "xenguest-image: Init script ${XENGUEST_EXTRA_INIT_PRE} does not exist" + fi + call_xenguest_mkimage partial --init-pre=${XENGUEST_EXTRA_INIT_PRE} + fi + + if [ -n "${XENGUEST_EXTRA_INIT}" ]; then + if [ ! -f ${XENGUEST_EXTRA_INIT} ]; then + die "xenguest-image: Init script ${XENGUEST_EXTRA_INIT} does not exist" + fi + call_xenguest_mkimage partial --init-script=${XENGUEST_EXTRA_INIT} + fi + + if [ -n "${XENGUEST_EXTRA_INIT_POST}" ]; then + if [ ! -f ${XENGUEST_EXTRA_INIT_POST} ]; then + die "xenguest-image: Init script ${XENGUEST_EXTRA_INIT_POST} does not exist" + fi + call_xenguest_mkimage partial --init-post=${XENGUEST_EXTRA_INIT_POST} + fi + + if [ -n "${XENGUEST_EXTRA_FILES}" ]; then + for f in ${XENGUEST_EXTRA_FILES}; do + if [ ! -f $f ]; then + die "xenguest-image: Xen file $f does not exist" + fi + call_xenguest_mkimage partial --xen-add-file=$f + done + fi + + if [ -n "${XENGUEST_EXTRA_DISK_FILES}" ]; then + for f in ${XENGUEST_EXTRA_DISK_FILES}; do + if [ ! -f $f ]; then + die "xenguest-image: Disk file $f does not exist" + fi + call_xenguest_mkimage partial --disk-add-file=$f + done + fi +} +# Need to have xenguest-image tool +do_deploy[depends] += "xenguest-base-image:do_deploy" + diff --git a/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image.bbclass b/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image.bbclass new file mode 100644 index 00000000..e8880f3f --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/classes/xenguest-image.bbclass @@ -0,0 +1,195 @@ +# This class must be used to create, extend or pack a xenguest image. +# It is using xenguest-mkimage tool to do operations + +DEPENDS += "xenguest-mkimage-native" + +# +# Xenguest image parameters +# All the following parameters can be modified in local.conf or on recipes +# inheriting this class +# + +# Guest memory size in MB +XENGUEST_IMAGE_MEMORY_SIZE ??= "512" + +# Guest number of vcpus +XENGUEST_IMAGE_NUM_VCPUS ??= "1" + +# Guest auto boot during init, set to 1 to have guest started during init or +# to 0 if the guest should not be auto started +XENGUEST_IMAGE_AUTOBOOT ??= "1" + +# Partition containing the root file system +# Xen will actually add root=${XENGUEST_IMAGE_ROOT} to your guest kernel +# command line +# You can let this empty if the root filesystem is specified in an other way +# and have root= option added to the command line for example or if you don't +# need a root filesystem mounted for your guest (initrd for example) +XENGUEST_IMAGE_ROOT ??= "/dev/xvda1" + +# Guest kernel command line arguments +XENGUEST_IMAGE_CMDLINE ??= "earlyprintk=xenboot console=hvc0 rw" + +# Extra commands to add to xenguest-image when creating the image +XENGUEST_IMAGE_EXTRA_CMD ??= "" + +# Kernel binary +# This value is used by the xenguest image type but is declared here to have +# all variables in the same place +# If this value is empty no kernel will be added to the image +XENGUEST_IMAGE_KERNEL ??= "Image" + +# Size of the disk to create (if 0 no disk will be created and rootfs will not +# be included in the xenguest image) +XENGUEST_IMAGE_DISK_SIZE ??= "${@ '4' if not d.getVar('INITRAMFS_IMAGE') else '0'}" + +# +# XENGUEST_IMAGE_DISK PARTITIONS is used to describe the partitions to setup +# and their content. +# It must be set to a space separated list of entries with each entry having +# the format num:sz:fs:[file] where: +# - num is a partition number +# - sz is the partition size in Gigabit +# - fs is the filesystem to use for the partition +# - file is optionally pointing to a file to use as content of the partition +# Please check image_types_xenguest.bbclass for rootfs handling of files +# +# Default value creates a partition 1 using the full disk, formated with ext4 +# and containing the root filesystem produced by Yocto +XENGUEST_IMAGE_DISK_PARTITIONS ??= "1:${XENGUEST_IMAGE_DISK_SIZE}:ext4:rootfs.tar.gz" + +# XENGUEST_IMAGE_NETWORK_BRIDGE can be set to 1 to have a network interface +# on the guest connected to host bridged network. This will provide the guest +# with a network interface connected directly to the external network +XENGUEST_IMAGE_NETWORK_BRIDGE ??= "1" + +# Sub-directory in wich the guest is created. This is create in deploy as a +# subdirectory and must be coherent between all components using this class so +# it must only be modified from local.conf if needed +XENGUEST_IMAGE_DEPLOY_SUBDIR ?= "xenguest" + +# Directory in which the xenguest should be deployed +# a sub-directory named ${XENGUEST_IMAGE_DEPLOY_SUBDIR} will be created there. +# This should be set to: +# - ${DEPLOYDIR} (default) if creating or extending the xenguest for a normal +# recipe. +# - something in ${WORKDIR} if you need to clone and manipulate an image +XENGUEST_IMAGE_DEPLOY_DIR ??= "${DEPLOYDIR}" + +# +# Wrapper to call xenguest-mkimage +# It is using XENGUEST_IMAGE_DEPLOY_DIR and XENGUEST_IMAGE_DEPLOY_SUBDIR +# to find the image to operate on +# +# Usage: call_xenguest_mkimage [operation] [args] +call_xenguest_mkimage() { + local cmd="${1}" + local img="${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR}" + shift + + echo "xenguest-mkimage $cmd $img $@" + xenguest-mkimage $cmd $img $@ +} + +# +# Create an initial xenguest image. +# This is a task which must be added in a recipe inheriting deploy +# It is using XENGUEST_IMAGE_MEMORY_SIZE, XENGUEST_IMAGE_NUM_VCPUS, +# XENGUEST_IMAGE_AUTOBOOT, XENGUEST_IMAGE_ROOT, XENGUEST_IMAGE_EXTRA_CMD, +# XENGUEST_IMAGE_CMDLINE, XENGUEST_IMAGE_DISK_SIZE and +# XENGUEST_IMAGE_DISK_PARTITIONS to customize the initial guest +# +xenguest_image_create() { + if [ -z "${XENGUEST_IMAGE_DEPLOY_DIR}" -o \ + -z "${XENGUEST_IMAGE_DEPLOY_SUBDIR}" ]; then + die "Configuration error: XENGUEST_IMAGE_DEPLOY_DIR or XENGUEST_IMAGE_DEPLOY_SUBDIR is empty" + fi + + rm -rf ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} + + mkdir -p ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} + + # Create the image + call_xenguest_mkimage create --xen-memory=${XENGUEST_IMAGE_MEMORY_SIZE} \ + --xen-vcpus=${XENGUEST_IMAGE_NUM_VCPUS} \ + --xen-root=${XENGUEST_IMAGE_ROOT} \ + ${XENGUEST_IMAGE_EXTRA_CMD} + + # add command line + if [ -n "${XENGUEST_IMAGE_CMDLINE}" ]; then + call_xenguest_mkimage update --xen-clean-extra + for arg in ${XENGUEST_IMAGE_CMDLINE}; do + call_xenguest_mkimage update --xen-extra=$arg + done + fi + + # create disk if needed + disksize="${XENGUEST_IMAGE_DISK_SIZE}" + if [ -z "$disksize" ]; then + disksize="0" + fi + if [ $disksize -gt 0 ]; then + # setup disk size + call_xenguest_mkimage update --disk-reset-config --disk-size=$disksize + + diskparts="${XENGUEST_IMAGE_DISK_PARTITIONS}" + if [ -n "$diskparts" ]; then + for arg in $diskparts; do + call_xenguest_mkimage update --disk-add-part=$arg + partnum="$(expr $partnum + 1)" + done + fi + fi + + if [ "${XENGUEST_IMAGE_AUTOBOOT}" = "1" ]; then + call_xenguest_mkimage update --set-param=GUEST_AUTOBOOT=1 + else + call_xenguest_mkimage update --set-param=GUEST_AUTOBOOT=0 + fi + + if [ "${XENGUEST_IMAGE_NETWORK_BRIDGE}" = "1" ]; then + call_xenguest_mkimage update --set-param=NETWORK_BRIDGE=1 + else + call_xenguest_mkimage update --set-param=NETWORK_BRIDGE=0 + fi +} + +# +# Clone the current xenguest from deploy to manipulate it locally +# This is required if you need to change things before packing an image +# To set the local directory where to clone you must set +# XENGUEST_IMAGE_DEPLOY_DIR if you don't want to use do_deploy to modify the +# image +# +xenguest_image_clone() { + if [ -z "${XENGUEST_IMAGE_DEPLOY_DIR}" -o \ + -z "${XENGUEST_IMAGE_DEPLOY_SUBDIR}" ]; then + die "Configuration error: XENGUEST_IMAGE_DEPLOY_DIR or XENGUEST_IMAGE_DEPLOY_SUBDIR is empty" + fi + + if [ ! -f ${DEPLOY_DIR_IMAGE}/${XENGUEST_IMAGE_DEPLOY_SUBDIR}/guest.cfg ]; then + die "xenguest-image: ${DEPLOY_DIR_IMAGE}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} does not contain a valid guest" + fi + + rm -rf ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} + mkdir -p ${XENGUEST_IMAGE_DEPLOY_DIR} + cp -rf ${DEPLOY_DIR_IMAGE}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} \ + ${XENGUEST_IMAGE_DEPLOY_DIR}/${XENGUEST_IMAGE_DEPLOY_SUBDIR} +} + +# Helper function to retrieve rootfs file if present in one partition +# This can return an empty string or rootfs.tar[.COMP] +def xenguest_image_rootfs_file(d): + disksize = d.getVar('XENGUEST_IMAGE_DISK_SIZE') + # if disksize is 0, we don't create anything + if not disksize or disksize == '0': + return "" + # Find first partition with file=rootfs.tar* + partlist = d.getVar('XENGUEST_IMAGE_DISK_PARTITIONS') + if partlist: + for partdesc in partlist.split(): + partelems = partdesc.split(':', 3) + if partelems[3]: + if partelems[3].startswith('rootfs.tar'): + return partelems[3] + return "" diff --git a/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-guest.inc b/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-guest.inc new file mode 100644 index 00000000..16b9f7ea --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-guest.inc @@ -0,0 +1,11 @@ +# This files is added when DISTRO_FEATURES contains arm-autonomy-guest + +# We need to have ipv4 activated +DISTRO_FEATURES_append = " ipv4" + +# Build a xenguest type image +IMAGE_CLASSES += "image_types_xenguest" +IMAGE_FSTYPES += "xenguest" + +# xenguest kernel extension to handle initramfs +KERNEL_CLASSES += "kernel-xenguest" diff --git a/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-host.inc b/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-host.inc new file mode 100644 index 00000000..bd98ae21 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/conf/distro/include/arm-autonomy-host.inc @@ -0,0 +1,9 @@ +# This files is added when DISTRO_FEATURES contains arm-autonomy-host + +# We need to have xen and ipv4 activated +DISTRO_FEATURES_append = " xen ipv4" + +# Don't include kernels in standard images when building arm-autonomy-host +# If the kernel image is needed in the rootfs the following should be set from +# a bbappend: RDEPENDS_${KERNEL_PACKAGE_NAME}-base = "${KERNEL_PACKAGE_NAME}-image" +RDEPENDS_${KERNEL_PACKAGE_NAME}-base ?= "" diff --git a/bsp/meta-arm/meta-arm-autonomy/conf/layer.conf b/bsp/meta-arm/meta-arm-autonomy/conf/layer.conf new file mode 100644 index 00000000..739dc811 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/conf/layer.conf @@ -0,0 +1,34 @@ +# Add layer to BBPATH +BBPATH .= ":${LAYERDIR}" + +# Add recipes-* directories to BBFILES +BBFILES += " \ + ${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend \ + " + +BBFILE_COLLECTIONS += "meta-arm-autonomy" +BBFILE_PATTERN_meta-arm-autonomy = "^${LAYERDIR}/" +BBFILE_PRIORITY_meta-arm-autonomy = "6" +LAYERDEPENDS_meta-arm-autonomy = " \ + core \ + yocto \ + openembedded-layer \ + virtualization-layer \ +" +LAYERSERIES_COMPAT_meta-arm-autonomy = "dunfell" + +# We don't activate virtualization feature from meta-virtualization as it +# brings in lots of stuff we don't need. We need to disable the sanity check +# otherwise the user will see a warning on each build. +SKIP_META_VIRT_SANITY_CHECK = "1" + +# Directory of our distro config files +ARM_AUTONOMY_DISTRO_CFGDIR = "${LAYERDIR}/conf/distro/include/" + +# Add class to handle arm-autonomy distro extensions +USER_CLASSES_append = " arm-autonomy-features" + +BBFILES_DYNAMIC += " \ + meta-arm-bsp:${LAYERDIR}/dynamic-layers/meta-arm-bsp/*/*/*.bbappend \ +" diff --git a/bsp/meta-arm/meta-arm-autonomy/conf/machine/arm64-autonomy-guest.conf b/bsp/meta-arm/meta-arm-autonomy/conf/machine/arm64-autonomy-guest.conf new file mode 100644 index 00000000..8b32fa7a --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/conf/machine/arm64-autonomy-guest.conf @@ -0,0 +1,17 @@ +#@TYPE: Machine +#@NAME: Autonomy Guest ARM64 machine +#@DESCRIPTION: Machine configuration for ARM64 Autonomy Guest + +TUNE_FEATURES = "aarch64" + +require conf/machine/include/arm/arch-armv8a.inc + +KERNEL_IMAGETYPE = "Image" + +IMAGE_FSTYPES += "tar.bz2" + +PREFERRED_PROVIDER_virtual/kernel = "linux-yocto" +PREFERRED_VERSION_linux-yocto ?= "5.4%" + +DISTRO_FEATURES += "arm-autonomy-guest" + diff --git a/bsp/meta-arm/meta-arm-autonomy/documentation/arm-autonomy-quickstart.md b/bsp/meta-arm/meta-arm-autonomy/documentation/arm-autonomy-quickstart.md new file mode 100644 index 00000000..2a457c16 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/documentation/arm-autonomy-quickstart.md @@ -0,0 +1,225 @@ +arm-autonomy Quick Start +================== + +This documentation is explaining how to quickly start with arm-autonomy layer +and the main features provided. +You will find in the documentation directory some more detailed documentation +for each of the functionalites provided by this layer. + +What to use this layer for? +--------------------------- +Using this layer, you can easily and rapidly create a system based on Xen with +one or more guests created using Yocto. + +For this you will need to create at least 2 Yocto projects: +- a host project: This one will compile Xen and create a Linux system to be + used as Xen Dom0. The Linux system will contain all functionalities required + to start and manage guests. +- one or several guest projects: Those will create Linux systems with the + required Linux kernel configuration to run as Xen DomU. + +Prepare your system +------------------- + +First you must download the Yocto layers needed: + - [meta-openembedded](https://git.openembedded.org/meta-openembedded) + - [poky](https://git.yoctoproject.org/poky) + - [meta-virtualization](https://git.yoctoproject.org/meta-virtualization) + - [meta-arm](https://git.yoctoproject.org/meta-arm) + - all other layers you might want to use + +For each of the downloaded layer make sure you checkout the release of Yocto +you want to use (for example zeus using `git checkout zeus`). + +Please follow [Yocto documentation](https://www.yoctoproject.org/docs/latest/brief-yoctoprojectqs/brief-yoctoprojectqs.html) +in order to have the required dependencies. + + +Create a project +---------------- + +Here are the main steps to create an arm-autonomy project: + +1. create a new Yocto project using `oe-init-build-env` in a new directory: + ``` + oe-init-build-env my-project + ``` + +2. Add `meta-arm/meta-arm-autonomy` layer to the list of layers of your + project in the `conf/bblayers.conf`. Also add any other layers you + might need (for example `meta-arm/meta-arm-bsp` and `meta-arm/meta-arm` to + use Arm boards like Juno or FVP emulator). You can achieve this by using + the `bitbake-layers add-layer layerdir [layerdir ...]` command. + For example: + ``` + export LAYERDIR_BASE="/home/user/arm-autonomy/" + bitbake-layers add-layer $LAYERDIR_BASE/meta-poky $LAYERDIR_BASE/meta-yocto-bsp \ + $LAYERDIR_BASE/meta-openembedded/meta-oe $LAYERDIR_BASE/meta-openembedded/meta-python \ + $LAYERDIR_BASE/meta-openembedded/meta-filesystems $LAYERDIR_BASE/meta-openembedded/meta-networking \ + $LAYERDIR_BASE/meta-virtualization $LAYERDIR_BASE/meta-arm/meta-arm-autonomy \ + $LAYERDIR_BASE/meta-arm/meta-arm $LAYERDIR_BASE/meta-arm/meta-arm-bsp + ``` + + Example of a `conf/bblayers.conf`: + ``` + BBLAYERS ?= " \ + /home/user/arm-autonomy/poky/meta \ + /home/user/arm-autonomy/poky/meta-poky \ + /home/user/arm-autonomy/poky/meta-yocto-bsp \ + /home/user/arm-autonomy/meta-openembedded/meta-oe \ + /home/user/arm-autonomy/meta-openembedded/meta-python \ + /home/user/arm-autonomy/meta-openembedded/meta-filesystems \ + /home/user/arm-autonomy/meta-openembedded/meta-networking \ + /home/user/arm-autonomy/meta-virtualization \ + /home/user/arm-autonomy/meta-arm/meta-arm-autonomy \ + /home/user/arm-autonomy/meta-arm/meta-arm \ + /home/user/arm-autonomy/meta-arm/meta-arm-bsp \ + " + ``` + +Those steps will have to be done for each project you will have to create. + +Host project +------------ +The host project will build Xen and the Dom0 Linux. It will be the only project +that will be specific to the board (MACHINE) you will be running on. + +To create a host project: +1. Follow the steps of "Create a project" + +2. Add the layers in `bblayers.conf` required to build a Yocto project for the + board you want to use. + For example to use Arm FVP Base emulator, add `meta-arm/meta-arm` and + `meta-arm/meta-arm-bsp`. + +3. edit conf/local.conf to add `arm-autonomy-host` to the DISTRO_FEATURES and + set MACHINE to the board you want to use. + For example, add the following lines: + ``` + MACHINE = "fvp-base" + DISTRO_FEATURES += "arm-autonomy-host" + ``` + +4. build the image using `bitbake arm-autonomy-host-image-minimal` + +The project will generate a Linux kernel, a root filesystem, a Xen binary and +a DTB modified to include the required entries to boot Xen and Linux as Dom0 +(this DTB has the extension `-xen.dtb`). + +To boot the system using an u-boot base board you will need to: +- Load the kernel (by default at 0x80080000 unless you modify + XEN_DEVICETREE_DOM0_ADDR value) +- Load the xen device tree (for example at 0x83000000) +- Load the xen-efi binary (for example at 0x84000000) +- run using `booti 0x84000000 - 0x83000000` + +In this example the addresses might need to be adapted depending on your board. + +Guest project +------------- +The guest projects are not target specific and will use a Yocto MACHINE defined +in meta-arm-autonomy to include only the Linux configuration required to run +a xen guest. + +To create a guest project: + +1. Follow the steps of "Create a project" + +2. Optionaly add layers required to build the image and features you need. + +3. edit conf/local.conf to add `arm-autonomy-guest` to the DISTRO_FEATURES and + set MACHINE to `arm64-autonomy-guest`: + ``` + MACHINE = "arm64-autonomy-guest" + DISTRO_FEATURES += "arm-autonomy-guest" + ``` + +4. build the image you want. + For example `bitbake core-image-minimal` + +The build will create a ".xenguest" image that can be use on an host project +with the xenguest-manager. + +Include guests directly in the host image +----------------------------------------- +The layer provides a way to directly include in the host project one or several +images generated by guest projects. + +To use this feature, you must edit your host project `local.conf` file and +add set ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS to the list of xenguest images +you want to include in your host. Each xenguest image must be given using a +full path to it. +For example: +``` +ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS = "/home/user/guest-project/tmp/deploy/images/arm64-autonomy-guest/core-image-minimal-arm64-autonomy-guest.xenguest;guestname=myguest" +``` +This will add the guest and name it `myguest` on the host project image and +the xenguest-manager will automatically boot it during startup. + +Add support for your board +-------------------------- +Most of arm-autonomy layer is board independent but some functionalities +might need to be customized for your board: + +### Add the kernel configuration for the host +The layer is using KERNEL_FEATURES to add drivers required to be a Xen Dom0 +system. +Depending on the kernel used by your BSP and how it is configured you might +need to add the required drivers to your kernel configuration: +- if KERNEL_FEATURES system is supported by your kernel, make sure that the +file `recipes-kernel/linux/linux-arm-autonomy.inc` from the layer is included +by your kernel recipe. +- if it is not supported, you must add the proper drivers inside your kernel +(modules are possible but they must be loaded before xenguest-manager is +started). You can find the complete list of the kernel configuration elements +required in `recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.cfg`. + +### Define the drive and partition to use for the LVM volume +The xenguest-manager is creating disk hard drive using LVM on an empty +partition. The default value is set to use /dev/sda2. +You can change this for your board by setting XENGUEST_MANAGER_VOLUME_DEVICE. + +Check `recipes-extended/xenguest/xenguest-manager.bbappend` for examples. + +Please also read xenguest-manager.md. + +### Define the interface to add to xenguest network bridge +xenguest-network bridge is creating a bridge on the host and adds network +interfaces to it so that guest connected to it have access to external network. +By default `eth0` is set as the list of interfaces to be added to the bridge. +Depending on your board or use case you might want to use an other interface +or use multiple interfaces. +You can change this for your board by setting XENGUEST_NETWORK_BRIDGE_MEMBERS. + +Check `recipes-extended/xenguest/xenguest-network-bridge.bbappend` for +exmaples. + +Please also read xenguest-network-bridge.md. + +### Define the network configuration of the xenguest network bridge +xenguest network bridge is putting the host network interfaces in a bridge +and is configuring it by default to use dhcp. +If you need a different type of configuration you can set +XENGUEST_NETWORK_BRIDGE_CONFIG in a xenguest-network-bridge.bbappend to use +a different file. +The recipe will look for the file in ${WORKDIR} so you will need to add it to +SRC_URI in your bbappend. +The recipe will also substitute `###BRIDGE_NAME###` with the bridge name +configured in ${XENGUEST_NETWORK_BRIDGE_NAME}. + +You can find an example configuration file in +`recipes-extended/xenguest/files/xenguest-network-bridge-dhcp.cfg.in`. + +Please also read xenguest-network-bridge.md. + +### Customize Dom0 and Xen boot arguments for you board +xen-devicetree is writting inside the generated DTB Xen and Linux boot +arguments as long as the address where Dom0 Linux kernel can be found. +You might need to have different values for your board or depending on your +use case. + +You can find examples to customize this in +`recipes-extended/xen-devicetree/xen-devicetree.bbappend`. + +Please also read xen-devicetree.md. + diff --git a/bsp/meta-arm/meta-arm-autonomy/documentation/xen-devicetree.md b/bsp/meta-arm/meta-arm-autonomy/documentation/xen-devicetree.md new file mode 100644 index 00000000..a44dca78 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/documentation/xen-devicetree.md @@ -0,0 +1,104 @@ +Xen device tree +=============== + +Introduction +------------ + +xen-devicetree recipe can be used to modify an existing Device Tree Blob, +produced by Linux kernel or another recipe, to include in it entries required +to start Xen and a Dom0 Linux on top of it. + +The recipe will do the following processing: +- generate a xen.dtsi file with entries required for xen based on parameters +- turn DTBs in ${XEN_DEVICETREE_DTBS} back to dts +- include in xen.dtsi and all other dtsi from + ${XEN_DEVICETREE_DTSI_MERGE} (check Bitbake parameters for more information + on this). +- use dtc to create a new DTB file + +The recipe will generate new files in deploy/images and name them with the +extension "-xen.dtb". +For example **machine.dtb** will generate **machine-xen.dtb**. + +Entries added to the DTBs +------------------------- + +When a DTB is processed by the recipe, the following block is added: +``` + chosen { + xen,dom0-bootargs = "VAL"; + xen,xen-bootargs = "VAL"; + + modules { + #size-cells = <0x00000001>; + #address-cells = <0x00000001>; + + module@0 { + reg = <VAL VAL>; + compatible = "multiboot,module"; + }; + }; + }; +``` +Each occurence of **VAL** is replaced by the content of the variables listed in +this documentation. + +Bitbake parameters +------------------ + +Several parameters are available to configure the xen-devicetree during Yocto +project compilation (those can be set in your project local.conf, for exmple). + +The following parameters are available: + +- XEN_DEVICETREE_DEPEND: This variable can be used to indicate which recipe + task is generating the DTBs that xen-devicetree will modify. This makes sure + the xen devicetrees are properly regenerated if the source DTBs are changed. + This variable is set by default to "virtual/kernel:do_deploy" to use DTBs + generated during the compilation of the Linux kernel. This must be changed + if the machine your are using is not using a DTB listed in KERNEL_DEVICETREE. + +- XEN_DEVICETREE_DTBS: This should be set to the list of DTBs you want to be + modified by xen-devicetree. Those must be files that xen-devicetree can find + in the ${DEPLOY_DIR_IMAGE} directory using only the basename of the entries. + For example "mydir/board.dtb" will make the recipe look for + ${DEPLOY_DIR_IMAGE}/board.dtb. + This variable is set by default to "${KERNEL_DEVICETREE}" to process the DTBs + generated by the Linux kernel. + +- XEN_DEVICETREE_DOM0_MEM: Memory size to allocate to Dom0. + This variable is only used if XEN_DEVICETREE_XEN_BOOTARGS has a value + containing "dom0_mem=${XEN_DEVICETREE_DOM0_MEM}" as the memory assigned to + dom0 is defined using Xen boot arguments. + This variable is set by default to "1024M". + +- XEN_DEVICETREE_DOM0_BOOTARGS: Boot arguments to pass to Dom0 Linux when + booting it. + This variable is set by default to "console=hvc0 earlycon=xen". + +- XEN_DEVICETREE_XEN_BOOTARGS: this variable should be set with the boot + arguments to be passed to Xen on boot. + This variable is set by default to + "noreboot dom0_mem=${XEN_DEVICETREE_DOM0_MEM}". + +- XEN_DEVICETREE_DOM0_ADDR: This is the address from which the Linux kernel to + be used for Dom0 will be copied. When using u-boot, this is the address at + which you will load the kernel Image before starting Xen. + This variable is set by default to "0x80080000". + +- XEN_DEVICETREE_DOM0_SIZE: This is the size of the kernel loaded at + ${XEN_DEVICETREE_DOM0_ADDR}. Xen will copy this amount of data inside the + guest before starting it so the size must be at least equal to the kernel + size but can be bigger. You must be careful not to have a value too big as it + could slow down boot or copy other parts with it (like the DTB). + You might need to increase this if you use a kernel with a bundled initramfs. + This variable is set by default to "0x01000000". + +- XEN_DEVICETREE_DTSI_MERGE: This variable contains the list of dtsi files that + must be included inside the generated DTB file. By default the only one + include is the "xen.dtsi" generated by the recipe. + If your board or project needs to include more fixes or entries in the DTB, + this variable can be appended from a bbappend file to include other dtsi. The + files must be inside the recipe workspace during Yocto compilation. + You can check xen-devicetree.bbappend for an example. + diff --git a/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-manager.md b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-manager.md new file mode 100644 index 00000000..387af944 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-manager.md @@ -0,0 +1,67 @@ +Xenguest Manager +================ + +Introduction +------------ + +xenguest-manager is a tool to manage Xenguest images generated by +[xenguest-mkimage](xenguest-mkimage.md). + +On a Xen Dom0 system it will: +- create a xen guest from a xenguest image: extract its components, create a + disk for the guest using LVM volumes. +- start/stop a xen guest (during init or using xenguest-manager directly). +- check guest status + +xenguest-manager is composed of 2 shell scripts: +- xenguest-manager which can be used from command line to start/stop/check +guests and create or remove guest using xenguest images. +- xenguest-init which is called during init to automatically create and start +some guests as part of the host init process. + +Usage +----- + +xenguest-manager must be called like this: +`xenguest-manager OPERATION [OPTIONS]` +The following operations are available: +- create XENGUEST_IMAGE [GUESTNAME]: create a guest from a xenguest image file + as guest GUESTNAME. If GUESTNAME is not given the image file name is used + without the xenguest extension. +- remove GUESTNAME: remove the guest GUESTNAME. +- start GUESTNAME: start the guest GUESTNAME. +- stop GUESTNAME: stop the guest GUESTNAME (this is using `xl stop` which is + sending a stop signal to the running guest). +- kill GUESTNAME: force stopping the guest GUESTNAME. +- list: list the available guests. +- status [GUESTNAME]: print the current status of GUESTNAME. If GUESTNAME is + not given, print the status of all guests. + +For a detailed help on available options please use: +`xenguest-manager --help` + +Bitbake parameters +------------------ + +Several parameters are available to configure the xenguest manager during Yocto +project compilation (those can be set in your project local.conf, for example). + +The following parameters are available: + +- XENGUEST_MANAGER_VOLUME_DEVICE: This is the device path used by the + xenguest-manager on the device to create LVM disks when guests have a disk + configuration. + This is set by default to "/dev/sda2". + +- XENGUEST_MANAGER_VOLUME_NAME: This is the LVM volume name that the + xenguest-manager will create and use to create guest LVM disks. + This is set by default to "vg-xen". + +- XENGUEST_MANAGER_GUEST_DIR: This is the directory on Dom0 where the + xenguest-manager will look for xenguest images to create during init. That's + the place where xenguest images can be added to have them automatically + created during next Dom0 boot. The xenguests found there will only be created + if they were not already before (the basename of the files is used as guest + name). + This is set by default to "/usr/share/guests". + diff --git a/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-mkimage.md b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-mkimage.md new file mode 100644 index 00000000..3dcc28b4 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-mkimage.md @@ -0,0 +1,119 @@ +Xenguest mkimage +================ + +Introduction +------------ + +xenguest-mkimage is a tool to create and modify images to be used as Guest with +Xen. It defines a format to store completely defined guests as a file or as +a directory and provides options to create and modify those images. + +A xenguest image contains all elements required to create a xen guest. +This is the base elements like a Xen configuration and a Linux kernel binary +but also some more advanced elements like init scripts or a disk definition. + +The format is made to be deployable easily by storing everything in a single +file and provide tools to easily manipulate the images. It can also easily be +extended to have features like encryption or signature of images, updates or +complex configurations by providing features to have init script that will be +executed on the host embedded inside the image. + +Xenguest images content +----------------------- + +### params.cfg + +This file contains parameters that can be used by tools to configure some +functionalities on the host. This can be used by init scripts to have +configurable parameters as it is sourced before calling init scripts. + +### guest.cfg and guest.d + +guest.cfg is the main xen configuration and guest.d contains optional +configuration parts. All those will be merged into one final xen configuration +before starting the guest. + +### files +This directory contains files that can be used by the xen configuration, for +example the binary of the kernel referenced in xen configuration). +This is where the kernel binary, the dtb or a ramdisk will be stored. + +### init.pre, init.d and init.post +These directories contain init scripts that will be executed on the host +during the guest startup. Those must be shell scripts and each directory +contains scripts called at a different time: + - init.pre: scripts executed before the guest is created. This can be used + to prepare some features required to create the guest in xen or to + generate part of the xen configuration dynamically. + - init.d: scripts executed when the guest has been created but before it is + started. This can be used to do some xenstore operations or configure the + guest behaviour using xl, for example. + - init.post: scripts executed just after starting the guest. This can be + used to configure things created by xen for the guest like network + network interfaces. + +When a directory contains several scripts, those will be called in alphabetical +order. + +### disk.cfg and disk-files +disk.cfg contains the guest disk description (disk size and disk partitions). +The file contains the following entries: +- `DISK_SIZE=X`: size of the disk to create in GB +- `DISK_PARTX=SIZE:FS:CONTENT`: create a partition number X (1 to 4) with a + size of SIZE GB, format it with filesystem FS (can be ext2, ext3, ext4, vfat + or swap) and extract CONTENT as initial partition content + (.tar[.gz|.xz|.bz2] file or img[.gz|.bz2] file to be dumped in the partition). FS and + CONTENT can be empty. + +The disk-files contain files to be used for initializing the disk partitions +content. Those should be used to create a LVM or a physical disk and initialize +it (create partitions, format them and put the initial content). + +Usage +----- + +xenguest-mkimage is a shell script which must be called like this: +`xenguest-mkimage OPERATION XENGUEST [OPTIONS]` + +### Operations +- create: create a xenguest image. If XENGUEST is an existing empty directory, + the image is created as a directory otherwise it will be created as a file. +- check: verify that XENGUEST is a valid xenguest image. +- update: modify a xenguest image (see --help for a list of operations). +- pack: pack a xenguest image directory into a xenguest image file. The file to + be created must be given as 3rd argument. +- extract: extract a xenguest image file into a directory. The destination + directory must be given as 3rd argument. +- dump-xenconfig: dump xenguest image xen configuration. +- dump-diskconfig: dump xenguest image disk configuration. +- dump-paramsconfig: dump xenguest image parameters configuration. + +For a detailed help on available operations, please use: +`xenguest-mkimage --help` + +### Options +- --kernel=FILE: add kernel FILE as guest kernel. This is both adding the file + to the image and modifying the xen configuration to use it. +- --xen-memory=SIZE: set the guest memory size in MB. +- --xen-extra: add a kernel command line argument. This can be called several + times to add several command line options. +- --xen-device-tree=FILE: add dtb FILE as device tree. This both adding the + file to the image and modifying the xen configuration to use it. +- --init-script=FILE: add guest init script. The script is embedded inside the + image file. Several script can be added and the basename of FILE is used to + distinguish them (calling the option twice with the same file will update the + script in the image with the second one). + --disk-size=SIZE: set the guest disk size to SIZE in GB. Calling this with 0 + disable the guest disk. +- --disk-add-part=NUM:SIZE:FS:CONTENT: This is adding a partition to the + xenguest image disk. The partition is described with the arguments: + - NUM: partition number. + - SIZE: partition size in GB. + - FS: filesystem to format the partition with. This can be ext2, ext3, ext4, + vfat of swap. If empty the partition is not formated. + - CONTENT: tar of img file to use to initialize the partition. The file must + be added to the image using --disk-add-file=FILE:CONTENT. + +For a detailed help on available options, please use: +`xenguest-mkimage OPERATION --help` + diff --git a/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-network-bridge.md b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-network-bridge.md new file mode 100644 index 00000000..6653fe81 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/documentation/xenguest-network-bridge.md @@ -0,0 +1,49 @@ +xenguest network bridge +======================= + +Introduction +------------ + +xenguest-network-bridge is creating a network bridge to allow some guests to +have a direct connection to the external network. +To do this, a bridge is created on the host using brctl with the network +interfaces added to it so that the bridge is connected to the external network. +It is also adding a guest init script which will, for guests configured to use +it, create a virtual network interface for the guest and connect it to the +network bridge on the host. + +Usage +----- + +On the host the package xenguest-network-bridge must be included in your image. + +On the xenguest image of your guest, the parameter NETWORK_BRIDGE must be set +to 1 (using xenguest-mkimage --set-param=NETWORK_BRIDGE=1). + +Bitbake parameters +------------------ +Several parameters are available to configure the xenguest network bridge +during Yocto project compilation (those can be set in your project local.conf, +for example). + +The following parameters are available: + +- XENGUEST_NETWORK_BRIDGE_NAME: This variable defines the name of the network + bridge that is created on the host during init. + This is set by default to "xenbr0". + +- XENGUEST_NETWORK_BRIDGE_MEMBERS: This variable defines the list of network + interfaces that are added to the bridge when it is created on the host during + init. + This is set by default to "eth0". + +- XENGUEST_NETWORK_BRIDGE_CONFIG: This variable defines the configuration file + to use to configure the bridge network. By default it points to have file + configuring the network using dhcp. + You can provide a different file using a bbappend and make this variable + point to it if you want to customize your network configuration. + +- XENGUEST_IMAGE_NETWORK_BRIDGE: This variable can be set to 0 or 1 on guest + projects to enable or not the connection of the guest to the host bridge. + This is set by default to "1". + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/boot-wrapper-aaarch64/boot-wrapper-aarch64_%.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/boot-wrapper-aaarch64/boot-wrapper-aarch64_%.bbappend new file mode 100644 index 00000000..3b93b3b7 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/boot-wrapper-aaarch64/boot-wrapper-aarch64_%.bbappend @@ -0,0 +1,32 @@ +# Use OVERRIDES to minimize the usage of +# ${@bb.utils.contains('DISTRO_FEATURES', 'xen', ... +OVERRIDES_append = "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ':xen', '', d)}" + +# Xen image to put in the image +# This should point to a file in the deploy image directory +BOOT_WRAPPER_AARCH64_XEN ??= "xen-${MACHINE}" + +# Xen command line for the image +BOOT_WRAPPER_AARCH64_XEN_CMDLINE ??= "noreboot dom0_mem=256M" + +BOOT_WRAPPER_AARCH64_XEN_CMDLINE_gem5-arm64 = "noreboot dom0_mem=256M console=dtuart \ + dtuart=/uart@1c090000 bootscrub=0" + +# Fix command line in the axf file for gem5-arm64 when Xen is present +BOOT_WRAPPER_AARCH64_CMDLINE_xen_gem5-arm64 = "console=hvc0 root=/dev/vda rw" + +# Image generated by boot wrapper when Xen is present +BOOT_WRAPPER_AARCH64_IMAGE_xen ?= "xen-system.axf" + +EXTRA_OECONF_append_xen = " \ +--with-xen=${WORKDIR}/kernel/arch/arm64/boot/Image \ +--with-xen-cmdline="" \ +" + +EXTRA_OEMAKE_append_xen = " \ +XEN_IMAGE=${DEPLOY_DIR_IMAGE}/${BOOT_WRAPPER_AARCH64_XEN} \ +XEN_CMDLINE="${BOOT_WRAPPER_AARCH64_XEN_CMDLINE}" \ +" + +# We need xen if it is activated +do_deploy[depends] += "${@bb.utils.contains('DISTRO_FEATURES', 'xen', 'xen:do_deploy', '', d)}" diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno.bbappend new file mode 100644 index 00000000..b0aae695 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno.bbappend @@ -0,0 +1,21 @@ +# Use OVERRIDES to minimize the usage of +# ${@bb.utils.contains('DISTRO_FEATURES', 'xen', ... +OVERRIDES_append = "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ':xen', '', d)}" + +FILESEXTRAPATHS_prepend_xen := "${THISDIR}/${PN}:" + +DEPLOY_EXTRA_DEPS ??= "" +DEPLOY_EXTRA_DEPS_xen = "xen:do_deploy xen-devicetree:do_deploy" + +do_deploy[depends] += "${DEPLOY_EXTRA_DEPS}" + +do_deploy_prepend_xen() { + # To avoid dependency loop between firmware-image-juno:do_install, + # xen:do_deploy and xen-devicetree:do_deploy when + # INITRAMFS_IMAGE_BUNDLE = "1", we need to handle the xen and + # xen-devicetree binaries copying in the do_deploy task. + cp ${DEPLOY_DIR_IMAGE}/xen-${COMPATIBLE_MACHINE}.efi \ + ${D}/${UNPACK_DIR}/SOFTWARE/xen + cp ${DEPLOY_DIR_IMAGE}/*xen.dtb \ + ${D}/${UNPACK_DIR}/SOFTWARE/ +} diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r0.txt b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r0.txt new file mode 100644 index 00000000..ec32ca29 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r0.txt @@ -0,0 +1,78 @@ +TITLE: Versatile Express Images Configuration File + +[IMAGES] +TOTALIMAGES: 11 ;Number of Images (Max: 32) + +NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR0ADDRESS: 0x00000000 ;Image Flash Address +NOR0FILE: \SOFTWARE\fip.bin ;Image File Name +NOR0LOAD: 00000000 ;Image Load Address +NOR0ENTRY: 00000000 ;Image Entry Point + +NOR1UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR1ADDRESS: 0x03EC0000 ;Image Flash Address +NOR1FILE: \SOFTWARE\bl1.bin ;Image File Name +NOR1LOAD: 00000000 ;Image Load Address +NOR1ENTRY: 00000000 ;Image Entry Point + +NOR2UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR2ADDRESS: 0x00500000 ;Image Flash Address +NOR2FILE: \SOFTWARE\Image ;Image File Name +NOR2NAME: norkern ;Rename kernel to norkern +NOR2LOAD: 00000000 ;Image Load Address +NOR2ENTRY: 00000000 ;Image Entry Point + +NOR3UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR3ADDRESS: 0x02700000 ;Image Flash Address +NOR3FILE: \SOFTWARE\juno-xen.dtb ;Image File Name +NOR3NAME: board.dtb ;Specify target filename to preserve file extension +NOR3LOAD: 00000000 ;Image Load Address +NOR3ENTRY: 00000000 ;Image Entry Point + +NOR4UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR4ADDRESS: 0x01D00000 ;Image Flash Address +NOR4FILE: \SOFTWARE\xen ;Image File Name +NOR4NAME: xen +NOR4LOAD: 00000000 ;Image Load Address +NOR4ENTRY: 00000000 ;Image Entry Point + +NOR5UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR5ADDRESS: 0x025C0000 ;Image Flash Address +NOR5FILE: \SOFTWARE\hdlcdclk.dat ;Image File Name +NOR5LOAD: 00000000 ;Image Load Address +NOR5ENTRY: 00000000 ;Image Entry Point + +NOR6UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR6ADDRESS: 0x03E40000 ;Image Flash Address +NOR6FILE: \SOFTWARE\scp_bl1.bin ;Image File Name +NOR6LOAD: 00000000 ;Image Load Address +NOR6ENTRY: 00000000 ;Image Entry Point + +NOR7UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR7ADDRESS: 0x0BF00000 ;Image Flash Address +NOR7FILE: \SOFTWARE\startup.nsh ;Image File Name +NOR7NAME: startup.nsh +NOR7LOAD: 00000000 ;Image Load Address +NOR7ENTRY: 00000000 ;Image Entry Point + +NOR8UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR8ADDRESS: 0x0BFC0000 ;Image Flash Address +NOR8FILE: \SOFTWARE\blank.img ;Image File Name +NOR8NAME: BOOTENV +NOR8LOAD: 00000000 ;Image Load Address +NOR8ENTRY: 00000000 ;Image Entry Point + +NOR9UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR9ADDRESS: 0x02600000 ;Image Flash Address +NOR9FILE: \SOFTWARE\selftest ;Image File Name +NOR9LOAD: 00000000 ;Image Load Address +NOR9ENTRY: 00000000 ;Image Entry Point + +NOR10UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR10ADDRESS: 0x02780000 ;Image Flash Address +NOR10NAME: uEnv.txt +NOR10FILE: \SOFTWARE\uEnv.txt ;Image File Name +NOR10LOAD: 00000000 ;Image Load Address +NOR10ENTRY: 00000000 ;Image Entry Point + + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r1.txt b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r1.txt new file mode 100644 index 00000000..1372bc30 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r1.txt @@ -0,0 +1,78 @@ +TITLE: Versatile Express Images Configuration File + +[IMAGES] +TOTALIMAGES: 11 ;Number of Images (Max: 32) + +NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR0ADDRESS: 0x00000000 ;Image Flash Address +NOR0FILE: \SOFTWARE\fip.bin ;Image File Name +NOR0LOAD: 00000000 ;Image Load Address +NOR0ENTRY: 00000000 ;Image Entry Point + +NOR1UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR1ADDRESS: 0x03EC0000 ;Image Flash Address +NOR1FILE: \SOFTWARE\bl1.bin ;Image File Name +NOR1LOAD: 00000000 ;Image Load Address +NOR1ENTRY: 00000000 ;Image Entry Point + +NOR2UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR2ADDRESS: 0x00500000 ;Image Flash Address +NOR2FILE: \SOFTWARE\Image ;Image File Name +NOR2NAME: norkern ;Rename kernel to norkern +NOR2LOAD: 00000000 ;Image Load Address +NOR2ENTRY: 00000000 ;Image Entry Point + +NOR3UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR3ADDRESS: 0x02700000 ;Image Flash Address +NOR3FILE: \SOFTWARE\juno-r1-xen.dtb ;Image File Name +NOR3NAME: board.dtb ;Specify target filename to preserve file extension +NOR3LOAD: 00000000 ;Image Load Address +NOR3ENTRY: 00000000 ;Image Entry Point + +NOR4UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR4ADDRESS: 0x01D00000 ;Image Flash Address +NOR4FILE: \SOFTWARE\xen ;Image File Name +NOR4NAME: xen +NOR4LOAD: 00000000 ;Image Load Address +NOR4ENTRY: 00000000 ;Image Entry Point + +NOR5UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR5ADDRESS: 0x025C0000 ;Image Flash Address +NOR5FILE: \SOFTWARE\hdlcdclk.dat ;Image File Name +NOR5LOAD: 00000000 ;Image Load Address +NOR5ENTRY: 00000000 ;Image Entry Point + +NOR6UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR6ADDRESS: 0x03E40000 ;Image Flash Address +NOR6FILE: \SOFTWARE\scp_bl1.bin ;Image File Name +NOR6LOAD: 00000000 ;Image Load Address +NOR6ENTRY: 00000000 ;Image Entry Point + +NOR7UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR7ADDRESS: 0x0BF00000 ;Image Flash Address +NOR7FILE: \SOFTWARE\startup.nsh ;Image File Name +NOR7NAME: startup.nsh +NOR7LOAD: 00000000 ;Image Load Address +NOR7ENTRY: 00000000 ;Image Entry Point + +NOR8UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR8ADDRESS: 0x0BFC0000 ;Image Flash Address +NOR8FILE: \SOFTWARE\blank.img ;Image File Name +NOR8NAME: BOOTENV +NOR8LOAD: 00000000 ;Image Load Address +NOR8ENTRY: 00000000 ;Image Entry Point + +NOR9UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR9ADDRESS: 0x02600000 ;Image Flash Address +NOR9FILE: \SOFTWARE\selftest ;Image File Name +NOR9LOAD: 00000000 ;Image Load Address +NOR9ENTRY: 00000000 ;Image Entry Point + +NOR10UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR10ADDRESS: 0x02780000 ;Image Flash Address +NOR10NAME: uEnv.txt +NOR10FILE: \SOFTWARE\uEnv.txt ;Image File Name +NOR10LOAD: 00000000 ;Image Load Address +NOR10ENTRY: 00000000 ;Image Entry Point + + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r2.txt b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r2.txt new file mode 100644 index 00000000..def465e1 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/images-r2.txt @@ -0,0 +1,78 @@ +TITLE: Versatile Express Images Configuration File + +[IMAGES] +TOTALIMAGES: 11 ;Number of Images (Max: 32) + +NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR0ADDRESS: 0x00000000 ;Image Flash Address +NOR0FILE: \SOFTWARE\fip.bin ;Image File Name +NOR0LOAD: 00000000 ;Image Load Address +NOR0ENTRY: 00000000 ;Image Entry Point + +NOR1UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR1ADDRESS: 0x03EC0000 ;Image Flash Address +NOR1FILE: \SOFTWARE\bl1.bin ;Image File Name +NOR1LOAD: 00000000 ;Image Load Address +NOR1ENTRY: 00000000 ;Image Entry Point + +NOR2UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR2ADDRESS: 0x00500000 ;Image Flash Address +NOR2FILE: \SOFTWARE\Image ;Image File Name +NOR2NAME: norkern ;Rename kernel to norkern +NOR2LOAD: 00000000 ;Image Load Address +NOR2ENTRY: 00000000 ;Image Entry Point + +NOR3UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR3ADDRESS: 0x02700000 ;Image Flash Address +NOR3FILE: \SOFTWARE\juno-r2-xen.dtb ;Image File Name +NOR3NAME: board.dtb ;Specify target filename to preserve file extension +NOR3LOAD: 00000000 ;Image Load Address +NOR3ENTRY: 00000000 ;Image Entry Point + +NOR4UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR4ADDRESS: 0x01D00000 ;Image Flash Address +NOR4FILE: \SOFTWARE\xen ;Image File Name +NOR4NAME: xen +NOR4LOAD: 00000000 ;Image Load Address +NOR4ENTRY: 00000000 ;Image Entry Point + +NOR5UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR5ADDRESS: 0x025C0000 ;Image Flash Address +NOR5FILE: \SOFTWARE\hdlcdclk.dat ;Image File Name +NOR5LOAD: 00000000 ;Image Load Address +NOR5ENTRY: 00000000 ;Image Entry Point + +NOR6UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR6ADDRESS: 0x03E40000 ;Image Flash Address +NOR6FILE: \SOFTWARE\scp_bl1.bin ;Image File Name +NOR6LOAD: 00000000 ;Image Load Address +NOR6ENTRY: 00000000 ;Image Entry Point + +NOR7UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR7ADDRESS: 0x0BF00000 ;Image Flash Address +NOR7FILE: \SOFTWARE\startup.nsh ;Image File Name +NOR7NAME: startup.nsh +NOR7LOAD: 00000000 ;Image Load Address +NOR7ENTRY: 00000000 ;Image Entry Point + +NOR8UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR8ADDRESS: 0x0BFC0000 ;Image Flash Address +NOR8FILE: \SOFTWARE\blank.img ;Image File Name +NOR8NAME: BOOTENV +NOR8LOAD: 00000000 ;Image Load Address +NOR8ENTRY: 00000000 ;Image Entry Point + +NOR9UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR9ADDRESS: 0x02600000 ;Image Flash Address +NOR9FILE: \SOFTWARE\selftest ;Image File Name +NOR9LOAD: 00000000 ;Image Load Address +NOR9ENTRY: 00000000 ;Image Entry Point + +NOR10UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR10ADDRESS: 0x02780000 ;Image Flash Address +NOR10NAME: uEnv.txt +NOR10FILE: \SOFTWARE\uEnv.txt ;Image File Name +NOR10LOAD: 00000000 ;Image Load Address +NOR10ENTRY: 00000000 ;Image Entry Point + + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/uEnv.txt b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/uEnv.txt new file mode 100644 index 00000000..4307b696 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-bsp/images/firmware-image-juno/uEnv.txt @@ -0,0 +1,15 @@ +xen_name=xen +xen_addr=0x84000000 +uenvcmd=run mybootcmd +mybootcmd=echo Loading custom boot command; \ +echo Loading kernel; \ +afs load ${kernel_name} ${kernel_addr} ; \ +if test $? -eq 1; then echo Loading ${kernel_alt_name} instead of ${kernel_name}; afs load ${kernel_alt_name} ${kernel_addr}; fi; \ +echo Loading device tree; \ +afs load ${fdtfile} ${fdt_addr}; \ +if test $? -eq 1; then echo Loading ${fdt_alt_name} instead of ${fdtfile}; \ +afs load ${fdt_alt_name} ${fdt_addr}; fi; fdt addr ${fdt_addr}; fdt resize; \ +echo Loading Xen; \ +afs load ${xen_name} ${xen_addr}; \ +if test $? -eq 0; then echo Booting Xen; bootefi ${xen_addr} ${fdt_addr}; fi; + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-juno.dtsi b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-juno.dtsi new file mode 100644 index 00000000..0f9af21f --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-juno.dtsi @@ -0,0 +1,11 @@ +/* + * Disable IOMMU on juno board when Xen is used + */ + +/ { + + /* turn off iommu */ + iommu@2b600000 { + status = "disabled"; + }; +}; diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-n1sdp.dtsi b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-n1sdp.dtsi new file mode 100644 index 00000000..01ec14a8 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/files/xen-n1sdp.dtsi @@ -0,0 +1,39 @@ +/* + * Modify N1SDP DTB to work properly when Xen is used + */ + +/ { + + /* + * pmu is using PPI interrupts which are reserved by xen + * remove pm nodes + */ + /delete-node/ pmu; + /delete-node/ spe-pmu; + + /* + * disable IOMMU until we have a proper support in xen + */ + /delete-node/ iommu@4f000000; + /delete-node/ iommu@4f400000; + + /* + * Set extra registers required for PCI quirks to communicate with SCP + * and remove invalid properties due to removal + */ + pcie@68000000 { + reg = <0 0x68000000 0 0x1200000>, + <0 0x06000000 0 0x80000>, + <0 0x62000000 0 0x80000>; + /delete-property/ msi-map; + /delete-property/ iommu-map; + }; + + pcie@70000000 { + reg = <0 0x70000000 0 0x1200000>, + <0 0x06000000 0 0x80000>, + <0 0x60000000 0 0x80000>; + /delete-property/ msi-map; + /delete-property/ iommu-map; + }; +}; diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/xen-devicetree.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/xen-devicetree.bbappend new file mode 100644 index 00000000..006d0b78 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen-devicetree/xen-devicetree.bbappend @@ -0,0 +1,25 @@ +# Platform dependent parameters + +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" + +# Add a dtb snippet to turn off iommu in dom0 on Juno board +SRC_URI_append_juno = " file://xen-juno.dtsi" +XEN_DEVICETREE_DTSI_MERGE_append_juno = " xen-juno.dtsi" + +# Add a dtb snippet to remove pmu and iommu in dom0 on N1SDP +SRC_URI_append_n1sdp = " file://xen-n1sdp.dtsi" +XEN_DEVICETREE_DTSI_MERGE_append_n1sdp = " xen-n1sdp.dtsi" + +# Board specific configs +XEN_DEVICETREE_DOM0_BOOTARGS_append_juno = " root=/dev/sda1 rootwait" +XEN_DEVICETREE_XEN_BOOTARGS_append_juno = " console=dtuart dtuart=serial0 bootscrub=0 iommu=no" + +XEN_DEVICETREE_DOM0_BOOTARGS_append_n1sdp = " root=/dev/sda1 rootwait" +XEN_DEVICETREE_XEN_BOOTARGS_append_n1sdp = " console=dtuart dtuart=serial0 bootscrub=0 iommu=no" + +XEN_DEVICETREE_DOM0_BOOTARGS_append_fvp-base = " root=/dev/vda2" +XEN_DEVICETREE_XEN_BOOTARGS_append_fvp-base = " console=dtuart dtuart=serial0 bootscrub=0" + +XEN_DEVICETREE_DOM0_BOOTARGS_append_foundation-armv8 = " root=/dev/vda2" +XEN_DEVICETREE_XEN_BOOTARGS_append_foundation-armv8 = " console=dtuart dtuart=serial0 bootscrub=0" + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/4.12.0/0001-xen-arm-Cap-the-number-of-interrupt-lines-for-dom0.patch b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/4.12.0/0001-xen-arm-Cap-the-number-of-interrupt-lines-for-dom0.patch new file mode 100644 index 00000000..792bc9ea --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/4.12.0/0001-xen-arm-Cap-the-number-of-interrupt-lines-for-dom0.patch @@ -0,0 +1,44 @@ +From a41feccdb6c03f12bddb4fb650a0465f0ed6eeca Mon Sep 17 00:00:00 2001 +From: Lukas Juenger <juenger@ice.rwth-aachen.de> +Date: Fri, 5 Apr 2019 15:54:04 +0200 +Subject: [PATCH] xen/arm: Cap the number of interrupt lines for dom0 + +Dom0 vGIC will use the same number of interrupt lines as the hardware GIC. +While the hardware GIC can support up to 1020 interrupt lines, +the vGIC is only supporting up to 992 interrupt lines. +This means that Xen will not be able to boot on platforms where the hardware +GIC supports more than 992 interrupt lines. +While it would make sense to increase the limits in the vGICs, this is not +trivial because of the design choices. +At the moment, only models seem to report the maximum of interrupt lines. +They also do not have any interrupt wired above the 992 limit. +So it should be fine to cap the number of interrupt lines for dom0 to 992 lines. + +Signed-off-by: Lukas Juenger <juenger@ice.rwth-aachen.de> +Acked-by: Julien Grall <julien.grall@arm.com> +--- + xen/arch/arm/setup.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c +index 444857a967..ccb0f181ea 100644 +--- a/xen/arch/arm/setup.c ++++ b/xen/arch/arm/setup.c +@@ -888,7 +888,13 @@ void __init start_xen(unsigned long boot_phys_offset, + /* Create initial domain 0. */ + /* The vGIC for DOM0 is exactly emulating the hardware GIC */ + dom0_cfg.arch.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE; +- dom0_cfg.arch.nr_spis = gic_number_lines() - 32; ++ /* ++ * Xen vGIC supports a maximum of 992 interrupt lines. ++ * 32 are substracted to cover local IRQs. ++ */ ++ dom0_cfg.arch.nr_spis = min(gic_number_lines(), (unsigned int) 992) - 32; ++ if ( gic_number_lines() > 992 ) ++ printk(XENLOG_WARNING "Maximum number of vGIC IRQs exceeded.\n"); + dom0_cfg.max_vcpus = dom0_max_vcpus(); + + dom0 = domain_create(0, &dom0_cfg, true); +-- +2.17.1 + diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/fvp/defconfig b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/fvp/defconfig new file mode 100644 index 00000000..f13327c1 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/fvp/defconfig @@ -0,0 +1,73 @@ +# +# Automatically generated file; DO NOT EDIT. +# Xen/arm 4.12.0 Configuration +# +CONFIG_64BIT=y +CONFIG_ARM_64=y +CONFIG_ARM=y +CONFIG_ARCH_DEFCONFIG="arch/arm/configs/arm64_defconfig" + +# +# Architecture Features +# +CONFIG_NR_CPUS=128 +CONFIG_GICV3=y +CONFIG_HVM=y +# CONFIG_NEW_VGIC is not set +CONFIG_SBSA_VUART_CONSOLE=y +CONFIG_ARM_SSBD=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y + +# +# ARM errata workaround via the alternative framework +# +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_834220=y +CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y +CONFIG_ALL_PLAT=y +# CONFIG_QEMU is not set +# CONFIG_RCAR3 is not set +# CONFIG_MPSOC is not set +# CONFIG_NO_PLAT is not set +CONFIG_ALL64_PLAT=y +# CONFIG_ALL32_PLAT is not set +CONFIG_MPSOC_PLATFORM=y + +# +# Common Features +# +CONFIG_HAS_ALTERNATIVE=y +CONFIG_HAS_DEVICE_TREE=y +CONFIG_MEM_ACCESS=y +CONFIG_HAS_PDX=y +# CONFIG_XSM is not set +CONFIG_SCHED_CREDIT=y +CONFIG_SCHED_CREDIT2=y +CONFIG_SCHED_RTDS=y +# CONFIG_SCHED_ARINC653 is not set +CONFIG_SCHED_NULL=y +CONFIG_SCHED_DEFAULT="credit2" +# CONFIG_LIVEPATCH is not set +CONFIG_SUPPRESS_DUPLICATE_SYMBOL_WARNINGS=y +CONFIG_CMDLINE="" +CONFIG_DOM0_MEM="" + +# +# Device Drivers +# +CONFIG_HAS_NS16550=y +CONFIG_HAS_CADENCE_UART=y +CONFIG_HAS_MVEBU=y +CONFIG_HAS_PL011=y +CONFIG_HAS_SCIF=y +CONFIG_HAS_PASSTHROUGH=y +CONFIG_ARM_SMMU=y +CONFIG_DEFCONFIG_LIST="arch/arm/configs/arm64_defconfig" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/juno/defconfig b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/juno/defconfig new file mode 100644 index 00000000..f13327c1 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/juno/defconfig @@ -0,0 +1,73 @@ +# +# Automatically generated file; DO NOT EDIT. +# Xen/arm 4.12.0 Configuration +# +CONFIG_64BIT=y +CONFIG_ARM_64=y +CONFIG_ARM=y +CONFIG_ARCH_DEFCONFIG="arch/arm/configs/arm64_defconfig" + +# +# Architecture Features +# +CONFIG_NR_CPUS=128 +CONFIG_GICV3=y +CONFIG_HVM=y +# CONFIG_NEW_VGIC is not set +CONFIG_SBSA_VUART_CONSOLE=y +CONFIG_ARM_SSBD=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y + +# +# ARM errata workaround via the alternative framework +# +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_834220=y +CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y +CONFIG_ALL_PLAT=y +# CONFIG_QEMU is not set +# CONFIG_RCAR3 is not set +# CONFIG_MPSOC is not set +# CONFIG_NO_PLAT is not set +CONFIG_ALL64_PLAT=y +# CONFIG_ALL32_PLAT is not set +CONFIG_MPSOC_PLATFORM=y + +# +# Common Features +# +CONFIG_HAS_ALTERNATIVE=y +CONFIG_HAS_DEVICE_TREE=y +CONFIG_MEM_ACCESS=y +CONFIG_HAS_PDX=y +# CONFIG_XSM is not set +CONFIG_SCHED_CREDIT=y +CONFIG_SCHED_CREDIT2=y +CONFIG_SCHED_RTDS=y +# CONFIG_SCHED_ARINC653 is not set +CONFIG_SCHED_NULL=y +CONFIG_SCHED_DEFAULT="credit2" +# CONFIG_LIVEPATCH is not set +CONFIG_SUPPRESS_DUPLICATE_SYMBOL_WARNINGS=y +CONFIG_CMDLINE="" +CONFIG_DOM0_MEM="" + +# +# Device Drivers +# +CONFIG_HAS_NS16550=y +CONFIG_HAS_CADENCE_UART=y +CONFIG_HAS_MVEBU=y +CONFIG_HAS_PL011=y +CONFIG_HAS_SCIF=y +CONFIG_HAS_PASSTHROUGH=y +CONFIG_ARM_SMMU=y +CONFIG_DEFCONFIG_LIST="arch/arm/configs/arm64_defconfig" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/n1sdp/defconfig b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/n1sdp/defconfig new file mode 100644 index 00000000..e8a88c1b --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/files/n1sdp/defconfig @@ -0,0 +1,100 @@ +# +# Automatically generated file; DO NOT EDIT. +# Xen/arm 4.12.2 Configuration +# +CONFIG_64BIT=y +CONFIG_ARM_64=y +CONFIG_ARM=y +CONFIG_ARCH_DEFCONFIG="arch/arm/configs/arm64_defconfig" + +# +# Architecture Features +# +CONFIG_NR_CPUS=128 +CONFIG_ACPI=y +CONFIG_GICV3=y +CONFIG_HAS_ITS=y +CONFIG_HVM=y +# CONFIG_NEW_VGIC is not set +CONFIG_SBSA_VUART_CONSOLE=y +CONFIG_ARM_SSBD=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y + +# +# ARM errata workaround via the alternative framework +# +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_834220=y +CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y +CONFIG_ALL_PLAT=y +# CONFIG_QEMU is not set +# CONFIG_RCAR3 is not set +# CONFIG_MPSOC is not set +# CONFIG_NO_PLAT is not set +CONFIG_ALL64_PLAT=y +# CONFIG_ALL32_PLAT is not set +CONFIG_MPSOC_PLATFORM=y + +# +# Common Features +# +CONFIG_HAS_ALTERNATIVE=y +CONFIG_HAS_DEVICE_TREE=y +# CONFIG_MEM_ACCESS is not set +CONFIG_HAS_PDX=y +# CONFIG_TMEM is not set +CONFIG_XSM=y +CONFIG_XSM_FLASK=y +CONFIG_XSM_FLASK_AVC_STATS=y +# CONFIG_XSM_FLASK_POLICY is not set +CONFIG_XSM_SILO=y +# CONFIG_XSM_DUMMY_DEFAULT is not set +# CONFIG_XSM_FLASK_DEFAULT is not set +CONFIG_XSM_SILO_DEFAULT=y +# CONFIG_ARGO is not set + +# +# Schedulers +# +CONFIG_SCHED_CREDIT=y +CONFIG_SCHED_CREDIT2=y +CONFIG_SCHED_RTDS=y +# CONFIG_SCHED_ARINC653 is not set +CONFIG_SCHED_NULL=y +# CONFIG_SCHED_CREDIT_DEFAULT is not set +CONFIG_SCHED_CREDIT2_DEFAULT=y +# CONFIG_SCHED_RTDS_DEFAULT is not set +# CONFIG_SCHED_NULL_DEFAULT is not set +CONFIG_SCHED_DEFAULT="credit2" +# CONFIG_LIVEPATCH is not set +CONFIG_SUPPRESS_DUPLICATE_SYMBOL_WARNINGS=y +CONFIG_CMDLINE="" +CONFIG_DOM0_MEM="" + +# +# Device Drivers +# +CONFIG_HAS_NS16550=y +CONFIG_HAS_CADENCE_UART=y +CONFIG_HAS_MVEBU=y +CONFIG_HAS_PL011=y +CONFIG_HAS_SCIF=y +CONFIG_HAS_PASSTHROUGH=y +CONFIG_ARM_SMMU=y +CONFIG_DEFCONFIG_LIST="arch/arm/configs/arm64_defconfig" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +CONFIG_DEBUG_INFO=y +# CONFIG_FRAME_POINTER is not set +# CONFIG_COVERAGE is not set +# CONFIG_LOCK_PROFILE is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VERBOSE_DEBUG=y +# CONFIG_DEVICE_TREE_DEBUG is not set +# CONFIG_SCRUB_DEBUG is not set diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/xen_%.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/xen_%.bbappend new file mode 100644 index 00000000..bdcb75f9 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xen/xen_%.bbappend @@ -0,0 +1,32 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" + +# Machine specific settings +XEN_CONFIG_EARLY_PRINTK_juno = "juno" +XEN_CONFIG_EARLY_PRINTK_gem5-arm64 = "vexpress" +XEN_CONFIG_EARLY_PRINTK_fvp-base = "fastmodel" +XEN_CONFIG_EARLY_PRINTK_foundation-armv8 = "fastmodel" +XEN_CONFIG_EARLY_PRINTK_n1sdp = "pl011,0x2a400000" + +# Foundation-armv8 support +COMPATIBLE_MACHINE_foundation-armv8 = "foundation-armv8" + +SRC_URI_append_foundation-armv8 = " file://fvp/defconfig" + +# FVP Base support +COMPATIBLE_MACHINE_fvp-base = "fvp-base" + +SRC_URI_append_fvp-base = " file://fvp/defconfig" + +# Juno support +COMPATIBLE_MACHINE_juno = "juno" + +SRC_URI_append_juno = " file://juno/defconfig" + +# Gem5 support +# Fix problem with number of interrupts on gem5 +SRC_URI_append_gem5-arm64 = " file://4.12.0/0001-xen-arm-Cap-the-number-of-interrupt-lines-for-dom0.patch" + +# N1SDP support +COMPATIBLE_MACHINE_n1sdp = "n1sdp" + +SRC_URI_append_n1sdp = " file://n1sdp/defconfig" diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-manager.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-manager.bbappend new file mode 100644 index 00000000..874cfede --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-manager.bbappend @@ -0,0 +1,6 @@ +# Board specific configuration for the manager + +# FVP and Foundation are using vda as hard drive and partition 2 is the +# default rootfs, so use vda3 for guest lvm +XENGUEST_MANAGER_VOLUME_DEVICE_foundation-armv8 ?= "/dev/vda3" +XENGUEST_MANAGER_VOLUME_DEVICE_fvp-base ?= "/dev/vda3" diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-network-bridge.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-network-bridge.bbappend new file mode 100644 index 00000000..dc849210 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-extended/xenguest/xenguest-network-bridge.bbappend @@ -0,0 +1,2 @@ +# Juno board has 2 network interfaces, add both of them to the bridge +XENGUEST_NETWORK_BRIDGE_MEMBERS_juno ?= "eth0 eth1" diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.cfg b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.cfg new file mode 100644 index 00000000..7e87cab4 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.cfg @@ -0,0 +1,4 @@ +# We need to turn off SVE support in the Linux kernel otherwise Xen is stopping +# Linux kernel with a coredump while trying to access ZEN bit of CPACR1 core +# register. +# CONFIG_ARM64_SVE is not set diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.scc b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.scc new file mode 100644 index 00000000..6bc769cc --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/arm-autonomy-kmeta-extra/features/arm-autonomy/disable-arm64-sve.scc @@ -0,0 +1,3 @@ +define KFEATURE_DESCRIPTION "Disable SVE support" + +kconf non-hardware disable-arm64-sve.cfg diff --git a/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/linux-%.bbappend b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/linux-%.bbappend new file mode 100644 index 00000000..189645af --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/dynamic-layers/meta-arm-bsp/recipes-kernel/linux/linux-%.bbappend @@ -0,0 +1,17 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}:" + +# +# arm-autonomy kmeta extra +# +SRC_URI_append = " file://arm-autonomy-kmeta-extra;type=kmeta;name=arm-autonomy-kmeta-extra;destsuffix=arm-autonomy-kmeta-extra" + +# We need to turn off SVE support in the Linux kernel otherwise Xen is stopping +# Linux kernel with a coredump while trying to access XEN bit of CPACR1 core +# register. +LINUX_ARM_AUTONOMY_DISABLE_ARM64_SVE = "${@bb.utils.contains_any('DISTRO_FEATURES', \ + 'arm-autonomy-host arm-autonomy-guest', \ + ' features/arm-autonomy/disable-arm64-sve.scc','',d)}" + +KERNEL_FEATURES_append_gem5-arm64 = "${LINUX_ARM_AUTONOMY_DISABLE_ARM64_SVE}" +KERNEL_FEATURES_append_fvp-base = "${LINUX_ARM_AUTONOMY_DISABLE_ARM64_SVE}" +KERNEL_FEATURES_append_foundation-armv8 = "${LINUX_ARM_AUTONOMY_DISABLE_ARM64_SVE}" diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb new file mode 100644 index 00000000..5b20fa09 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-core/images/arm-autonomy-host-image-minimal.bb @@ -0,0 +1,120 @@ +# Recipe to create a minimal Arm Autonomy stack host image + +DESCRIPTION = "Arm Autonomy stack host minimal image" + +inherit core-image + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +# The ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS variable can be used to include in the +# image one or several xenguest images. +# The list must be space separated and each entry must have the following +# format: URL[;guestname=NAME] +# - URL can be the full path to a file or a Yocto compatible SRC_URI url +# - guestname=NAME can be used to specify the name of the guest. If not +# specified the basename of the file (without .xenguest extension) is used. +# Here are examples of values: +# /home/mydir/myguest.xenguest;guestname=guest1 +# http://www.url.com/testguest.xenguest +# +# If you are using the output of an other Yocto project, you should use the +# full path syntax instead of the Yocto SRC_URI to be able to use the +# symlink version of your image (as the real file has a new name on each +# build as it includes the date). You must not use SRC_URI type file:// as +# it will try to include the symlink and not the destination file which will +# be detected by the recipe and output an error 'Guest file is a symlink'. +# +# Guests can also be added using a bbapend to this recipe by adding entries +# to SRC_URI with parameter ;guestname=NAME to specify the destination +# guestname. The parameter guestname must be present as it is used to detect +# guests to be added +ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS ??= "" + +#Â Includes minimal set required to start and manage guest. The xen specific +# modules are not explicitly included as they are built as part of the kernel +# image for performance reasons. It doesn't include all kernel modules to +# reduce the image size. If the kernel-modules packages are needed they can +# be appended to IMAGE_INSTALL in a bbappend. +IMAGE_INSTALL += " \ + packagegroup-core-boot \ + packagegroup-core-ssh-openssh \ + qemu-xen \ + xenguest-manager \ + xenguest-network-bridge \ + " + +# Build xen binary +EXTRA_IMAGEDEPENDS += "xen" + +# Build xen-devicetree to produce a xen ready devicetree +EXTRA_IMAGEDEPENDS += "xen-devicetree" + +python __anonymous() { + if bb.utils.contains('DISTRO_FEATURES', 'arm-autonomy-host', False, True, d): + raise bb.parse.SkipRecipe("DISTRO_FEATURES does not contain 'arm-autonomy-host'") + + if bb.utils.contains('DISTRO_FEATURES', 'xen', False, True, d): + raise bb.parse.SkipRecipe("DISTRO_FEATURES does not contain 'xen'") + + # Check in ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS for extra guests and add them + # to SRC_URI with xenguest parameter if not set + guestlist = d.getVar('ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS') + if guestlist: + for guest in guestlist.split(): + # If the user just specified a file instead of file://FILE, add + # the file:// prefix + if guest.startswith('/'): + guestfile = '' + guestname = '' + if ';guestname=' in guest: + # user specified a guestname + guestname = guest.split(';guestname=')[1] + guestfile = guest.split(';guestname=')[0] + else: + # no guestname so use the basename + guestname = os.path.basename(guest) + guestfile = guest + # in case we have a link we need the destination + guestfile = os.path.realpath(guestfile) + + # make sure the file exist to give a meaningfull error + if not os.path.exists(guestfile): + raise bb.parse.SkipRecipe("ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS entry does not exist: " + guest) + + # In case the file is a symlink make sure we use the destination + d.appendVar('SRC_URI', ' file://' + guestfile + ';guestname=' + guestname) + else: + # we have a Yocto URL + try: + _, _, path, _, _, parm = bb.fetch.decodeurl(guest) + # force guestname param in if not already there + if not 'guestname' in parm: + guest += ';guestname=' + os.path.basename(path) + d.appendVar('SRC_URI', ' ' + guest) + except: + raise bb.parse.SkipRecipe("ARM_AUTONOMY_HOST_IMAGE_EXTERN_GUESTS contains an invalid entry: " + guest) +} + +python add_extern_guests () { + # Destination directory on the rootfs + guestdir = d.getVar('IMAGE_ROOTFS') + d.getVar('datadir') + '/guests' + + # Parse SRC_URI for files with ;guestname= parameter + src_uri = d.getVar('SRC_URI') + for entry in src_uri.split(): + _, _, path, _, _, parm = bb.fetch.decodeurl(entry) + if 'guestname' in parm: + if os.path.islink(path): + bb.fatal("Guest file is a symlink: " + path) + bb.utils.mkdirhier(guestdir) + dstname = parm['guestname'] + # Add file extension if not there + if not dstname.endswith('.xenguest'): + dstname += '.xenguest' + if not bb.utils.copyfile(path, guestdir + '/' + dstname): + bb.fatal("Fail to copy Guest file " + path) +} + +IMAGE_PREPROCESS_COMMAND += "add_extern_guests; " + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend b/bsp/meta-arm/meta-arm-autonomy/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend new file mode 100644 index 00000000..1d97e50c --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend @@ -0,0 +1,18 @@ +# Add support for interface configuration via interfaces.d directory. This +# feature can be used by other packages to add network interface +# configuration by adding network network interface configuration file under +# interfaces.d directory. + +do_install_append() { + # Add scan of interfaces.d to interfaces file + cp -f ${WORKDIR}/interfaces ${WORKDIR}/interfaces.subdir + echo "source-directory ${sysconfdir}/network/interfaces.d/" \ + >> ${WORKDIR}/interfaces.subdir + + # Create interfaces.d script in case nobody is adding a script + # so that there is no error about non existing directory + install -d -m 755 ${D}${sysconfdir}/network/interfaces.d + + # Install our file instead of the original one + install -m 644 interfaces.subdir ${D}${sysconfdir}/network/interfaces +} diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-core/sysvinit/sysvinit-inittab_2.%.bbappend b/bsp/meta-arm/meta-arm-autonomy/recipes-core/sysvinit/sysvinit-inittab_2.%.bbappend new file mode 100644 index 00000000..7b0c6472 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-core/sysvinit/sysvinit-inittab_2.%.bbappend @@ -0,0 +1,16 @@ +# if arm-autonomy-guest is activated, we are running as a xen guest so we must +# have a console on hvc0 +# This is normally done in meta-virtualization if xen is activated but here +# we don't have xen activated. +# + +SYSVINIT_ADDHVC0 = "${@bb.utils.contains('DISTRO_FEATURES', \ + 'arm-autonomy-guest', 'true', 'false', d)}" + +do_install_append() { + if ${SYSVINIT_ADDHVC0}; then + echo "" >> ${D}${sysconfdir}/inittab + echo "X0:12345:respawn:/sbin/getty 115200 hvc0" >> \ + ${D}${sysconfdir}/inittab + fi +} diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-devtools/qemu/qemu_%.bbappend b/bsp/meta-arm/meta-arm-autonomy/recipes-devtools/qemu/qemu_%.bbappend new file mode 100644 index 00000000..ed63a4e9 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-devtools/qemu/qemu_%.bbappend @@ -0,0 +1,18 @@ +# Use OVERRIDES to minimize the usage of +# ${@bb.utils.contains('DISTRO_FEATURES', 'xen', ... +OVERRIDES_append = "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ':xen', '', d)}" + +# For Xen we only need the i386 binaries +QEMU_TARGETS_xen = "i386" + +PACKAGECONFIG[noaudio] = "--audio-drv-list='',," +PACKAGECONFIG_append_xen = " virtfs noaudio" +PACKAGECONFIG_remove_xen = "sdl" + +# Reduce the qemu package size by splitting it into +# qemu and qemu-xen packages +PACKAGES_prepend_xen := "${PN}-xen" +RDEPENDS_${PN}_xen += "${PN}-xen" +FILES_${PN}-xen_xen = "${bindir}/qemu-system-i386" +RDEPENDS_${PN}-xen_xen += "xen-tools-libxenstore xen-tools-libxenctrl \ + xen-tools-libxenguest" diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/files/xen.dtsi.in b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/files/xen.dtsi.in new file mode 100644 index 00000000..42d12fae --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/files/xen.dtsi.in @@ -0,0 +1,17 @@ +/ { + chosen { + xen,dom0-bootargs = "###XEN_DOM0_BOOTARGS###"; + xen,xen-bootargs = "###XEN_XEN_BOOTARGS###"; + + modules { + #size-cells = <0x00000001>; + #address-cells = <0x00000001>; + + module@0 { + reg = <###XEN_DOM0_ADDR### ###XEN_DOM0_SIZE###>; + compatible = "multiboot,module"; + }; + }; + }; +}; + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/xen-devicetree.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/xen-devicetree.bb new file mode 100644 index 00000000..cef5f79e --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/xen-devicetree.bb @@ -0,0 +1,72 @@ +# This recipe can be used to modify one or several DTBS to add +# entries required to declare and boot Linux as Dom0 from Xen + +SRC_URI = "file://xen.dtsi.in" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "\ + file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302 \ + " + +S = "${WORKDIR}" + +DESCRIPTION = "Add entries in DTB for Xen and Dom0" + +# Please refer to documentation/xen-devicetree.md for documentation on those +# parameters +XEN_DEVICETREE_DEPEND ?= "virtual/kernel:do_deploy" +XEN_DEVICETREE_DTBS ?= "${KERNEL_DEVICETREE}" +XEN_DEVICETREE_XEN_BOOTARGS ?= "noreboot dom0_mem=${XEN_DEVICETREE_DOM0_MEM}" +XEN_DEVICETREE_DOM0_MEM ?= "1024M" +XEN_DEVICETREE_DOM0_BOOTARGS ?= "console=hvc0 earlycon=xen" +XEN_DEVICETREE_DOM0_ADDR ?= "0x80080000" +XEN_DEVICETREE_DOM0_SIZE ?= "0x01000000" +XEN_DEVICETREE_DTSI_MERGE ?= "xen.dtsi" + +# Our package does not generate any package for the rootfs but contributes to +# deploy +inherit nopackages deploy + +DEPENDS += "dtc-native" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" +do_install[noexec] = "1" + +do_deploy() { + if [ ! -f ${WORKDIR}/xen.dtsi.in ]; then + die "xen.dtsi.in does not exist" + fi + cat ${WORKDIR}/xen.dtsi.in \ + | sed -e "s,###XEN_DOM0_BOOTARGS###,${XEN_DEVICETREE_DOM0_BOOTARGS}," \ + | sed -e "s,###XEN_XEN_BOOTARGS###,${XEN_DEVICETREE_XEN_BOOTARGS}," \ + | sed -e "s,###XEN_DOM0_ADDR###,${XEN_DEVICETREE_DOM0_ADDR}," \ + | sed -e "s,###XEN_DOM0_SIZE###,${XEN_DEVICETREE_DOM0_SIZE}," \ + > ${WORKDIR}/xen.dtsi + + # Generate final dtbs + for dtbf in ${XEN_DEVICETREE_DTBS}; do + rdtb=`basename $dtbf` + if [ ! -f ${DEPLOY_DIR_IMAGE}/$rdtb ]; then + die "Wrong file in XEN_DEVICETREE_DTBS: ${DEPLOY_DIR_IMAGE}/$rdtb does not exist" + fi + dtc -I dtb -O dts -o ${WORKDIR}/dom0-linux.dts ${DEPLOY_DIR_IMAGE}/$rdtb + + # Add external includes + for inc in ${XEN_DEVICETREE_DTSI_MERGE}; do + if [ ! -f ${WORKDIR}/${inc} ]; then + die "Wrong file in XEN_DEVICETREE_DTSI_MERGE: ${WORKDIR}/${inc} does not exist" + fi + echo "/include/ \"$inc\"" >> ${WORKDIR}/dom0-linux.dts + done + + rdtbnoextn=`basename $dtbf ".dtb"` + dtc -I dts -O dtb \ + -o ${WORKDIR}/${rdtbnoextn}-xen.dtb ${WORKDIR}/dom0-linux.dts + install -m 644 ${rdtbnoextn}-xen.dtb ${DEPLOYDIR}/. + done +} +do_deploy[depends] += "${XEN_DEVICETREE_DEPEND}" + +addtask deploy after do_install + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen/xen_%.bbappend b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen/xen_%.bbappend new file mode 100644 index 00000000..846d2442 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen/xen_%.bbappend @@ -0,0 +1,14 @@ +# +# Define early console based on board parameters +# + +XEN_CONFIG_EARLY_PRINTK ??= "disable" + +EXTRA_OEMAKE += "${@bb.utils.contains('XEN_CONFIG_EARLY_PRINTK', 'disable', \ + '', ' CONFIG_DEBUG=y CONFIG_EARLY_PRINTK=${XEN_CONFIG_EARLY_PRINTK}',d)}" + +# Make Xen machine specific +# This ensures that sstate is properly handled and that each machine can have +# its own configuration +PACKAGE_ARCH = "${MACHINE_ARCH}" + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/network-bridge.sh.in b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/network-bridge.sh.in new file mode 100755 index 00000000..2a360964 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/network-bridge.sh.in @@ -0,0 +1,15 @@ +#!/bin/sh +# This script is setting up a virtual network interface connected to the +# xenguest-network-bridge if NETWORK_BRIDGE is set to 1 in the guest params + +guestname="${1}" + +BRIDGE_NAME="###BRIDGE_NAME###" + +# get guest parameters +. ./params.cfg + +if [ "${NETWORK_BRIDGE:-}" = "1" ]; then + echo "vif = ['${BRIDGE_NAME}']" >> ${guestname}.cfg +fi + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-init b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-init new file mode 100755 index 00000000..9563d2fc --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-init @@ -0,0 +1,85 @@ +#!/bin/bash +# +# xenguest Init Script to start and stop xenguests during boot +# + +XENGUEST_CONF_BASE="/etc/xenguest" + +if [ ! -f ${XENGUEST_CONF_BASE}/xenguest-manager.conf ]; then + echo "No xenguest manager configuration !!" + exit 1 +fi + +source ${XENGUEST_CONF_BASE}/xenguest-manager.conf + +# Create guest list +guestlist=$(/usr/bin/xenguest-manager list) + +# Unconfigured guests + +case "$1" in + start) + echo "Starting xenguest" + + # Create unconfigured guests + if [ -d ${XENGUEST_GUEST_DIR} ]; then + for f in $(find ${XENGUEST_GUEST_DIR} -name "*.xenguest" \ + -exec basename {} .xenguest \;); do + if [ ! -f ${XENGUEST_CONF_BASE}/guests/${f}/guest.cfg ]; then + # Check if this guest should be auto booted + autoboot=$(/usr/bin/xenguest-mkimage dump-paramsconfig \ + ${XENGUEST_GUEST_DIR}/${f}.xenguest | \ + grep GUEST_AUTOBOOT | sed -e "s,.*=,," | tr -d '"') + if [ "$autoboot" = "0" ]; then + echo "Do not create $f, autoboot disabled" + else + /usr/bin/xenguest-manager create \ + ${XENGUEST_GUEST_DIR}/${f}.xenguest + # Update guestlist + if [ $? -eq 0 ]; then + guestlist="${guestlist} ${f}" + fi + fi + fi + done + fi + if [ -n "${guestlist}" ]; then + for f in ${guestlist}; do + GUEST_AUTOBOOT="1" + if [ -f ${XENGUEST_CONF_BASE}/guests/${f}/params.cfg ]; then + source ${XENGUEST_CONF_BASE}/guests/${f}/params.cfg + fi + if [ "${GUEST_AUTOBOOT}" = "1" ]; then + /usr/bin/xenguest-manager start ${f} + fi + done + else + echo "No guest configured" + fi + ;; + status) + true + ;; + stop) + echo "Stopping xenguest" + for f in ${guestlist}; do + /usr/bin/xenguest-manager stop ${f} + done + ;; + reload) + echo >&2 'Reload not available; use force-reload'; exit 1 + ;; + force-reload|restart) + echo "Restarting xenguest" + $0 stop + $0 start + ;; + *) + # do not advertise unreasonable commands that there is no reason + # to use with this device + echo $"Usage: $0 {start|stop|status|restart|force-reload}" + exit 1 +esac + +exit $? + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager new file mode 100755 index 00000000..99975a24 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager @@ -0,0 +1,665 @@ +#!/bin/bash +# This script manages xenguest +# +set -u +this="$0" + +XENGUEST_CONF_BASE="/etc/xenguest" +LOGFILE="/var/log/xenguest" + +if [ ! -f ${XENGUEST_CONF_BASE}/xenguest-manager.conf ]; then + echo "Cannot find xenguest manager configuration" + exit 1 +fi + +# Following variables must be set in configuration: +# XENGUEST_VOLUME_DEVICE: device to use for lvm +# XENGUEST_VOLUME_NAME: lvm volume name to create on device +source ${XENGUEST_CONF_BASE}/xenguest-manager.conf + +PREF="xenguest:" + +function usage() { + cat <<EOF +Usage $this ACTION [OPTIONS] + +with ACTION being one of: + help + Display this help + + create GUESTFILE [GUESTNAME] + Create a guest using xenguest image GUESTFILE and name it GUESTNAME. + This will extract and configure the guest and will also create the guest + disk if guest has one configured. + GUESTNAME is set to the basename of GUESTFILE if unspecified. + GUESTNAME guest must not exist + + remove GUESTNAME + Remove GUESTNAME and destroy its disk (if it has one) + + start GUESTNAME + Start guest GUESTNAME + + stop|shutdown GUESTNAME + Stop guest GUESTNAME (send stop signal and let it shutdown normally) + + kill|destroy GUESTNAME + Kill guest GUESTNAME (stop directly the guest without signaling it) + + list + List configured guests + + status + List guests and their current status (running or stopped) +EOF +} + +function xenguest_volume_init() +{ + if [ -z "${XENGUEST_VOLUME_DEVICE:-}" -o \ + ! -b ${XENGUEST_VOLUME_DEVICE:-} ]; then + echo "${PREF} Invalid volume device in configuration: ${XENGUEST_VOLUME_DEVICE:-}" + exit 1 + fi + + if [ -z "${XENGUEST_VOLUME_NAME:-}" ]; then + echo "${PREF} No volume name in configuration, using vg-xen..." + XENGUEST_VOLUME_NAME="vg-xen" + fi + + pvs ${XENGUEST_VOLUME_DEVICE} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Initialize lvm on ${XENGUEST_VOLUME_DEVICE}" + echo "pvcreate -f ${XENGUEST_VOLUME_DEVICE}" >> ${LOGFILE} 2>&1 + pvcreate -f ${XENGUEST_VOLUME_DEVICE} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error" + exit 1 + fi + fi + vgs ${XENGUEST_VOLUME_NAME} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Create ${XENGUEST_VOLUME_NAME} volume" + echo "vgcreate ${XENGUEST_VOLUME_NAME} ${XENGUEST_VOLUME_DEVICE}" \ + >> ${LOGFILE} 2>&1 + vgcreate ${XENGUEST_VOLUME_NAME} ${XENGUEST_VOLUME_DEVICE} \ + >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error" + exit 1 + fi + fi +} + +# Detach a disk we attached to xen +function xenguest_detach_disk() +{ + echo "xl block-detach 0 \$\(xl block-list 0 | " \ + "grep \"domain/0\" | awk '{print \$1}'\)" \ + >> ${LOGFILE} 2>&1 + xl block-detach 0 $(xl block-list 0 | \ + grep "domain/0" | awk '{print $1}') \ + >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error detaching partition ${part}" + exit 1 + fi +} + +function xenguest_disk_init() +{ + guestname="$1" + guestfile="$2" + devname="/dev/${XENGUEST_VOLUME_NAME}/${guestname}" + + source ${XENGUEST_CONF_BASE}/guests/${guestname}/disk.cfg + + if [ ${DISK_SIZE:-0} -eq 0 ]; then + echo "${PREF} No disk for ${guestname}" + return + fi + + echo "${PREF} Create ${guestname} disk" + + # Init our volume + xenguest_volume_init + + echo "${PREF} Create hard drive for ${guestname}" + + + # Remove volume if it already exist + echo "lvs ${XENGUEST_VOLUME_NAME}/${guestname}" >> ${LOGFILE} 2>&1 + lvs ${XENGUEST_VOLUME_NAME}/${guestname} >> ${LOGFILE} 2>&1 + if [ $? -eq 0 ]; then + echo "lvremove -y ${devname}" >> ${LOGFILE} 2>&1 + lvremove -y ${devname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error removing volume ${guestname}" + exit 1 + fi + fi + + # Create volume + echo "lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME}" \ + >> ${LOGFILE} 2>&1 + lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME} \ + >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error creating volume ${guestname}" + exit 1 + fi + + # Add partition table + echo "parted -s ${devname} mklabel msdos" >> ${LOGFILE} 2>&1 + parted -s ${devname} mklabel msdos >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error creating partition table on ${guestname}" + exit 1 + fi + + # Setup disk name in xen configuration + echo "xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname}" \ + "--xen-disk=${devname}" >> ${LOGFILE} 2>&1 + xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname} \ + --xen-disk=${devname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error setting disk in xen configuration" + exit 1 + fi + + # Create partitions + partstart="0" + + # For each partition X the disk.cfg file should set a variable DISK_PARTX + # with a : separated list defining the partition: + # DISK_PART3="4:ext4:disk.tgz" means that partition 3 should be 4G formated + # with ext4 and initialized with the content of disk.tgz + for part in $(seq 1 4); do + eval partdesc="\${DISK_PART${part}:-0}" + size=$(echo ${partdesc} | sed -e "s/\(.*\):.*:.*/\1/") + fstype=$(echo ${partdesc} | sed -e "s/.*:\(.*\):.*/\1/") + content=$(echo ${partdesc} | sed -e "s/.*:.*:\(.*\)/\1/") + + if [ "${size}" -ne 0 ]; then + # Size is expressed in GB, pass it in MB + size=$(expr ${size} \* 1024) + partend=$(expr ${partstart} + ${size}) + + # Let first MB of disk free for partition table + if [ ${partstart} -eq 0 ]; then + partstart="1" + fi + + # Create partition + echo "parted -s ${devname} unit MB mkpart primary ${partstart}" \ + "${partend}" >> ${LOGFILE} 2>&1 + parted -s ${devname} unit MB mkpart primary ${partstart} \ + ${partend} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error adding partition ${part}" + exit 1 + fi + + # Set next partition start to current partition end + partstart="${partend}" + + # Sync to see the created partition + echo "sync" >> ${LOGFILE} 2>&1 + sync >> ${LOGFILE} 2>&1 + + # Prepare format command + if [ -n "${fstype}" ]; then + case ${fstype} in + vfat|ext2|ext3|ext4) + formatcmd="mkfs.${fstype} -F" + ;; + swap) + formatcmd="mkswap" + ;; + *) + echo "${PREF} partition ${part} of ${guestname}" \ + "fstype is invalid: ${fstype}" + exit 1 + ;; + esac + else + formatcmd="" + fi + + # Attach disk to xen + echo "xl block-attach 0 phy:${devname} xvda w" >> ${LOGFILE} 2>&1 + xl block-attach 0 phy:${devname} xvda w >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error attaching partition ${part}" + exit 1 + fi + + + # Loop for 20s to wait until /dev/xvdaX appears + i=0 + while [ ! -b /dev/xvda${part} ]; do + ((i++)) + if [[ "$i" == '40' ]]; then + break; + fi + sleep 0.5 + done + + if [ ! -b /dev/xvda${part} ]; then + echo "${PREF} Partition ${part} creation error" + xenguest_detach_disk + exit 1 + fi + + if [ -n "${formatcmd}" ]; then + echo "${formatcmd} /dev/xvda${part}" >> ${LOGFILE} 2>&1 + ${formatcmd} /dev/xvda${part} + if [ $? -ne 0 ]; then + echo "${PREF} Cannot create partition ${part} FS" + xenguest_detach_disk + exit 1 + fi + fi + + case ${content} in + *.img*) + decompress="" + case ${content} in + *.img.gz) + decompress='zcat' + ;; + *.img.bz2) + decompress='bzcat' + ;; + *.img) + decompress='cat' + ;; + *) + # invalid/unknown compression type + echo "${PREF} Invalid file format in disk ${content}" + xenguest_detach_disk + exit 1 + ;; + esac + # dd into partition + echo "xenguest-mkimage extract-disk-file ${guestfile} " \ + "${content} | ${decompress} | dd of=/dev/xvda${part} " >> ${LOGFILE} 2>&1 + xenguest-mkimage extract-disk-file ${guestfile} ${content} \ + | ${decompress} | dd of=/dev/xvda${part} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Cannot populate partition ${part}" + xenguest_detach_disk + exit 1 + fi + ;; + *.tar*) + tararg="" + case ${content} in + *.tar.gz) + tararg="z" + ;; + *.tar.bz2) + tararg="j" + ;; + *.tar.xz) + tararg="J" + ;; + *.tar) + tararg="" + ;; + *) + # invalid/unknown tar type + echo "${PREF} Invalid file format in disk ${content}" + xenguest_detach_disk + exit 1 + ;; + esac + + # must mount the partition and extract + mntdir=$(mktemp -d) + echo "mount /dev/xvda${part} ${mntdir}" >> ${LOGFILE} 2>&1 + mount /dev/xvda${part} ${mntdir} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Cannot mount partition ${part}" + xenguest_detach_disk + rm -rf ${mntdir} + exit 1 + fi + + # tar and unmount + echo "xenguest-mkimage extract-disk-file ${guestfile}" \ + "${content} | tar -C ${mntdir} -x${tararg}f - " \ + >> ${LOGFILE} 2>&1 + xenguest-mkimage extract-disk-file ${guestfile} ${content} \ + | tar -C ${mntdir} -x${tararg}f - >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Cannot populate partition ${part}" + umount ${mntdir} + rm -rf ${mntdir} + xenguest_detach_disk + exit 1 + fi + echo "umount ${mntdir}" >> ${LOGFILE} 2>&1 + umount ${mntdir} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error unmounting ${part}" + xenguest_detach_disk + rm -rf ${mntdir} + exit 1 + fi + rm -rf ${mntdir} + ;; + *) + #invalid content type + ;; + esac + + # Detach disk + xenguest_detach_disk + fi + done + +} + +function xenguest_guest_create() +{ + guestfile="$1" + guestname="$2" + + # extract xenguest tar + # put xen config in etc ? + # if disk config file: + # disk init + # add partititions + + echo "${PREF} Create ${guestname} using ${guestfile}" + rm -rf ${XENGUEST_CONF_BASE}/guests/${guestname} + mkdir -p ${XENGUEST_CONF_BASE}/guests/${guestname} + + echo "xenguest-mkimage extract-config ${guestfile}" \ + "${XENGUEST_CONF_BASE}/guests/${guestname}" >> ${LOGFILE} 2>&1 + xenguest-mkimage extract-config ${guestfile} \ + ${XENGUEST_CONF_BASE}/guests/${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error extracting guest image" + exit 1 + fi + + # Set guest name inside config + echo "xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname}" \ + "--xen-name=${guestname}" >> ${LOGFILE} 2>&1 + xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname} \ + --xen-name=${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error setting guest name" + exit 1 + fi + + xenguest_disk_init ${guestname} ${guestfile} +} + +function xenguest_guest_remove() +{ + guestname="$1" + devname="/dev/${XENGUEST_VOLUME_NAME}/${guestname}" + + # check if guest had a volume + echo "lvs ${XENGUEST_VOLUME_NAME}/${guestname}" >> ${LOGFILE} 2>&1 + lvs ${XENGUEST_VOLUME_NAME}/${guestname} >> ${LOGFILE} 2>&1 + if [ $? -eq 0 ]; then + # Remove guest volume + echo "lvremove -y ${devname}" >> ${LOGFILE} 2>&1 + lvremove -y ${devname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error removing volume ${guestname}" + exit 1 + fi + fi + + # remove guest files + rm -rf ${XENGUEST_CONF_BASE}/guests/${guestname} +} + +function xenguest_guest_start() +{ + guestname="${1}" + guestdir=${XENGUEST_CONF_BASE}/guests/${guestname} + + # Get guest configuration + source ${guestdir}/params.cfg + + pushd ${guestdir} > /dev/null 2>&1 + + # create config by merging all configurations together + cat guest.cfg $(find guest.d -type f 2> /dev/null) > ${guestname}.cfg + + # Build init script lists (ignore non existing dirs errors, + # sort alphabetically and run global scripts first) + init_pre="$(find ${XENGUEST_CONF_BASE}/init.pre -type f 2> /dev/null | \ + sort) $(find ${guestdir}/init.pre -type f 2> /dev/null | sort)" + init_d="$(find ${XENGUEST_CONF_BASE}/init.d -type f 2> /dev/null | \ + sort) $(find ${guestdir}/init.d -type f 2> /dev/null | sort)" + init_post="$(find ${XENGUEST_CONF_BASE}/init.post -type f 2> /dev/null | \ + sort) $(find ${guestdir}/init.post -type f 2> /dev/null | sort)" + + # call pre init scripts + for f in ${init_pre}; do + echo "$f ${guestname}" >> ${LOGFILE} 2>&1 + $f ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + rm -f ${guestname}.cfg + popd > /dev/null 2>&1 + echo "${PREF} Error during pre init script of ${guestname}" + exit 1 + fi + done + + # Create non started guest + echo "xl create -p ${guestname}.cfg" >> ${LOGFILE} 2>&1 + xl create -p ${guestname}.cfg >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + rm -f ${guestname}.cfg + popd > /dev/null 2>&1 + echo "${PREF} Error starting ${guestname}" + exit 1 + fi + + # call init scripts + for f in ${init_d}; do + echo "$f ${guestname}" >> ${LOGFILE} 2>&1 + $f ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + rm -f ${guestname}.cfg + echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1 + xl destroy ${guestname} >> ${LOGFILE} 2>&1 + popd > /dev/null 2>&1 + echo "${PREF} Error during init script of ${guestname}" + exit 1 + fi + done + + # Start guest + echo "xl unpause ${guestname}" >> ${LOGFILE} 2>&1 + xl unpause ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + rm -f ${guestname}.cfg + popd > /dev/null 2>&1 + echo "${PREF} Error starting ${guestname}" + exit 1 + fi + + # call post init scripts + for f in ${init_post}; do + echo "$f ${guestname}" >> ${LOGFILE} 2>&1 + $f ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + rm -f ${guestname}.cfg + echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1 + xl destroy ${guestname} >> ${LOGFILE} 2>&1 + popd > /dev/null 2>&1 + echo "${PREF} Error during post init script of ${guestname}" + exit 1 + fi + done + + rm -f ${guestname}.cfg + popd > /dev/null 2>&1 +} + +function xenguest_guest_stop() +{ + guestname="${1}" + echo "xl shutdown ${guestname}" >> ${LOGFILE} 2>&1 + xl shutdown ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error stopping ${guestname}" + exit 1 + fi +} + +function check_guest_arg() +{ + cmd="${1}" + guestname="${2:-}" + if [ -z "${guestname:-}" ]; then + echo "${PREF} Usage ${this} ${cmd} GUESTNAME" + exit 1 + fi +} + +function check_guest_exist() +{ + guestname="${1}" + if [ ! -f ${XENGUEST_CONF_BASE}/guests/${guestname}/guest.cfg -o \ + ! -f ${XENGUEST_CONF_BASE}/guests/${guestname}/params.cfg ]; then + echo "${PREF} Invalid guest name: ${guestname}" + exit 1 + fi +} + +function check_guest_running() +{ + guestname="${1}" + running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" || echo) + if [ ! "${running}" = "${guestname}" ]; then + echo "${PREF} Guest ${guestname} is not running" + exit 1 + fi +} + +function check_guest_not_running() +{ + guestname="${1}" + running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" || echo) + if [ "${running}" = "${guestname}" ]; then + echo "${PREF} Guest ${guestname} is running" + exit 1 + fi +} + +cmd="${1:-help}" +arg1="${2:-}" +arg2="${3:-}" + +case ${cmd} in + help|--help|-h|-?) + usage + exit 0 + ;; + create) + guestfile="${arg1}" + guestname="${arg2}" + if [ -z "${guestfile}" -o ! -f "${guestfile}" ]; then + echo "${PREF} Usage ${this} create XENGUEST_FILE [NAME]" + exit 1 + fi + if [ -z "${guestname}" ]; then + guestname=$(basename ${guestfile} .xenguest) + fi + + if [ -f ${XENGUEST_CONF_BASE}/guests/${guestname}/guest.cfg ]; then + # Guest already exist + echo "${PREF} A guest ${guestname} already exist" + exit 1 + fi + + xenguest_guest_create ${guestfile} ${guestname} + ;; + remove) + guestname="${arg1:-}" + check_guest_arg ${cmd} ${guestname} + check_guest_exist ${guestname} + # We need to stop the guest first + running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" \ + || echo) + if [ "${running}" = "${guestname}" ]; then + echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1 + xl destroy ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error killing ${guestname}" + exit 1 + fi + fi + xenguest_guest_remove ${guestname} + ;; + start) + guestname="${arg1:-}" + check_guest_arg ${cmd} ${guestname} + check_guest_exist ${guestname} + check_guest_not_running ${guestname} + xenguest_guest_start ${guestname} + ;; + stop|shutdown) + guestname="${arg1:-}" + check_guest_arg ${cmd} ${guestname} + check_guest_exist ${guestname} + check_guest_running ${guestname} + xenguest_guest_stop ${guestname} + ;; + kill|destroy) + guestname="${arg1:-}" + check_guest_arg ${cmd} ${guestname} + check_guest_exist ${guestname} + check_guest_running ${guestname} + echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1 + xl destroy ${guestname} >> ${LOGFILE} 2>&1 + if [ $? -ne 0 ]; then + echo "${PREF} Error killing ${guestname}" + exit 1 + fi + ;; + list) + if [ -d ${XENGUEST_CONF_BASE}/guests ]; then + for f in $(find ${XENGUEST_CONF_BASE}/guests -mindepth 1 \ + -maxdepth 1 -type d -exec basename {} \;); do + if [ -f ${XENGUEST_CONF_BASE}/guests/$f/guest.cfg ]; then + echo "$f" + fi + done + fi + ;; + status) + guestname="${arg1}" + if [ -n "${guestname}" ]; then + check_guest_exist ${guestname} + if xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" > \ + /dev/null 2>&1; then + echo "${guestname}: Running" + else + echo "${guestname}: Stopped" + fi + else + guestlist=$($this list) + if [ -n "${guestlist}" ]; then + for f in ${guestlist}; do + $this status $f + done + fi + fi + ;; + *) + echo "${PREF} Invalid argument ${cmd}" + exit 1 + ;; +esac + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage new file mode 100755 index 00000000..4c1b4a87 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage @@ -0,0 +1,772 @@ +#!/bin/bash +# This script must be used to manipulate xenguest images +# +# xenguest image topology: +# params.cfg: guest global configuration file. Only edited using this script. +# guest.cfg: xen main configuration file. Only edited using this script. +# guest.d: directory contains files with custom xen configuration entries +# which are appended to guest.cfg before starting the guest +# files: directory where files used by xen configuration are stored +# disk.cfg: guest disk configuration file. Only edited using this script. +# (dtb, kernel image, etc) +# disk: directory where files for disk creation are stored +# init.[pre,d,post]: directories containing init pre, base and post scripts +set -u +set -e + +this="$0" + +IMAGE_TMPDIR="" + +usage() { + cat <<EOF +Usage $this ACTION XENGUEST [ARGS] + +Where XENGUEST is a xenguest image file or a xenguest directory. + +The following actions are supported: +help Display this help +create Create a xenguest image +update Update/modify a xenguest image +partial Create partial xenguest image in a directory +pack Pack a xenguest directory into an image +check Check a xenguest image +dump-paramsconfig Display the guest configuration of a xenguest image +dump-xenconfig Display the xen configuration of a xenguest image +dump-diskconfig Display the disk configuration of a xenguest image +dump-init Display init scripts of a xenguest image +extract Extract a xenguest image content +extract-config Extract the guest configuration from a xenguest image +extract-disk-file Extract a disk file from a xenguest image +Use $this ACTION --help to have help on a specific action and its arguments. +EOF +} + +usage-check() { + cat <<EOF +Usage $this check XENGUEST + +Check a xenguest image or a xenguest directory. +EOF +} + +usage-update-create() { + cat <<EOF +All arguments are handled in order. + +Global configuration for the guest +--guest-config-reset reset guest global configuration +--set-param=PARAM disable parameter PARAM in guest global configuration +--set-param=PARAM=VAL set parameter PARAM to value VAL in guest global + configuration. + Example of parameters supported are: + GUEST_AUTOBOOT: if set to 1 (default), guest will be + automatically created and started during host init. + +Xen configuration for the guest +--xen-reset-config reset xen guest configuration to default +--xen-name= disable name parameter in xen configuration +--xen-name=NAME set guest name in xen configuration +--xen-kernel= disable guest kernel parameter in xen configuration +--xen-kernel=FILE set guest kernel to FILE (file is added and xen + configuration is set to use it) +--xen-memory set guest memory size (in MB) +--xen-vcpus set guest number of virtual cpus +--xen-clean-extra set guest command line (extra) to an empty string +--xen-extra=ARG append ARG to the guest command line (with space) + use this several time to set command line. + To set the command line to "console=ttyS0 rw" do + --xen-extra=console=ttyS0 --xen-extra=rw +--xen-root= disable root parameter in xen configuration +--xen-root=ROOT set guest root in xen configuration +--xen-device-tree= disable device tree parameter in xen configuration +--xen-device-tree=FILE set guest device tree in xen configuration and add + file to xen files +--xen-disk= disable disk parameter in xen configuration +--xen-disk=DEV set guest disk to device DEV (phy:DEV,xvda,w is set) +--xen-append=FILE append FILE content to xen configuration + +Xen files +--xen-add-file=SRC:DST add file SRC as file DST in the xenguest image. + If DST already exist in the image, it is overwritten. + DST must be the same as arguments passed to other + options (like --xen-kernel) +--xen-rm-file=DST remove file DST from the xenguest image. + +Init configuration + This can be used to add init scripts for the guest. There are 3 possible init + scripts which are called at different time. The pre scripts are called first, + then the xen guest is created in pause and standard init scripts are called. + Finally the xen guest is started then the post init scripts are called. + Each script is called with the name of the guest as first argument and + multiple scripts can be added (they must have different names). + +--init-script=FILE add FILE as init script +--init-pre=FILE add FILE as pre init script +--init-post=FILE add FILE as post init script + +Disk configuration +--disk-reset-config reset disk guest configuration to default (no disk) +--disk-size=SZ set guest disk size (in GB) +--disk-device=DEV set device to be used to create the guest disk + if unset or set to an empty string, the volume will be + create in the default manager volume group. +--disk-add-part=DEF add a partition to the guest disk with definition DEF + a partition definition must have the following format: + ID:SIZE:FORMAT:CONTENT where: + - ID is the partition numeric ID (1 to 4) + - FORMAT is the filesystem format (supported formats + are none, vfat, swap, ext2, ext3 and ext4) or can be + left empty to not format + - CONTENT can be used to point to a file added using + --disk-add-file to be used as partition initial + content (tar file or img file) +--disk-rm-part=ID remove partition ID from the guest disk +--disk-add-file=SRC:DST add file SRC as disk file DST in the xenguest image. + DST can then be used as a partition CONTENT. +--disk--rm-file=DST remove disk file DST from the xenguest image. +EOF +} + +usage-create() { + cat <<EOF +Usage $this create XENGUEST [ARGS] + +Create a xenguest image as XENGUEST file. + +EOF + usage-update-create +} + +usage-update() { + cat <<EOF +Usage $this update XENGUEST [ARGS] + +Update or modify a xenguest image or a xenguest directory. + +EOF + usage-update-create +} + +usage-pack() { + cat <<EOF +Usage $this pack XENGUEST DESTFILE + +Pack a xenguest directory in XENGUEST to create a xenguest image DESTFILE. + +EOF +} + +usage-partial() { + cat <<EOF +Usage $this partial XENGUEST [ARGS] + +Update or modify a partial xenguest image. + +EOF + usage-update-create +} + +usage-dump-paramsconfig() { + cat <<EOF +Usage $this dump-paramsconfig XENGUEST + +Dump the guest parameters of a xenguest image or directory +EOF +} + +usage-dump-xenconfig() { + cat <<EOF +Usage $this dump-xenconfig XENGUEST + +Dump the xen configuration of a xenguest image or directory +EOF +} + +usage-dump-diskconfig() { + cat <<EOF +Usage $this dump-diskconfig XENGUEST + +Dump the disk configuration of a xenguest image or directory +EOF +} + +usage-extract() { + cat <<EOF +Usage $this extract XENGUEST DESTDIR + +Extract guest to DESTDIR +EOF +} + +usage-extract-config() { + cat <<EOF +Usage $this extract-config XENGUEST DESTDIR + +Extract guest configuration to DESTDIR +EOF +} + +usage-extract-disk-file() { + cat <<EOF +Usage $this extract-disk-file XENGUEST DISKFILE + +Extract disk file DISKFILE to stdout. +EOF +} + +check_image() { + local tstfile=${1} + + if [ ! -e ${tstfile} -o ! -w ${tstfile} ]; then + echo "Error: File ${tstfile} does not exist or is not writeable" + exit 1 + fi + + if [ -f ${tstfile} ]; then + # This is a xenguest file + local res=$(tar -tvf ${tstfile} ./guest.cfg ./disk.cfg \ + ./params.cfg > /dev/null 2>&1 || echo "error") + if [ -n "${res}" ]; then + echo "Error: File ${tstfile} is not a valid xenguest" + exit 1 + fi + elif [ -d ${tstfile} ]; then + if [ ! -f ${tstfile}/guest.cfg -o ! -f ${tstfile}/disk.cfg -o \ + ! ${tstfile}/params.cfg ]; then + echo "Error: Directory ${tstfile} is not a valid xenguest" + exit 1 + fi + fi +} + +params_config_reset() { + cat <<EOF > ${IMAGE_TMPDIR}/params.cfg +# Xenguest-image guest global configuration +# +# !! This file must not be modified manually !! +# +# You can use xenguest-image to modify parameters. +# + +# Guest auto boot during Dom0 init +GUEST_AUTOBOOT="1" +EOF +} + +params_config_setparam() { + param="${1}" + shift + value="$@" + + if [ -z "$value" ]; then + sed -i "/.*${param}=.*/d" ${IMAGE_TMPDIR}/params.cfg + elif grep -e "^${param}=" ${IMAGE_TMPDIR}/params.cfg > /dev/null; then + sed -i "s/${param}=\".*\"/${param}=\"${value}\"/" \ + ${IMAGE_TMPDIR}/params.cfg + else + echo "${param}=\"${value}\"" >> ${IMAGE_TMPDIR}/params.cfg + fi +} + +xen_config_reset() { + cat <<EOF > ${IMAGE_TMPDIR}/guest.cfg +# Xenguest-image main configuraiton +# +# !! This file must not be modified manually !! +# +# You can use xenguest-image to modify parameters. +# +# You can add custom entries to configuration in the guest.d directory. + +# Guest name (set by manager when guest is created) +# name = "" + +# Guest memory size in MB +memory = 1024 + +# Number of VCPUS +vcpus = 1 + +# Guest command line +extra = "earlyprintk=xenboot console=hvc0 rw" + +# Guest root filesystem device (from guest point of view) +# root = "/dev/xvda2" + +# Disk that will be used by the guest (set by manager when guest is created) +# disk = ['phy:/dev/vg-xen/guestname,xvda,w'] + +EOF +} + +get_param_file() { + param="${1}" + + if grep ${param} ${IMAGE_TMPDIR}/guest.cfg > /dev/null 2>&1; then + echo "${IMAGE_TMPDIR}/guest.cfg" + else + if [ ! -f ${IMAGE_TMPDIR}/guest.d/${param}.cfg ]; then + mkdir -p ${IMAGE_TMPDIR}/guest.d + echo "# ${param} = \"\"" > ${IMAGE_TMPDIR}/guest.d/${param}.cfg + fi + echo "${IMAGE_TMPDIR}/guest.d/${param}.cfg" + fi +} + +xen_config_disable_param() { + param="${1}" + dst=$(get_param_file ${param}) + + sed -i "s@.*\(${param} = .*\)\$@# \1@" ${dst} +} + +xen_config_set_number() { + param="${1}" + shift + value="$@" + dst=$(get_param_file ${param}) + + sed -i "s@.*${param} = .*@${param} = ${value}@" ${dst} +} + +xen_config_set_string() { + param="${1}" + shift + value="$@" + dst=$(get_param_file ${param}) + + sed -i "s@.*${param} = .*@${param} = \"${value}\"@" ${dst} +} + +xen_config_append_string() { + param="${1}" + shift + value="$@" + dst=$(get_param_file ${param}) + + sed -i "s@.*${param} = \"\([^\"]*\)\"@${param} = \"\1 ${value}\"@" ${dst} +} + +xen_config_set_list() { + param="${1}" + shift + value=$(echo $@ | tr " " ",") + dst=$(get_param_file ${param}) + + sed -i "s@.*${param} = .*@${param} = ['${value}']@" ${dst} +} + +disk_config_reset() { + echo "DISK_SIZE=\"0\"" > ${IMAGE_TMPDIR}/disk.cfg + echo "DISK_DEVICE=\"\"" >> ${IMAGE_TMPDIR}/disk.cfg +} + +disk_config_rm_part() { + partid=$1 + sed -i "/DISK_PART${partid}=.*/d" ${IMAGE_TMPDIR}/disk.cfg +} + +disk_config_add_part() { + partconf="${1}" + partid=$(echo ${partconf} | sed -e "s/:.*//") + partinfo=$(echo ${partconf} | sed -e "s/[^:]*://") + + # Make sure we don't add the same partition twice + disk_config_rm_part ${partid} + echo "DISK_PART${partid}=\"${partinfo}\"" >> \ + ${IMAGE_TMPDIR}/disk.cfg +} + +# We need an action as first argument +action="${1:-}" + +if [ -z "${action}" ]; then + echo "Error: No ACTION provided" + usage + exit 1 +fi + +# Only help does not require a xenguest argument so treat this first +# while there we also check that user is asking for a supported action +case $action in + help|--help|-h|-?) + usage + exit 0 + ;; + check|create|update|pack|partial) + ;; + dump-xenconfig|dump-diskconfig|dump-init|dump-paramsconfig) + ;; + extract|extract-config|extract-disk-file) + ;; + *) + echo "Error: Invalid action $action" + exit 1 + ;; +esac + +# Second argument should be the file name or directory +guestfile="${2:-}" + +# Handle user asking for help on a specific action +case $guestfile in + help|--help|-h|-?) + usage-${action} + exit 0 + ;; +esac + +if [ -z "${guestfile}" ]; then + echo "Error: no GUESTFILE provided" + usage + exit 1 +fi + +shift 2 + +case ${action} in + check) + check_image ${guestfile} + echo "Image is OK" + exit 0 + ;; + dump-paramsconfig) + check_image ${guestfile} + echo "Guest configuration:" + if [ -f ${guestfile} ]; then + tar -xOf ${guestfile} ./params.cfg + else + cat ${guestfile}/params.cfg + fi + exit 0 + ;; + dump-xenconfig) + check_image ${guestfile} + echo "Xen configuration:" + if [ -f ${guestfile} ]; then + tar -xOf ${guestfile} ./guest.cfg + tar -xOf ${guestfile} ./guest.d 2> /dev/null || true + else + cat ${guestfile}/guest.cfg + cat ${guestfile}/guest.d/* 2> /dev/null || true + fi + echo + exit 0 + ;; + dump-diskconfig) + check_image ${guestfile} + echo "Disk configuration:" + if [ -f ${guestfile} ]; then + tar -xOf ${guestfile} ./disk.cfg + else + cat ${guestfile}/disk.cfg + fi + echo + exit 0 + ;; + dump-init) + check_image ${guestfile} + for init in init.d init-pre init-post; do + echo "=== ${init} ===" + if [ -f ${guestfile} ]; then + tar -xOf ${guestfile} ./${init} 2> /dev/null || \ + echo "No ${init} scripts." + else + cat ${guestfile}/${init}/* 2> /dev/null || \ + echo "No ${init} scripts." + fi + echo "===============" + echo + done + exit 0 + ;; + pack) + check_image ${guestfile} + if [ ! -d ${guestfile} ]; then + echo "Error: Pack can only be done on a xenguest directory" + exit 1 + fi + + if [ -z "${1:-}" ] || [ -f ${1} ]; then + echo "Error: No destination file or already existing file" + exit 1 + fi + + tar -C ${guestfile} -cf ${1} . + exit 0 + ;; + extract) + check_image ${guestfile} + if [ -d ${guestfile} ]; then + echo "Error: Cannot extract config from xenguest directory" + exit 1 + fi + + if [ -z "${1:-}" ] || [ ! -d ${1} ]; then + echo "Error: No destination directory for image extract" + exit 1 + fi + + tar -C ${1} -xf ${guestfile} + exit 0 + ;; + extract-config) + check_image ${guestfile} + if [ -d ${guestfile} ]; then + echo "Error: Cannot extract config from xenguest directory" + exit 1 + fi + + if [ -z "${1:-}" ] || [ ! -d ${1} ]; then + echo "Error: No destination directory for config extract" + exit 1 + fi + + #extract all but disk files + tar -C ${1} --exclude='./disk' -xf ${guestfile} + exit 0 + ;; + extract-disk-file) + check_image ${guestfile} + + if [ -d ${guestfile} ]; then + echo "Error: Cannot extract disk file from xenguest directory" >&2 + exit 1 + fi + + if [ -z "${1:-}" ]; then + echo "Error: No file to extract" >&2 + exit 1 + fi + + tar -xOf ${guestfile} ./disk/${1} + exit 0 + ;; + create) + if [ -f ${guestfile} ]; then + echo "Error: File ${guestfile} already exist" + exit 1 + elif [ -d ${guestfile} ]; then + if [ -n "$(ls -A ${guestfile})" ]; then + echo "Error: Directory ${guestfile} is not empty" + exit 1 + fi + IMAGE_TMPDIR=$(realpath -m ${guestfile}) + else + IMAGE_TMPDIR=$(mktemp -d) + fi + + # Create initial content + params_config_reset + xen_config_reset + disk_config_reset + ;; + update) + check_image ${guestfile} + + if [ -f ${guestfile} ]; then + # Extract the image to update it + IMAGE_TMPDIR=$(mktemp -d) + tar -C ${IMAGE_TMPDIR} -xf ${guestfile} + else + IMAGE_TMPDIR=$(realpath -m ${guestfile}) + fi + ;; + partial) + if [ -e ${guestfile} -a ! -d ${guestfile} ]; then + echo "Error: Invalid partial output directory" + exit 1 + fi + mkdir -p ${guestfile} + IMAGE_TMPDIR=$(realpath -m ${guestfile}) + ;; + *) + echo "Invalid action ${action}" + usage + exit 1 + ;; +esac + +# Process command line arguments +for arg in "${@}"; do + case ${arg} in + --*=*) + optarg=$(echo ${arg} | sed -e "s/[^=]*=//") + ;; + *) + optarg="" + ;; + esac + + case ${arg} in + --guest-reset-config) + params_config_reset + ;; + --set-param=*=*) + param_name=$(echo $optarg | sed -e "s/=.*//") + param_value=$(echo $optarg | sed -e "s/[^=]*=//") + params_config_setparam "$param_name" "$param_value" + ;; + --set-param=*) + params_config_setparam "$optarg" + ;; + --xen-reset-config) + xen_config_create + ;; + --xen-name=*) + if [ -z "${optarg}" ]; then + xen_config_disable_param "name" + else + xen_config_set_string "name" "${optarg}" + fi + ;; + --xen-kernel=*) + if [ -z "${optarg}" ]; then + xen_config_disable_param "kernel" + rm -f ${IMAGE_TMPDIR}/files/kernel + else + if [ ! -f ${optarg} ]; then + echo "Error: invalid kernel file ${optarg}" + exit 1 + fi + xen_config_set_string "kernel" "files/kernel" + mkdir -p ${IMAGE_TMPDIR}/files + install -m 644 ${optarg} ${IMAGE_TMPDIR}/files/kernel + fi + ;; + --xen-memory=*) + xen_config_set_number "memory" ${optarg} + ;; + --xen-vcpus=*) + xen_config_set_number "vcpus" ${optarg} + ;; + --xen-clean-extra) + xen_config_set_string "extra" "" + ;; + --xen-extra=*) + xen_config_append_string "extra" ${optarg} + ;; + --xen-root=*) + if [ -z "${optarg}" ]; then + xen_config_disable_param "root" + else + xen_config_set_string "root" "${optarg}" + fi + ;; + --xen-device-tree=*) + if [ -z "${optarg}" ]; then + xen_config_disable_param "device_tree" + rm -f ${IMAGE_TMPDIR}/files/guest.dtb + else + if [ ! -f ${optarg} ]; then + echo "Error: invalid dtb file ${optarg}" + exit 1 + fi + xen_config_set_string "device_tree" "files/guest.dtb" + mkdir -p ${IMAGE_TMPDIR}/files + install -m 644 ${optarg} ${IMAGE_TMPDIR}/files/guest.dtb + fi + ;; + --xen-disk=*) + if [ -z "${optarg}" ]; then + xen_config_disable_param "disk" + else + xen_config_set_list "disk" "phy:${optarg}" "xvda" "w" + fi + ;; + --xen-append=*) + if [ ! -f ${optarg} ]; then + echo "Error: invalid xen append file ${optarg}" + exit 1 + fi + mkdir -p ${IMAGE_TMPDIR}/guest.d + install -m 755 ${optarg} ${IMAGE_TMPDIR}/guest.d/. + ;; + --xen-add-file=*) + src=$(echo "${optarg}" | sed -e "s/:.*//") + dst=$(echo "${optarg}" | sed -e "s/.*://") + if [ ! -f ${src} ]; then + echo "Error: Invalid file: ${src}" + rm -rf ${IMAGE_TMPDIR} + exit 1 + fi + if [ -z "${dst}" ]; then + dst=$(basename ${src}) + fi + mkdir -p ${IMAGE_TMPDIR}/files/$(dirname ${dst}) + cp -f ${src} ${IMAGE_TMPDIR}/files/${dst} + ;; + --xen-rm-file=*) + rm -f ${IMAGE_TMPDIR}/files/${optarg} + ;; + --init-script=*|--init-pre=*|--init-post=*) + dst="" + case $arg in + --init-script=*) + dst="init.d" + ;; + --init-pre=*) + dst="init.pre" + ;; + --init-post=*) + dst="init.post" + ;; + esac + if [ ! -f ${optarg} ]; then + echo "${optarg} does not point to a valid file" + exit 1 + else + mkdir -p ${IMAGE_TMPDIR}/${dst} + install -m 755 ${optarg} ${IMAGE_TMPDIR}/${dst}/. + fi + ;; + --disk-reset-config) + disk_config_reset + ;; + --disk-size=*) + sed -i "s/DISK_SIZE=.*/DISK_SIZE=\"${optarg}\"/" \ + ${IMAGE_TMPDIR}/disk.cfg + ;; + --disk-device=*) + sed -i "s/DISK_DEVICE=.*/DISK_SIZE=\"${optarg}\"/" \ + ${IMAGE_TMPDIR}/disk.cfg + ;; + --disk-add-part=*) + disk_config_add_part ${optarg} + ;; + --disk-rm-part=*) + disk_config_rm_part ${optarg} + ;; + --disk-add-file=*) + src=$(echo "${optarg}" | sed -e "s/:.*//") + dst=$(echo "${optarg}" | sed -e "s/.*://") + if [ ! -f ${src} ]; then + echo "Error: Invalid disk file: ${src}" + rm -rf ${IMAGE_TMPDIR} + exit 1 + fi + if [ -z "${dst}" ]; then + dst=$(basename ${src}) + fi + mkdir -p ${IMAGE_TMPDIR}/disk/$(dirname ${dst}) + cp -f ${src} ${IMAGE_TMPDIR}/disk/${dst} + ;; + --disk-rm-file=*) + rm -f ${IMAGE_TMPDIR}/disk/${optarg} + ;; + *) + echo "Unsupported command: ${arg}" + exit 1 + ;; + esac +done + +if [ ! -d ${guestfile} ]; then + # If the original guest was in a file we need to repack the file + # with the changes we did on it in the IMAGE_TMPDIR + rm -f ${guestfile} + tar -C ${IMAGE_TMPDIR} -cf ${guestfile} . + rm -rf ${IMAGE_TMPDIR} +fi + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge-dhcp.cfg.in b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge-dhcp.cfg.in new file mode 100644 index 00000000..6e063793 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge-dhcp.cfg.in @@ -0,0 +1,3 @@ +# Xenguest Network Bridge interface configuration +auto ###BRIDGE_NAME### +iface ###BRIDGE_NAME### inet dhcp diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge.in b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge.in new file mode 100755 index 00000000..2278b80c --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge.in @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Xenguest Network Bridge init +# This script creates a network bridge and add host interfaces to it +# It will then be used by xen guests to connect to the external nework +# + +INTFS="###BRIDGE_MEMBERS###" +BR_INTF="###BRIDGE_NAME###" + +case "$1" in + start) + echo "Starting $BR_INTF" + brctl addbr $BR_INTF + for intf in $INTFS; do + echo "Adding $intf to $BR_INTF" + brctl addif $BR_INTF $intf + done + ;; + status) + true + ;; + stop) + echo "Stopping $BR_INTF" + ifdown $BR_INTF + brctl delbr $BR_INTF + ;; + reload) + echo >&2 'Reload not available; use force-reload'; exit 1 + ;; + force-reload|restart) + echo "Restarting host-bridge" + $0 stop + $0 start + ;; + *) + # do not advertise unreasonable commands that there is no reason + # to use with this device + echo $"Usage: $0 {start|stop|status|restart|force-reload}" + exit 1 +esac + +exit $? + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-base-image.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-base-image.bb new file mode 100644 index 00000000..fb665666 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-base-image.bb @@ -0,0 +1,119 @@ +# Create a xenguest base image +# +# This recipe creates a base image that is then extended by other recipes +# through xenguest-image class. +# xenguest image type is using this as base to add a kernel and a disk image +# to create a guest +# +# The recipe is also adding files in those directories to the xenguest image: +# - ${WORKDIR}/extend/disk-files: all files in this directory will be added to +# the guest disk files (using --disk-add-file) +# - ${WORKDIR}/extend/files: all files in this directory will be added to the +# guest xen files (using --xen-add-file) +# - ${WORKDIR}/extend/guest.d: all files in this directory will be added to +# the xen append configuration files (using --xen-append) +# - ${WORKDIR}/extend/init.[pre|post|d]: all files in those directories will +# be added to the corresponding init scripts (using --init-[pre|post|script]) +# You can bbappend this recipe and put files in ${WORKDIR}/extend to add +# elements to the image. +# + +DESCRIPTION = "Xenguest Base Image" +LICENSE = "MIT" + +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +# +# The following variables can contain SRC_URI compatible entries to add +# files to the xenguest image. +# You can set those variable in local.conf to add one or several files +# For example to add a boot.tar.gz file that has to be downloaded to the file +# useable for disk partition initialisation: +# XENGUEST_IMAGE_SRC_URI_DISK_FILES += "https://www.test.com/files/boot.tar.gz" + +# Add disk files +XENGUEST_IMAGE_SRC_URI_DISK_FILES ??= "" + +# Add xen files +XENGUEST_IMAGE_SRC_URI_XEN_FILES ??= "" + +# Add xen configuration elements +XENGUEST_IMAGE_SRC_URI_XEN_CONFIG ??= "" + +# Add pre init script +XENGUEST_IMAGE_SRC_URI_INIT_PRE ??= "" + +# Add init script +XENGUEST_IMAGE_SRC_URI_INIT ??= "" + +# Add post init script +XENGUEST_IMAGE_SRC_URI_INIT_POST ??= "" + +S = "${WORKDIR}" + +inherit deploy xenguest-image + +# parse XENGUEST_IMAGE_SRC_URI_ variables and add them to SRC_URI +python __anonymous() { + def parse_extend_variable(d, varname, destdir): + list = d.getVar(varname) + if list: + for entry in list.split(): + #Check the URL + try: + decode = bb.fetch.decodeurl(entry) + d.appendVar('SRC_URI', ' ' + entry + ';unpack=0;subdir=extend/' + destdir) + except: + bb.fatal("%s: %s contains an invalid URL: %s" \ + % (d.getVar('PF'), varname, entry)) + + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_DISK_FILES', 'disk-files') + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_XEN_FILES', 'files') + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_XEN_CONFIG', 'guest.d') + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_INIT_PRE', 'init.pre') + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_INIT', 'init.d') + parse_extend_variable(d, 'XENGUEST_IMAGE_SRC_URI_INIT_POST', 'init.post') +} + +# Make sure we are removing old files before redoing a fetch +do_fetch[cleandirs] += "${WORKDIR}/extend" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" +do_install[noexec] = "1" + +add_extend_files() { + local subdir="$1" + local cmd="$2" + local stripdest="${3:-n}" + + if [ -d ${WORKDIR}/extend/$subdir ]; then + filelist=$(find ${WORKDIR}/extend/$subdir -type f) + + if [ -n "$filelist" ]; then + for f in $filelist; do + if [ "$stripdest" = "y" ]; then + call_xenguest_mkimage update --$cmd=$f:$(basename $f) + else + call_xenguest_mkimage update --$cmd=$f + fi + done + fi + fi +} + +do_deploy() { + # Create a new image + xenguest_image_create + + # Add our extra files if any + add_extend_files "disk-files" "disk-add-file" "y" + add_extend_files "files" "xen-add-file" "y" + add_extend_files "guest.d" "xen-append" + add_extend_files "init.pre" "init-pre" + add_extend_files "init.d" "init-script" + add_extend_files "init.post" "init-post" +} + +addtask deploy after do_install before do_build + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-manager.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-manager.bb new file mode 100644 index 00000000..65925d2a --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-manager.bb @@ -0,0 +1,52 @@ +# Xenguest manager recipe +# +# xenguest-manager is a tool to control xen guest (e.g. create, start, stop) +# + +DESCRIPTION = "Xen Guest Manager" +LICENSE = "MIT" + +SRC_URI = " \ + file://xenguest-manager \ + file://xenguest-init \ + " +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +S = "${WORKDIR}" + +# Please refer to documentation/xenguest-manager.md for documentation on those +# parameters +XENGUEST_MANAGER_VOLUME_DEVICE ?= "/dev/sda2" +XENGUEST_MANAGER_VOLUME_NAME ?= "vg-xen" +XENGUEST_MANAGER_GUEST_DIR ?= "${datadir}/guests/" + +# We add an init script to create and start guests automatically +INITSCRIPT_NAME = "xenguest" +INITSCRIPT_PARAMS = "defaults 90" + +inherit update-rc.d + +do_compile() { + echo "XENGUEST_VOLUME_DEVICE=\"${XENGUEST_MANAGER_VOLUME_DEVICE}\"" > \ + xenguest-manager.conf + echo "XENGUEST_VOLUME_NAME=\"${XENGUEST_MANAGER_VOLUME_NAME}\"" >> \ + xenguest-manager.conf + echo "XENGUEST_GUEST_DIR=\"${XENGUEST_MANAGER_GUEST_DIR}\"" >> \ + xenguest-manager.conf +} + +do_install() { + install -d -m 755 ${D}${bindir} + install -m 755 xenguest-manager ${D}${bindir}/. + install -d -m 755 ${D}${sysconfdir}/xenguest + install -m 644 xenguest-manager.conf ${D}${sysconfdir}/xenguest/. + install -d -m 755 ${D}${sysconfdir}/init.d + install -m 755 xenguest-init ${D}${sysconfdir}/init.d/${INITSCRIPT_NAME} + install -d -m 755 ${D}${XENGUEST_GUEST_DIR} +} + +# Things that we need on the target +RDEPENDS_${PN} += "bash tar xenguest-mkimage lvm2 xen-tools parted e2fsprogs" + +FILES_${PN} += "${bindir}/xenguest-manager \ + ${sysconfdir}/xenguest" diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-mkimage.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-mkimage.bb new file mode 100644 index 00000000..6ea5fb10 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-mkimage.bb @@ -0,0 +1,31 @@ +# Xenguest mkimage recipe +# +# xenguest-mkimage is a tool to create/modify images to be used as xen guests +# Produced images contains a xen configuration and several optional components +# (kernel, device-tree, disk definition and files, init scripts) which all +# together fully define a full xen guest + +DESCRIPTION = "Xenguest mkimage tool" +LICENSE = "MIT" + +SRC_URI = "file://xenguest-mkimage" + +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +S = "${WORKDIR}" + +# Can be built native also to produce xenguest images during Yocto build +BBCLASSEXTEND = "native" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d -m 755 ${D}${bindir} + install -m 755 xenguest-mkimage ${D}${bindir}/. +} + +# We need bash and tar +RDEPENDS_${PN} = "bash tar" +FILES_${PN} = "${bindir}/xenguest-mkimage" + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-network-bridge.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-network-bridge.bb new file mode 100644 index 00000000..babd694d --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-network-bridge.bb @@ -0,0 +1,52 @@ +# Recipe to handle xenguest network configuration +DESCRIPTION = "XenGuest Network Bridge" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +S = "${WORKDIR}" + +# Please refer to documentation/xenguest-network-bridge.md for documentation on +# those parameters +XENGUEST_NETWORK_BRIDGE_NAME ?= "xenbr0" +XENGUEST_NETWORK_BRIDGE_MEMBERS ?= "eth0" +XENGUEST_NETWORK_BRIDGE_CONFIG ?= "xenguest-network-bridge-dhcp.cfg.in" + +SRC_URI = " \ + file://xenguest-network-bridge.in \ + file://xenguest-network-bridge-dhcp.cfg.in \ + file://network-bridge.sh.in \ + " + +# Bridge configurator needs to run before S01networking init script +# Prefix with a_ to make sure it is executed in runlevel 01 before others +INITSCRIPT_NAME = "a_xenguest-network-bridge" +INITSCRIPT_PARAMS = "defaults 01" + +inherit update-rc.d + +do_install() { + cat ${WORKDIR}/xenguest-network-bridge.in \ + | sed -e "s,###BRIDGE_MEMBERS###,${XENGUEST_NETWORK_BRIDGE_MEMBERS}," \ + | sed -e "s,###BRIDGE_NAME###,${XENGUEST_NETWORK_BRIDGE_NAME}," \ + > ${WORKDIR}/xenguest-network-bridge + cat ${WORKDIR}/${XENGUEST_NETWORK_BRIDGE_CONFIG} \ + | sed -e "s,###BRIDGE_NAME###,${XENGUEST_NETWORK_BRIDGE_NAME}," \ + > ${WORKDIR}/xenguest-network-bridge.cfg + cat ${WORKDIR}/network-bridge.sh.in \ + | sed -e "s,###BRIDGE_NAME###,${XENGUEST_NETWORK_BRIDGE_NAME}," \ + > ${WORKDIR}/network-bridge.sh + install -d -m 755 ${D}${sysconfdir}/init.d + install -m 755 ${WORKDIR}/xenguest-network-bridge \ + ${D}${sysconfdir}/init.d/${INITSCRIPT_NAME} + install -d -m 755 ${D}${sysconfdir}/network/interfaces.d + install -m 755 ${WORKDIR}/xenguest-network-bridge.cfg \ + ${D}${sysconfdir}/network/interfaces.d/. + install -d -m 755 ${D}${sysconfdir}/xenguest/init.pre + install -m 755 ${WORKDIR}/network-bridge.sh \ + ${D}${sysconfdir}/xenguest/init.pre/. +} + +RDEPENDS_${PN} += "bridge-utils" +FILES_${PN} += "${sysconfdir}/network/interfaces.d/xenguest-network-bridge.cfg" +FILES_${PN} += "${sysconfdir}/xenguest/init.pre/network-bridge.sh" diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-nodisk-image.bb b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-nodisk-image.bb new file mode 100644 index 00000000..b2dbbe99 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-nodisk-image.bb @@ -0,0 +1,38 @@ +# Create a xenguest image with kernel but no rootfs or an external rootfs +DESCRIPTION = "Xenguest No Disk Image" +LICENSE = "MIT" + +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +S = "${WORKDIR}" + +inherit deploy xenguest-image + +# Name of the file we create in deploy +XENGUEST_IMAGE_NODISK_DEPLOY = "xenguest-nodisk-image.xenguest" + +# use a local copy to pack all together +XENGUEST_IMAGE_DEPLOY_DIR = "${WORKDIR}/tmp-xenguest" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" +do_install[noexec] = "1" + +do_deploy() { + xenguest_image_clone + + # Add kernel to the image + if [ -n "${XENGUEST_IMAGE_KERNEL}" ]; then + call_xenguest_mkimage partial \ + --xen-kernel=${DEPLOY_DIR_IMAGE}/${XENGUEST_IMAGE_KERNEL} + fi + + # Pack and deploy the final image + rm -f ${DEPLOYDIR}/${XENGUEST_IMAGE_NODISK_DEPLOY} + call_xenguest_mkimage pack ${DEPLOYDIR}/${XENGUEST_IMAGE_NODISK_DEPLOY} +} +do_deploy[depends] += "virtual/kernel:do_deploy" +do_deploy[depends] += "xenguest-base-image:do_deploy" + +addtask deploy before do_build after do_install + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest-standard.scc b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest-standard.scc new file mode 100644 index 00000000..7c75d99f --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest-standard.scc @@ -0,0 +1,5 @@ +define KMACHINE arm64-autonomy-guest +define KTYPE standard +define KARCH arm64 + +include arm64-autonomy-guest.scc diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.cfg b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.cfg new file mode 100644 index 00000000..fcdad985 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.cfg @@ -0,0 +1,2 @@ +CONFIG_ARM64=y +CONFIG_SMP=y diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.scc b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.scc new file mode 100644 index 00000000..e887b4e5 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/bsp/arm-autonomy/arm64-autonomy-guest.scc @@ -0,0 +1,6 @@ +include ktypes/standard/standard.scc +include features/input/input.scc +include features/net/net.scc +include cfg/timer/no_hz.scc + +kconf hardware arm64-autonomy-guest.cfg diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.cfg b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.cfg new file mode 100644 index 00000000..e4e44a9c --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.cfg @@ -0,0 +1,54 @@ +CONFIG_PARAVIRT=y +CONFIG_XEN=y + +CONFIG_BLOCK=y +CONFIG_XEN_BLKDEV_FRONTEND=y + +CONFIG_SCSI=y +CONFIG_XEN_SCSI_FRONTEND=y + +CONFIG_NET=y +CONFIG_XEN_NETDEV_FRONTEND=y + +CONFIG_INPUT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y + +CONFIG_HVC_IRQ=y + +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y + +CONFIG_WATCHDOG=y +CONFIG_XEN_WDT=y + +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_XEN_FBDEV_FRONTEND=y + +CONFIG_XEN_BALLOON=y + +CONFIG_XEN_DEV_EVTCHN=y + +CONFIG_XENFS=y +CONFIG_XEN_COMPAT_XENFS=y + +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GRANT_DEV_ALLOC=y +CONFIG_SWIOTLB_XEN=y + +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y + +CONFIG_DRM=y +CONFIG_DRM_XEN=y +CONFIG_DRM_XEN_FRONTEND=y + +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_XEN_FRONTEND=y diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.scc b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.scc new file mode 100644 index 00000000..935e78f8 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-guest.scc @@ -0,0 +1,4 @@ +define KFEATURE_DESCRIPTION "Enable XEN Guest Frontend Drivers" + +kconf non-hardware xen-guest.cfg + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.cfg b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.cfg new file mode 100644 index 00000000..d457cb84 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.cfg @@ -0,0 +1,38 @@ +CONFIG_PARAVIRT=y +CONFIG_XEN=y + +CONFIG_BLOCK=y +CONFIG_XEN_BLKDEV_BACKEND=y + +CONFIG_SCSI=y +CONFIG_TARGET_CORE=y +CONFIG_XEN_SCSI_BACKEND=y + +CONFIG_NET=y +CONFIG_XEN_NETDEV_BACKEND=y + +CONFIG_HVC_IRQ=y + +CONFIG_HVC_XEN=y + +CONFIG_WATCHDOG=y +CONFIG_XEN_WDT=y + +CONFIG_XEN_BALLOON=y + +CONFIG_XEN_DEV_EVTCHN=y + +CONFIG_XENFS=y +CONFIG_XEN_COMPAT_XENFS=y + +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GRANT_DEV_ALLOC=y +CONFIG_SWIOTLB_XEN=y + +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y + +# For LVM2 we need Multiple Devices and Device Mapper support +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.scc b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.scc new file mode 100644 index 00000000..6fdbabc4 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/arm-autonomy-kmeta/features/arm-autonomy/xen-host.scc @@ -0,0 +1,4 @@ +define KFEATURE_DESCRIPTION "Enable XEN Host Drivers on autonomy systems" + +kconf non-hardware xen-host.cfg + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-%.bbappend b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-%.bbappend new file mode 100644 index 00000000..add70425 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-%.bbappend @@ -0,0 +1,3 @@ +# Add arm-autonomy kernel support +require linux-arm-autonomy.inc + diff --git a/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-arm-autonomy.inc b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-arm-autonomy.inc new file mode 100644 index 00000000..27634447 --- /dev/null +++ b/bsp/meta-arm/meta-arm-autonomy/recipes-kernel/linux/linux-arm-autonomy.inc @@ -0,0 +1,22 @@ +# Add arm-autonomy specific features to the kernel + +FILESEXTRAPATHS_prepend := "${THISDIR}:" + +# +# arm-autonomy kmeta +# +SRC_URI_append = " file://arm-autonomy-kmeta;type=kmeta;name=arm-autonomy-kmeta;destsuffix=arm-autonomy-kmeta" + + +# Add xen host drivers to kernel if arm-autonomy-host is activated +KERNEL_FEATURES += "${@bb.utils.contains('DISTRO_FEATURES', \ + 'arm-autonomy-host', 'features/arm-autonomy/xen-host.scc', '', d)}" + +# Add xen guest drivers to kernel if arm-autonomy-guest is activated +KERNEL_FEATURES += "${@bb.utils.contains('DISTRO_FEATURES', \ + 'arm-autonomy-guest', 'features/arm-autonomy/xen-guest.scc', '', d)}" + +# Add support for arm64-autonomy-guest machine +COMPATIBLE_MACHINE_arm64-autonomy-guest = "arm64-autonomy-guest" +KMACHINE_arm64-autonomy-guest = "arm64-autonomy-guest" + |