Skip to content

Commit 81286a4

Browse files
committed
boot-qemu.py: Add support for arm32
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
1 parent d5353c9 commit 81286a4

1 file changed

Lines changed: 103 additions & 3 deletions

File tree

boot-qemu.py

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@
1515
import utils
1616

1717
BOOT_UTILS = Path(__file__).resolve().parent
18-
SUPPORTED_ARCHES = ['arm64', 'arm64be', 'x86', 'x86_64']
18+
SUPPORTED_ARCHES = [
19+
'arm',
20+
'arm32_v5',
21+
'arm32_v6',
22+
'arm32_v7',
23+
'arm64',
24+
'arm64be',
25+
'x86',
26+
'x86_64',
27+
]
1928

2029

2130
class QEMURunner:
@@ -39,10 +48,11 @@ def __init__(self):
3948
self.timeout = ''
4049

4150
self._default_kernel_path = None
51+
self._dtb = None
4252
self._efi_img = None
4353
self._efi_vars = None
4454
self._initrd_arch = None
45-
self._kvm_cpu = 'host'
55+
self._kvm_cpu = ['host']
4656
self._qemu_arch = None
4757
self._qemu_args = [
4858
'-display', 'none',
@@ -55,6 +65,23 @@ def __init__(self):
5565
def _can_use_kvm(self):
5666
return False
5767

68+
def _find_dtb(self):
69+
if not self._dtb:
70+
raise RuntimeError('No dtb set?')
71+
if not self.kernel:
72+
raise RuntimeError('Cannot locate dtb without kernel')
73+
74+
# If we are in a boot folder, look for them in the dts folder in it.
75+
# Otherwise, assume there is a 'dtbs' folder in the same folder as the
76+
# kernel image (tuxmake)
77+
dtb_dir = 'dts' if self.kernel.parent.name == 'boot' else 'dtbs'
78+
if not (dtb := Path(self.kernel.parent, dtb_dir, self._dtb)).exists():
79+
raise FileNotFoundError(
80+
f"dtb ('{self._dtb}') is required for booting but it could not be found at expected location ('{dtb}')",
81+
)
82+
83+
return dtb
84+
5885
def _get_default_smp_value(self):
5986
if not self.kernel_dir:
6087
raise RuntimeError('No kernel build folder specified?')
@@ -262,14 +289,16 @@ def run(self):
262289
self.cmdline.append('nokaslr')
263290
if self.cmdline:
264291
self._qemu_args += ['-append', ' '.join(self.cmdline)]
292+
if self._dtb:
293+
self._qemu_args += ['-dtb', self._find_dtb()]
265294
self._qemu_args += ['-kernel', self.kernel]
266295
self._qemu_args += ['-initrd', self._prepare_initrd()]
267296

268297
# KVM
269298
if self.use_kvm:
270299
if not self.smp:
271300
self.smp = self._get_default_smp_value()
272-
self._qemu_args += ['-cpu', self._kvm_cpu, '-enable-kvm']
301+
self._qemu_args += ['-cpu', ','.join(self._kvm_cpu), '-enable-kvm']
273302

274303
# Machine specs
275304
self._qemu_args += ['-m', self._ram]
@@ -293,6 +322,73 @@ def supports_efi(self):
293322
return False
294323

295324

325+
class ARMQEMURunner(QEMURunner):
326+
327+
def __init__(self):
328+
super().__init__()
329+
330+
self._default_kernel_path = Path('arch/arm/boot/zImage')
331+
self._initrd_arch = self._qemu_arch = 'arm'
332+
self._machine = 'virt'
333+
334+
def run(self):
335+
self._qemu_args += ['-machine', self._machine]
336+
337+
super().run()
338+
339+
340+
class ARMV5QEMURunner(ARMQEMURunner):
341+
342+
def __init__(self):
343+
super().__init__()
344+
345+
self.cmdline.append('earlycon')
346+
347+
self._dtb = 'aspeed-bmc-opp-palmetto.dtb'
348+
self._machine = 'palmetto-bmc'
349+
350+
351+
class ARMV6QEMURunner(ARMQEMURunner):
352+
353+
def __init__(self):
354+
super().__init__()
355+
356+
self._dtb = 'aspeed-bmc-opp-romulus.dtb'
357+
self._machine = 'romulus-bmc'
358+
359+
360+
class ARMV7QEMURunner(ARMQEMURunner):
361+
362+
def __init__(self):
363+
super().__init__()
364+
365+
self.cmdline += ['console=ttyAMA0', 'earlycon']
366+
367+
def _can_use_kvm(self):
368+
# 32-bit ARM KVM was ripped out in 5.7, so we do not bother checking
369+
# for it here.
370+
if platform.machine() != 'aarch64':
371+
return False
372+
373+
# 32-bit EL1 is not supported on all cores so support for it must be
374+
# explicitly queried via the KVM_CHECK_EXTENSION ioctl().
375+
try:
376+
subprocess.run(Path(BOOT_UTILS, 'utils',
377+
'aarch64_32_bit_el1_supported'),
378+
check=True)
379+
except subprocess.CalledProcessError:
380+
return False
381+
382+
return self._have_dev_kvm_access()
383+
384+
def run(self):
385+
if self.use_kvm:
386+
self._kvm_cpu.append('aarch64=off')
387+
self._qemu_arch = 'aarch64'
388+
389+
super().run()
390+
391+
296392
class ARM64QEMURunner(QEMURunner):
297393

298394
def __init__(self):
@@ -498,6 +594,10 @@ def parse_arguments():
498594
args = parse_arguments()
499595

500596
arch_to_runner = {
597+
'arm': ARMV7QEMURunner,
598+
'arm32_v5': ARMV5QEMURunner,
599+
'arm32_v6': ARMV6QEMURunner,
600+
'arm32_v7': ARMV7QEMURunner,
501601
'arm64': ARM64QEMURunner,
502602
'arm64be': ARM64BEQEMURunner,
503603
'x86': X86QEMURunner,

0 commit comments

Comments
 (0)