Skip to content

Commit

Permalink
boot-qemu.py: Add support for booting ARCH=arm kernels via EFI
Browse files Browse the repository at this point in the history
arm kernels can be booted via EFI in the same manner as arm64. Refactor
the current EFI image creation logic into its own class so that
arm32_v7 and arm64 can share most of the logic, just with different
files.

Signed-off-by: Nathan Chancellor <[email protected]>
  • Loading branch information
nathanchance committed Feb 27, 2024
1 parent 1e85bca commit 64bae25
Showing 1 changed file with 38 additions and 22 deletions.
60 changes: 38 additions & 22 deletions boot-qemu.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,31 @@ def run(self):
self._run_fg()


class ARMEFIQEMURunner(QEMURunner):

def _setup_efi(self, possible_locations):
# Sizing the images to 64M is recommended by "Prepare the firmware" section at
# https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/docs/qemu/qemu-arm64-howto.html
efi_img_size = 64 * 1024 * 1024 # 64M

usr_share = Path('/usr/share')

aavmf = utils.find_first_file(usr_share, possible_locations)

self._efi_img = Path(utils.BOOT_UTILS, 'images', self._initrd_arch,
'efi.img')
# This file is in /usr/share, so it must be copied in order to be
# modified.
shutil.copyfile(aavmf, self._efi_img)
with self._efi_img.open(mode='r+b') as file:
file.truncate(efi_img_size)

self._efi_vars = self._efi_img.with_name('efivars.img')
self._efi_vars.unlink(missing_ok=True)
with self._efi_vars.open(mode='xb') as file:
file.truncate(efi_img_size)


class ARMQEMURunner(QEMURunner):

def __init__(self):
Expand Down Expand Up @@ -359,11 +384,12 @@ def __init__(self):
self._machine = 'romulus-bmc'


class ARMV7QEMURunner(ARMQEMURunner):
class ARMV7QEMURunner(ARMQEMURunner, ARMEFIQEMURunner):

def __init__(self):
super().__init__()

self.supports_efi = True
self.use_kvm = self._can_use_kvm()

self.cmdline += ['console=ttyAMA0', 'earlycon']
Expand All @@ -385,15 +411,24 @@ def _can_use_kvm(self):

return self._have_dev_kvm_access()

def _setup_efi(self):
aavmf_locations = [
Path('edk2/arm/QEMU_EFI.fd'), # Arch Linux, Fedora
]
super()._setup_efi(aavmf_locations)

def run(self):
if self.efi:
self._setup_efi()

if self.use_kvm:
self._kvm_cpu.append('aarch64=off')
self._qemu_arch = 'aarch64'

super().run()


class ARM64QEMURunner(QEMURunner):
class ARM64QEMURunner(ARMEFIQEMURunner):

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -430,32 +465,13 @@ def _get_cpu_val(self):
return cpu

def _setup_efi(self):
# Sizing the images to 64M is recommended by "Prepare the firmware" section at
# https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/docs/qemu/qemu-arm64-howto.html
efi_img_size = 64 * 1024 * 1024 # 64M

usr_share = Path('/usr/share')

aavmf_locations = [
Path('edk2/aarch64/QEMU_EFI.silent.fd'), # Fedora
Path('edk2/aarch64/QEMU_EFI.fd'), # Arch Linux (current)
Path('edk2-armvirt/aarch64/QEMU_EFI.fd'), # Arch Linux (old)
Path('qemu-efi-aarch64/QEMU_EFI.fd'), # Debian and Ubuntu
]
aavmf = utils.find_first_file(usr_share, aavmf_locations)

self._efi_img = Path(utils.BOOT_UTILS, 'images', self._initrd_arch,
'efi.img')
# This file is in /usr/share, so it must be copied in order to be
# modified.
shutil.copyfile(aavmf, self._efi_img)
with self._efi_img.open(mode='r+b') as file:
file.truncate(efi_img_size)

self._efi_vars = self._efi_img.with_name('efivars.img')
self._efi_vars.unlink(missing_ok=True)
with self._efi_vars.open(mode='xb') as file:
file.truncate(efi_img_size)
super()._setup_efi(aavmf_locations)

def run(self):
machine = ['virt', 'gic-version=max']
Expand Down

0 comments on commit 64bae25

Please sign in to comment.