1515import utils
1616
1717BOOT_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
2130class 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+
296392class 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