diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2016-12-16 15:18:12 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-02-28 11:26:32 +0000 |
commit | b91fc0893651b9e3069893e36439de0b4e70ad13 (patch) | |
tree | 16b6fae2f86069838f69406540428f0033066982 | |
parent | ca0fad3ad9d75d4198388b2a3133326267fc58db (diff) | |
download | openembedded-core-b91fc0893651b9e3069893e36439de0b4e70ad13.tar.gz openembedded-core-b91fc0893651b9e3069893e36439de0b4e70ad13.tar.bz2 openembedded-core-b91fc0893651b9e3069893e36439de0b4e70ad13.zip |
runqemu: support UEFI with OVMF firmware
In the simplest case, "runqemu qemux86 <some-image> qcow2 ovmf" for an
EFI-enabled image in the qcow2 format will locate the ovmf.qcow2
firmware file deployed by the ovmf recipe in the image deploy
directory, override the graphics hardware with "-vga std" because that
is all that OVMF supports, and boot with UEFI enabled.
ovmf is not built by default. Either do it explicitly ("bitbake ovmf")
or make it a part of the normal build
("MACHINE_ESSENTIAL_EXTRA_RDEPENDS_append = ' ovmf'").
The firmware file is activated as a flash drive instead of using the
qemu BIOS parameters, because that is the recommended method
(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=764918#47) as it
allows storing UEFI variables in the file.
Instead of just "ovmf", a full path to an existing file can also be
used, just as with the rootfs. That may be useful when making a
permanent copy of the virtual machine data files.
It is possible to specify "ovmf*" parameters more than once, then
each parameter creates a separate flash drive. This way it is possible
to use separate flash drives for firmware code and variables:
$ runqemu qemux86 <some-image> qcow2 ovmf.code ovmf.vars"
Note that rebuilding ovmf will overwrite the ovmf.vars.qcow2 file in
the image deploy directory. So when the goal is to update the firmware
while keeping variables, make a copy of the variable file and use
that:
$ mkdir my-machine
$ cp tmp/deploy/images/qemux86/ovmf.vars.qcow2 my-machine/
$ runqemu qemux86 <some-image> qcow2 ovmf.code my-machine/ovmf.vars.qcow2
When Secure Boot was enabled in ovmf, one can pick that instead of
the non-Secure-Boot enabled ovmf.code:
$ runqemu qemux86 <some-image> qcow2 ovmf.secboot.code my-machine/ovmf.vars.qcow2
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
-rwxr-xr-x | scripts/runqemu | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/scripts/runqemu b/scripts/runqemu index 918141238c..4d8fc8ec3c 100755 --- a/scripts/runqemu +++ b/scripts/runqemu @@ -74,6 +74,7 @@ of the following environment variables (in any order): kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required) publicvnc - enable a VNC server open to all hosts audio - enable audio + [*/]ovmf* - OVMF firmware file or base name for booting with UEFI tcpserial=<port> - specify tcp serial port number biosdir=<dir> - specify custom bios dir biosfilename=<filename> - specify bios filename @@ -175,6 +176,13 @@ class BaseConfig(object): self.clean_nfs_dir = False self.nfs_server = '' self.rootfs = '' + # File name(s) of a OVMF firmware file or variable store, + # to be added with -drive if=pflash. + # Found in the same places as the rootfs, with or without one of + # these suffices: qcow2, bin. + # Setting one also adds "-vga std" because that is all that + # OVMF supports. + self.ovmf_bios = [] self.qemuboot = '' self.qbconfload = False self.kernel = '' @@ -281,6 +289,7 @@ class BaseConfig(object): - Check whether is a kernel file - Check whether is a image file - Check whether it is a nfs dir + - Check whether it is a OVMF flash file """ if p.endswith('.qemuboot.conf'): self.qemuboot = p @@ -321,6 +330,8 @@ class BaseConfig(object): else: logger.info("Assuming %s is an nfs rootfs" % p) self.check_arg_nfs(p) + elif os.path.basename(p).startswith('ovmf'): + self.ovmf_bios.append(p) else: raise Exception("Unknown path arg %s" % p) @@ -406,6 +417,8 @@ class BaseConfig(object): elif re.search(r'-image-|-image$', arg): # Lazy rootfs self.rootfs = arg + elif arg.startswith('ovmf'): + self.ovmf_bios.append(arg) else: # At last, assume is it the MACHINE if (not unknown_arg) or unknown_arg == arg: @@ -504,6 +517,20 @@ class BaseConfig(object): if not os.path.exists(self.rootfs): raise Exception("Can't find rootfs: %s" % self.rootfs) + def check_ovmf(self): + """Check and set full path for OVMF firmware and variable file(s).""" + + for index, ovmf in enumerate(self.ovmf_bios): + if os.path.exists(ovmf): + continue + for suffix in ('qcow2', 'bin'): + path = '%s/%s.%s' % (self.get('DEPLOY_DIR_IMAGE'), ovmf, suffix) + if os.path.exists(path): + self.ovmf_bios[index] = path + break + else: + raise Exception("Can't find OVMF firmware: %s" % ovmf) + def check_kernel(self): """Check and set kernel, dtb""" # The vm image doesn't need a kernel @@ -598,6 +625,7 @@ class BaseConfig(object): self.check_kvm() self.check_fstype() self.check_rootfs() + self.check_ovmf() self.check_kernel() self.check_biosdir() self.check_mem() @@ -706,6 +734,8 @@ class BaseConfig(object): print('NFS_DIR: [%s]' % self.nfs_dir) else: print('ROOTFS: [%s]' % self.rootfs) + if self.ovmf_bios: + print('OVMF: %s' % self.ovmf_bios) print('CONFFILE: [%s]' % self.qemuboot) print('') @@ -1012,7 +1042,17 @@ class BaseConfig(object): check_libgl(qemu_bin) - self.qemu_opt = "%s %s %s %s %s" % (qemu_bin, self.get('NETWORK_CMD'), self.get('ROOTFS_OPTIONS'), self.get('QB_OPT_APPEND'), self.qemu_opt_script) + self.qemu_opt = "%s %s %s %s" % (qemu_bin, self.get('NETWORK_CMD'), self.get('ROOTFS_OPTIONS'), self.get('QB_OPT_APPEND')) + + for ovmf in self.ovmf_bios: + format = ovmf.rsplit('.', 1)[-1] + self.qemu_opt += ' -drive if=pflash,format=%s,file=%s' % (format, ovmf) + if self.ovmf_bios: + # OVMF only supports normal VGA, i.e. we need to override a -vga vmware + # that gets added for example for normal qemux86. + self.qemu_opt += ' -vga std' + + self.qemu_opt += ' ' + self.qemu_opt_script if self.snapshot: self.qemu_opt += " -snapshot" |