summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--classes/qemuboot-xen-defaults.bbclass30
-rw-r--r--classes/qemuboot-xen-dtb.bbclass209
-rw-r--r--conf/distro/include/meta-virt-xen.inc3
-rw-r--r--recipes-extended/images/xen-image-minimal.bb5
4 files changed, 245 insertions, 2 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"
diff --git a/conf/distro/include/meta-virt-xen.inc b/conf/distro/include/meta-virt-xen.inc
index 02a78105..2becba15 100644
--- a/conf/distro/include/meta-virt-xen.inc
+++ b/conf/distro/include/meta-virt-xen.inc
@@ -10,3 +10,6 @@ XEN_RPI4_64_CONFIG_PATH ??= \
10 'dynamic-layers/raspberrypi/conf/distro/include/xen-raspberrypi4-64.inc' 10 'dynamic-layers/raspberrypi/conf/distro/include/xen-raspberrypi4-64.inc'
11include ${@bb.utils.contains('MACHINE', 'raspberrypi4-64', \ 11include ${@bb.utils.contains('MACHINE', 'raspberrypi4-64', \
12 '${XEN_RPI4_64_CONFIG_PATH}', '', d)} 12 '${XEN_RPI4_64_CONFIG_PATH}', '', d)}
13
14# Set serial for working qemuboot console
15SERIAL_CONSOLES_qemuarm64 ?= "115200;ttyAMA0"
diff --git a/recipes-extended/images/xen-image-minimal.bb b/recipes-extended/images/xen-image-minimal.bb
index 6733801c..ca6d2683 100644
--- a/recipes-extended/images/xen-image-minimal.bb
+++ b/recipes-extended/images/xen-image-minimal.bb
@@ -31,7 +31,7 @@ XEN_PCIBACK_MODULE_x86-64 = "kernel-module-xen-pciback"
31 31
32LICENSE = "MIT" 32LICENSE = "MIT"
33 33
34inherit core-image 34inherit core-image qemuboot-xen-defaults qemuboot-xen-dtb
35 35
36do_check_xen_state() { 36do_check_xen_state() {
37 if [ "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ' yes', 'no', d)}" = "no" ]; then 37 if [ "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ' yes', 'no', d)}" = "no" ]; then
@@ -74,10 +74,11 @@ build_syslinux_cfg () {
74 74
75# Enable runqemu. eg: runqemu xen-image-minimal nographic slirp 75# Enable runqemu. eg: runqemu xen-image-minimal nographic slirp
76WKS_FILE_x86-64 = "directdisk-xen.wks" 76WKS_FILE_x86-64 = "directdisk-xen.wks"
77QB_MEM ?= "-m 400"
78QB_DEFAULT_KERNEL ?= "none" 77QB_DEFAULT_KERNEL ?= "none"
79QB_DEFAULT_FSTYPE ?= "wic" 78QB_DEFAULT_FSTYPE ?= "wic"
79QB_DEFAULT_FSTYPE_qemux86-64 = "wic"
80QB_FSINFO ?= "wic:kernel-in-fs" 80QB_FSINFO ?= "wic:kernel-in-fs"
81QB_SERIAL_OPT = "-serial mon:stdio"
81# qemux86-64 machine does not include 'wic' in IMAGE_FSTYPES, which is needed 82# qemux86-64 machine does not include 'wic' in IMAGE_FSTYPES, which is needed
82# to boot this image, so add it here: 83# to boot this image, so add it here:
83IMAGE_FSTYPES_qemux86-64 += "wic" 84IMAGE_FSTYPES_qemux86-64 += "wic"