summaryrefslogtreecommitdiffstats
path: root/classes
diff options
context:
space:
mode:
authorChristopher Clark <christopher.clark@starlab.io>2021-07-27 17:07:40 -0700
committerBruce Ashfield <bruce.ashfield@gmail.com>2021-07-29 10:55:56 -0400
commit19347a7c4e4cc3baf08923d6d42c086f170f1c63 (patch)
tree48f3bce1ba4e0fd3274b50ee9e643ecd6b42cee4 /classes
parent29796322c23ce6b425cd0adce380391b70f492df (diff)
downloadmeta-virtualization-19347a7c4e4cc3baf08923d6d42c086f170f1c63.tar.gz
qemuboot, xen-image-minimal: enable runqemu for qemuarm64 Xen images
The Xen hypervisor built for Arm 64-bit targets can be launched with runqemu by providing a Device Tree binary and configuration for Qemu, which enables interactive testing of Xen images. Add qemuboot-xen-dtb.bbclass to add a new bitbake task for generating the dtb file by using lopper on a device tree produced by Qemu. Add qemuboot-xen-defaults.bbclass to supply working default parameters for the qemuarm64 machine and general support for qemuboot for Xen, and adjust the defaults as needed to boot successfully in testing. Development aided by this script by Stewart Hildebrand of DornerWorks: https://gist.github.com/stewdk/110f43e0cc1d905fc6ed4c7e10d8d35e Signed-off-by: Christopher Clark <christopher.clark@starlab.io> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'classes')
-rw-r--r--classes/qemuboot-xen-defaults.bbclass30
-rw-r--r--classes/qemuboot-xen-dtb.bbclass209
2 files changed, 239 insertions, 0 deletions
diff --git a/classes/qemuboot-xen-defaults.bbclass b/classes/qemuboot-xen-defaults.bbclass
new file mode 100644
index 00000000..67751d3a
--- /dev/null
+++ b/classes/qemuboot-xen-defaults.bbclass
@@ -0,0 +1,30 @@
1# Set defaults for booting Xen images with qemuboot
2
3# Xen and Dom0 command line options
4QB_XEN_CMDLINE_EXTRA ??= "dom0_mem=192M"
5QB_XEN_DOM0_BOOTARGS ??= \
6 "console=hvc0 earlyprintk clk_ignore_unused root=/dev/vda"
7
8# Launch with one initial domain, dom0, with one boot module, the kernel
9DOM0_KERNEL ??= "${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}"
10DOM0_KERNEL_LOAD_ADDR ??= "0x45000000"
11QB_XEN_DOMAIN_MODULES ??= "${DOM0_KERNEL}:${DOM0_KERNEL_LOAD_ADDR}:multiboot,kernel"
12
13# Qemuboot for 64-bit Arm uses the QB_DEFAULT_KERNEL method to load Xen
14# and the device loader option for the dom0 kernel:
15QB_OPT_APPEND_append_aarch64 = " \
16 -device loader,file=${DOM0_KERNEL},addr=${DOM0_KERNEL_LOAD_ADDR} \
17 "
18QB_DEFAULT_KERNEL_aarch64 = "xen-${MACHINE}"
19
20# 64-bit Arm: gic version 3
21QB_MACHINE_aarch64 = "-machine virt,gic-version=3 -machine virtualization=true"
22
23# Increase the default qemu memory allocation to allow for the hypervisor.
24# Use a weak assignment to allow for change of default and override elsewhere.
25QB_MEM_VALUE ??= "512"
26QB_MEM = "-m ${QB_MEM_VALUE}"
27
28# 64-bit Arm: qemuboot with a device tree binary
29QB_DTB_aarch64 = "${IMAGE_NAME}.qemuboot.dtb"
30QB_DTB_LINK_aarch64 = "${IMAGE_LINK_NAME}.qemuboot.dtb"
diff --git a/classes/qemuboot-xen-dtb.bbclass b/classes/qemuboot-xen-dtb.bbclass
new file mode 100644
index 00000000..08f9b02e
--- /dev/null
+++ b/classes/qemuboot-xen-dtb.bbclass
@@ -0,0 +1,209 @@
1# Enable booting Xen with qemuboot / runqemu: generate device tree
2#
3# Copyright (c) 2021 Star Lab Corp. All rights reserved.
4#
5# Author: Christopher Clark <christopher.clark@starlab.io>
6
7# Interface variables:
8#
9# QB_DTB : defined in qemuboot.bbclass.
10# If set, this class will generate the specified device tree file.
11#
12# QB_XEN_CMDLINE_EXTRA :
13# A string to be appended to the default Xen hypervisor boot command line,
14# for supplying Xen boot options.
15# The device tree that this bbclass generates will contain Xen command
16# line options to connect the Xen console to the Qemu serial port.
17#
18# QB_XEN_DOMAIN_MODULES :
19# A space-separated list of colon-separated entries:
20# "<file for the module>:<load memory address>:<module compatibility string>"
21#
22# QB_XEN_DOM0_BOOTARGS :
23# A string for specifying Dom0 boot options for the Xen section of the device
24# tree.
25#
26# QB_XEN_DTB_TASK_DEPENDS :
27# The task dependencies for the DTB generation. A default is provided.
28#
29# See also: Other QB_ variables as defined by the qemuboot.bbclass.
30
31write_lops_xen_section() {
32 cat <<EOF >"$1"
33/dts-v1/;
34/ {
35 compatible = "system-device-tree-v1";
36 lops {
37 /* Connect the Xen console to Qemu dtuart */
38 lop_1 {
39 compatible = "system-device-tree-v1,lop,code-v1";
40 code = "
41 chosen = node.tree['/chosen']
42 stdout_path = str(chosen['stdout-path'].value[0])
43 chosen['xen,xen-bootargs'] = \
44 'console=dtuart dtuart=%s' % stdout_path
45 return True
46 ";
47 };
48 lop_2 {
49 compatible = "system-device-tree-v1,lop,modify";
50 modify = "/chosen:xen,dom0-bootargs:${QB_XEN_DOM0_BOOTARGS}";
51 };
52 lop_3 {
53 compatible = "system-device-tree-v1,lop,modify";
54 modify = "/chosen:#address-cells:<1>";
55 };
56 lop_4 {
57 compatible = "system-device-tree-v1,lop,modify";
58 modify = "/chosen:#size-cells:<1>";
59 };
60 };
61};
62EOF
63}
64
65write_lop_add_to_xen_cmdline() {
66 EXTRA_XEN_BOOTARGS="$2"
67 cat <<EOF >"$1"
68/dts-v1/;
69/ {
70 compatible = "system-device-tree-v1";
71 lops {
72 lop_1 {
73 compatible = "system-device-tree-v1,lop,code-v1";
74 options = "extra_xen_bootargs:${EXTRA_XEN_BOOTARGS}";
75 code = "
76 chosen = node.tree['/chosen']
77 xen_bootargs = str(chosen['xen,xen-bootargs'].value)
78 chosen['xen,xen-bootargs'] = '%s %s' % \
79 (xen_bootargs, extra_xen_bootargs)
80 return True
81 ";
82 };
83 };
84};
85EOF
86}
87
88write_lop_add_chosen_module() {
89 ADDR="$2"
90 SIZE="$3"
91 MODULE_TYPE="$4"
92 cat <<EOF >"$1"
93/dts-v1/;
94/ {
95 compatible = "system-device-tree-v1";
96 lops {
97 lop_1 {
98 compatible = "system-device-tree-v1,lop,add";
99 node_src = "module@${ADDR}";
100 node_dest = "/chosen/module@${ADDR}";
101
102 module@${ADDR} {
103 compatible = "multiboot,module", "${MODULE_TYPE}";
104 reg = <${ADDR} ${SIZE}>;
105 };
106 };
107 };
108};
109EOF
110}
111
112generate_xen_qemuboot_dtb() {
113 # First: invoke qemu to generate an initial device tree.
114 # Parameters supplied here inspired by inspection of:
115 # runqemu "${IMAGE_BASENAME}" nographic slirp \
116 # qemuparams='-dtb "" -machine dumpdtb=${B}/qemu-dumped.dtb'
117 ${QB_SYSTEM_NAME} \
118 -device qemu-xhci \
119 -device usb-tablet \
120 -device usb-kbd \
121 -machine virt,gic-version=3 \
122 -machine virtualization=true \
123 ${QB_CPU} \
124 ${QB_SMP} \
125 ${QB_MEM} \
126 -nographic \
127 -serial mon:stdio \
128 -machine "dumpdtb=${B}/qemu-dumped.dtb"
129
130 # Lopper generates temporary files in cwd, so run it within ${B}
131 cd "${B}"
132 write_lops_xen_section "${B}/lop-insert-xen-section.dts"
133
134 write_lop_add_to_xen_cmdline "${B}/lop-xen-cmdline.dts" \
135 "${QB_XEN_CMDLINE_EXTRA}"
136
137 if [ -z "${QB_XEN_DOMAIN_MODULES}" ]; then
138 bbwarn "No domain modules: please set QB_XEN_DOMAIN_MODULES"
139 fi
140
141 for DOMAIN_MODULE in ${QB_XEN_DOMAIN_MODULES}
142 do
143 MODULE_FILE="$(echo ${DOMAIN_MODULE} | cut -f1 -d:)"
144 ADDR="$(echo ${DOMAIN_MODULE} | cut -f2 -d:)"
145 MODULE_TYPE="$(echo ${DOMAIN_MODULE} | cut -f3 -d:)"
146 RESOLVED_FILE="$(readlink -f ${MODULE_FILE})"
147 SIZE=$(printf '0x%x\n' $(stat -c '%s' "${RESOLVED_FILE}"))
148 [ "x${SIZE}" != "x0x0" ] || bbfatal No module: "${MODULE_FILE}"
149 write_lop_add_chosen_module "${B}/lop-add-module-${ADDR}.dts" \
150 "${ADDR}" "${SIZE}" "${MODULE_TYPE}"
151 LOP_MODULE_ARGS="${LOP_MODULE_ARGS} -i ${B}/lop-add-module-${ADDR}.dts"
152 done
153
154 QEMUBOOT_DTB="${IMGDEPLOYDIR}/${QB_DTB}"
155 QEMUBOOT_DTB_LINK="${IMGDEPLOYDIR}/${QB_DTB_LINK}"
156
157 lopper.py --werror --verbose \
158 -i "${B}/lop-insert-xen-section.dts" \
159 -i "${B}/lop-xen-cmdline.dts" \
160 ${LOP_MODULE_ARGS} \
161 -f -o "${QEMUBOOT_DTB}" \
162 "${B}/qemu-dumped.dtb"
163
164 # To assist debugging:
165 dtc -I dtb -O dts -o "${B}/output.dts" "${QEMUBOOT_DTB}"
166
167 if [ "${QEMUBOOT_DTB_LINK}" != "${QEMUBOOT_DTB}" ] ; then
168 if [ -e "${QEMUBOOT_DTB_LINK}" ] ; then
169 rm "${QEMUBOOT_DTB_LINK}"
170 fi
171 ln -s "${QB_DTB}" "${QEMUBOOT_DTB_LINK}"
172 fi
173}
174
175do_write_xen_qemuboot_dtb() {
176 # Not all architectures qemuboot with a device tree binary, so check
177 # to see if one is needed. This allows this bbclass file to be used
178 # in the same image recipe for multiple architectures.
179 if [ -n "${QB_DTB}" ] ; then
180 generate_xen_qemuboot_dtb
181 fi
182}
183
184addtask do_write_xen_qemuboot_dtb after do_write_qemuboot_conf before do_image
185# Task dependency:
186# An expected common case is that the kernel for at least one of the initial
187# domains (eg. dom0) is deployed from the virtual/kernel recipe, so
188# add virtual/kernel:do_deploy as a task dependency here since the kernel size
189# needs to be known for generating the device tree.
190# Dependencies are only introduced if a device tree will be generated.
191QB_XEN_DTB_TASK_DEPENDS ?= " \
192 ${@[ ' \
193 qemu-helper-native:do_populate_sysroot \
194 lopper-native:do_populate_sysroot \
195 dtc-native:do_populate_sysroot \
196 virtual/kernel:do_deploy \
197 ', ''][d.getVar('QB_DTB') == '' or d.getVar('QB_DTB') is None]} \
198 "
199do_write_xen_qemuboot_dtb[depends] = "${QB_XEN_DTB_TASK_DEPENDS}"
200
201def qemuboot_dtb_vars(d):
202 build_vars = ['MACHINE', 'TUNE_ARCH', 'DEPLOY_DIR_IMAGE',
203 'KERNEL_IMAGETYPE', 'IMAGE_NAME', 'IMAGE_LINK_NAME',
204 'STAGING_DIR_NATIVE', 'STAGING_BINDIR_NATIVE',
205 'STAGING_DIR_HOST', 'SERIAL_CONSOLES']
206 return build_vars + [k for k in d.keys() if k.startswith('QB_')]
207
208do_write_qemuboot_dtb[vardeps] += "${@' '.join(qemuboot_dtb_vars(d))}"
209do_write_qemuboot_dtb[vardepsexclude] += "TOPDIR"