summaryrefslogtreecommitdiffstats
path: root/bsp/meta-arm/meta-arm-autonomy/recipes-extended
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/meta-arm/meta-arm-autonomy/recipes-extended')
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/files/xen.dtsi.in17
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen-devicetree/xen-devicetree.bb72
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xen/xen_%.bbappend14
-rwxr-xr-xbsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/network-bridge.sh.in15
-rwxr-xr-xbsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-init85
-rwxr-xr-xbsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager665
-rwxr-xr-xbsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage772
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge-dhcp.cfg.in3
-rwxr-xr-xbsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-network-bridge.in44
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-base-image.bb119
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-manager.bb52
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-mkimage.bb31
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-network-bridge.bb52
-rw-r--r--bsp/meta-arm/meta-arm-autonomy/recipes-extended/xenguest/xenguest-nodisk-image.bb38
14 files changed, 1979 insertions, 0 deletions
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
+