Xen Hypervisor through Yocto Flow


Table of Contents

Building the Xen Image

Running Xen built from Yocto on QEMU or hardware is similar to running any other Yocto images.  First you need to build the Xen image. To do this you will need to have the meta-xilinx layer and the meta-petalinux layer cloned. Then bulid the xen-image-minimal image. Note that only ZynqMP supports Xen.
 $ MACHINE=qemuzynqmp bitbake xen-image-minimal # You can also use MACHINE=zcu102-zynqmp to target hardware

Booting Xen

Once that has built you can boot it on either QEMU or hardware. See Booting Yocto Images on QEMU and Meta-Xilinx Booting README for detailed steps on how to do this.
As mentioned in thoses links sometimes the u-boot TFTP images are named differently in the Yocto output compared to what u-boot expects. I generally run these two commands before booting Xen on QEMU to solve the problem.
 $ cp tmp/deploy/images/qemuzynqmp/Image-zynqmp-zcu102-revB.dtb tmp/deploy/images/qemuzynqmp/system.dtb
 $ cp tmp/deploy/images/qemuzynqmp/xen-image-minimal-qemuzynqmp.cpio.gz.u-boot tmp/deploy/images/qemuzynqmp/image.ub
Once you get to the u-boot prompt use the built in xen or xen_qemu command to TFTP boot Xen. You will probably need to run dhcp first.
The u-boot shipped with the 2016.3 release doesn't work with Ethernet on all boards, if you see this problem you will need to use an older version of u-boot, use u-boot from PetaLinux or try SDBoot instead.
ZynqMP> dhcp
BOOTP broadcast 1
DHCP client bound to address 10.10.70.1 (1 ms)
Using ethernet@ff0e0000 device
TFTP from server 10.0.2.2; our IP address is 10.10.70.1
Filename 'Image'.
Load address: 0x80000
Loading: #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     ########################################################
Abort
ZynqMP> run xen_qemu
Using ethernet@ff0e0000 device
TFTP from server 10.0.2.2; our IP address is 10.10.70.1
Filename 'system.dtb'.
Load address: 0x4000000
Loading: ######
     4.7 MiB/s
done
Bytes transferred = 29314 (7282 hex)
Using ethernet@ff0e0000 device
TFTP from server 10.0.2.2; our IP address is 10.10.70.1
Filename 'Image'.
Load address: 0x80000
Loading: #################################################################
...
Starting kernel ...
...
[   32.203772] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
 
PetaLinux 2016.3 qemuzynqmp /dev/hvc0
 
qemuzynqmp login:
You have now booted Xen and Dom0 ontop of Xen. You can login to Dom0 using the username 'root'.

Xilinx has included some example Xen configurations to help users get started with running DomUs ontop of Xen. These are avaliable in /etc/xen/
 # cd /etc/xen/
You can then use xl to create a DomU based on a configuration file. For more options and information about xl run:
 # xl help
Once you have started a DomU the console input/output will transfer to that guest. You can get control back to Dom0 by typing the following
  Ctrl + ']'
You can also transfer the input/output back to Xen by pressing:
  Ctrl + 'a' three times

Simple Example

This is the simplist example and can be started with:
# xl create -c example-simple.cfg

Para-Virtulised Network Example

This is a slightly more complex example and requires some steps before starting DomU. Once you have logeed into Domo run the following commands:
# killall -9 udhcpc # Kill the DHCP client for eth0
# ip addr show dev eth0 # List the existing addresses for eth0
# ip addr del 10.10.70.2/8 dev eth0 # This is an example, use the IP address and subnet mask displayed from the previous command
 # brctl addbr xenbr0 $ Create the networkigng bridge
 # brctl addif xenbr0 eth0
 # /sbin/udhcpc -i xenbr0 -b # Start the DHCP server on the new networking bridge
You should now see the DHCP server start up. It will look something like this:
 [ 5478.370842] xenbr0: port 1(eth0) entered blocking state
 [ 5478.371155] xenbr0: port 1(eth0) entered forwarding state
 Sending discover...
 Sending select for 10.10.70.2...
 Lease of 10.10.70.2 obtained, lease time 86400
 /etc/udhcpc.d/50default: Adding DNS 10.0.2.3
Now create the DomU guest to make use of the para-virtualised network.
 # xl create -c example-pvnet.cfg

Passthrough Network Example

This is the most complex example and requires work before booting Xen. If booting on hardware you need to set the GEM to issue NS DMA transactions. This can be done after running FSBL:
 proc zynqmp_gem_ns {} {
         # Set the GEMS to be NS
         mwr 0xff240000 0x492
         mwr 0xff240004 0x492
 
         # Unmask SMMU interrupts.
         mwr 0xFD5F0018 0x1f
 }
This step is not required if running on QEMU, but all other steps below apply to both hardware and QEMU.

When booting from u-boot use the following command instead of the run commands mentioned above.
 > tftpb $fdt_addr system.dtb &&&& tftpb 0x80000 Image &&&& run xen_prepare_dt_qemu &&&& fdt set /amba/ethernet@ff0e0000 status "disabled" &&&& fdt set /amba/ethernet@ff0e0000 xen,passthrough "1" &&&& tftpb 6000000 xen.ub &&&& tftpb 0x1000000 image.ub &&&& bootm 6000000 0x1000000 $fdt_addr # For QEMU
 > tftpb $fdt_addr system.dtb &&&& tftpb 0x80000 Image &&&& run xen_prepare_dt &&&& fdt set /amba/ethernet@ff0e0000 status "disabled" &&&& fdt set /amba/ethernet@ff0e0000 xen,passthrough "1" &&&& tftpb 6000000 xen.ub &&&& tftpb 0x1000000 image.ub &&&& bootm 6000000 0x1000000 $fdt_addr # For hardware
These commands are similar to the xen_qemu and xen commands mentioned before, but they have these two extra commands in the middle:
 fdt set /amba/ethernet@ff0e0000 status "disabled" &&&& fdt set /amba/ethernet@ff0e0000 xen,passthrough "1"
This is required to ensure that Dom0 doesn't use the GEM device so that we can pass it to DomU.

This will start Domo similar to before. Now start Dom1 using the xl command.
 # xl create -c example-passnet.cfg

Where is the RootFS?

All of the steps above will result in an error when booting DomU as there is no rootFS included in Dom0's RootFS. The Dom0 kernel image is included in the Dom0 rootFS which is why the kernel boots but then panics when no rootFS can be found.

The config files can be edited to point to a specific kernel image and rootFS to use when booting DomU. This image and configuration is up to the user to determine and select. The kernel used in the examples above is just the Dom0 kernel. If you would like a specific DomU kernel you will need to build and boot that yourselvf.

One option is to load the images on an SD card, see here for details on how to do that: Starting Linux guests with Pass-through networking

Another option is to get the rootFS into the Dom0 kernel image is to add a diff similar to this to the meta-petalinux layer. This diff has been applied onto the 2017.1 (morty) release of meta-petalinux
diff --git a/recipes-extended/xen/xen_4.8.0.bbappend b/recipes-extended/xen/xen_4.8.0.bbappend
index 96adee9..91cb5b7 100644
--- a/recipes-extended/xen/xen_4.8.0.bbappend
+++ b/recipes-extended/xen/xen_4.8.0.bbappend
@@ -17,6 +17,7 @@ FILES_${PN}-xl_append = " \
     /etc/xen/example-pvnet.cfg \
     /etc/xen/example-simple.cfg \
     /etc/xen/passthrough-example-part.dtb \
+    /boot/Image \
     "
 
 DEPENDS += "u-boot-mkimage-native"
@@ -44,4 +45,8 @@ do_install_append() {
     install -m 0644 ${WORKDIR}/example-simple.cfg ${D}/etc/xen/example-simple.cfg
 
     install -m 0644 ${WORKDIR}/passthrough-example-part.dtb ${D}/etc/xen/passthrough-example-part.dtb
+
+    if [ -f ${DEPLOY_DIR_IMAGE}/Image ]; then
+        install -m 0644 ${DEPLOY_DIR_IMAGE}/Image ${D}/boot/Image
+    fi
 }

© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy