Skip to content

Commit 7a1363b

Browse files
committed
boot-qemu.py: Implement '--efi'
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
1 parent b4d6205 commit 7a1363b

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

boot-qemu.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def __init__(self):
2323

2424
# Properties that can be adjusted by the user or class
2525
self.cmdline = []
26+
self.efi = False
2627
self.interactive = False
2728
self.kernel = None
2829
self.kernel_dir = None
@@ -35,6 +36,8 @@ def __init__(self):
3536
self.timeout = ''
3637

3738
self._default_kernel_path = None
39+
self._efi_img = None
40+
self._efi_vars = None
3841
self._initrd_arch = None
3942
self._kvm_cpu = 'host'
4043
self._qemu_arch = None
@@ -142,6 +145,15 @@ def run(self):
142145
f"{self._default_kernel_path.name} could not be found at possible locations ('{possible_locations}')",
143146
)
144147

148+
# EFI:
149+
if self.efi:
150+
self._qemu_args += [
151+
'-drive', f"if=pflash,format=raw,file={self._efi_img},readonly=on",
152+
'-drive', f"if=pflash,format=raw,file={self._efi_vars}",
153+
'-object', 'rng-random,filename=/dev/urandom,id=rng0',
154+
'-device', 'virtio-rng-pci',
155+
] # yapf: disable
156+
145157
# Kernel options
146158
if self.interactive:
147159
self.cmdline.append('rdinit=/bin/sh')
@@ -187,6 +199,9 @@ def run(self):
187199
utils.red("ERROR: QEMU did not exit cleanly!")
188200
sys.exit(err.returncode)
189201

202+
def supports_efi(self):
203+
return False
204+
190205

191206
class X86QEMURunner(QEMURunner):
192207

@@ -203,7 +218,10 @@ def _can_use_kvm(self):
203218
return platform.machine() == 'x86_64' and self._have_dev_kvm_access()
204219

205220
def run(self):
206-
if self.use_kvm:
221+
if self.use_kvm and not self.efi:
222+
# There are a lot of messages along the line of
223+
# "Invalid read at addr 0xFED40000, size 1, region '(null)', reason: rejected"
224+
# with EFI, so do not bother.
207225
self._qemu_args += ['-d', 'unimp,guest_errors']
208226

209227
super().run()
@@ -216,10 +234,31 @@ def __init__(self):
216234

217235
self._initrd_arch = self._qemu_arch = 'x86_64'
218236

237+
def supports_efi(self):
238+
return True
239+
219240
def run(self):
220241
if not self.use_kvm:
221242
self._qemu_args += ['-cpu', 'Nehalem']
222243

244+
if self.efi:
245+
usr_share = Path('/usr/share')
246+
ovmf_locations = [
247+
Path('edk2/x64/OVMF_CODE.fd'), # Arch Linux (current), Fedora
248+
Path('edk2-ovmf/x64/OVMF_CODE.fd'), # Arch Linux (old)
249+
Path('OVMF/OVMF_CODE.fd'), # Debian and Ubuntu
250+
]
251+
self._efi_img = utils.find_first_file(usr_share, ovmf_locations)
252+
253+
ovmf_vars_locations = [
254+
Path('edk2/x64/OVMF_VARS.fd'), # Arch Linux and Fedora
255+
Path('OVMF/OVMF_VARS.fd'), # Debian and Ubuntu
256+
]
257+
ovmf_vars = utils.find_first_file(usr_share, ovmf_vars_locations)
258+
self._efi_vars = Path(BOOT_UTILS, 'images', self.initrd_arch,
259+
ovmf_vars.name)
260+
shutil.copyfile(ovmf_vars, self._efi_vars)
261+
223262
super().run()
224263

225264

@@ -233,6 +272,9 @@ def parse_arguments():
233272
help='The architecture to boot. Possible values are: %(choices)s',
234273
metavar='ARCH',
235274
required=True)
275+
parser.add_argument('--efi',
276+
action='store_true',
277+
help='Boot kernel via UEFI (x86_64 only)')
236278
parser.add_argument(
237279
'-k',
238280
'--kernel-location',
@@ -286,6 +328,13 @@ def parse_arguments():
286328
if args.append:
287329
runner.cmdline += args.append
288330

331+
if args.efi:
332+
runner.efi = runner.supports_efi()
333+
if not runner.efi:
334+
utils.yellow(
335+
f"EFI boot requested on unsupported architecture ('{args.architecture}'), ignoring...",
336+
)
337+
289338
if args.no_kvm:
290339
runner.use_kvm = False
291340

0 commit comments

Comments
 (0)