diff options
| author | Patrick Ohly <patrick.ohly@intel.com> | 2016-12-16 15:18:12 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-03-01 11:17:44 +0000 |
| commit | 715f4e3ec1743a9565cefeee6707edabbd5a2201 (patch) | |
| tree | 057f6894d3c1cb70e906d2cf70a1a16e5198205c /scripts | |
| parent | 63f61a1afff677aaf24525fb7a4fdee8b5c15dea (diff) | |
| download | poky-715f4e3ec1743a9565cefeee6707edabbd5a2201.tar.gz | |
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
(From OE-Core rev: b91fc0893651b9e3069893e36439de0b4e70ad13)
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
| -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): | |||
| 74 | kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required) | 74 | kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required) |
| 75 | publicvnc - enable a VNC server open to all hosts | 75 | publicvnc - enable a VNC server open to all hosts |
| 76 | audio - enable audio | 76 | audio - enable audio |
| 77 | [*/]ovmf* - OVMF firmware file or base name for booting with UEFI | ||
| 77 | tcpserial=<port> - specify tcp serial port number | 78 | tcpserial=<port> - specify tcp serial port number |
| 78 | biosdir=<dir> - specify custom bios dir | 79 | biosdir=<dir> - specify custom bios dir |
| 79 | biosfilename=<filename> - specify bios filename | 80 | biosfilename=<filename> - specify bios filename |
| @@ -175,6 +176,13 @@ class BaseConfig(object): | |||
| 175 | self.clean_nfs_dir = False | 176 | self.clean_nfs_dir = False |
| 176 | self.nfs_server = '' | 177 | self.nfs_server = '' |
| 177 | self.rootfs = '' | 178 | self.rootfs = '' |
| 179 | # File name(s) of a OVMF firmware file or variable store, | ||
| 180 | # to be added with -drive if=pflash. | ||
| 181 | # Found in the same places as the rootfs, with or without one of | ||
| 182 | # these suffices: qcow2, bin. | ||
| 183 | # Setting one also adds "-vga std" because that is all that | ||
| 184 | # OVMF supports. | ||
| 185 | self.ovmf_bios = [] | ||
| 178 | self.qemuboot = '' | 186 | self.qemuboot = '' |
| 179 | self.qbconfload = False | 187 | self.qbconfload = False |
| 180 | self.kernel = '' | 188 | self.kernel = '' |
| @@ -281,6 +289,7 @@ class BaseConfig(object): | |||
| 281 | - Check whether is a kernel file | 289 | - Check whether is a kernel file |
| 282 | - Check whether is a image file | 290 | - Check whether is a image file |
| 283 | - Check whether it is a nfs dir | 291 | - Check whether it is a nfs dir |
| 292 | - Check whether it is a OVMF flash file | ||
| 284 | """ | 293 | """ |
| 285 | if p.endswith('.qemuboot.conf'): | 294 | if p.endswith('.qemuboot.conf'): |
| 286 | self.qemuboot = p | 295 | self.qemuboot = p |
| @@ -321,6 +330,8 @@ class BaseConfig(object): | |||
| 321 | else: | 330 | else: |
| 322 | logger.info("Assuming %s is an nfs rootfs" % p) | 331 | logger.info("Assuming %s is an nfs rootfs" % p) |
| 323 | self.check_arg_nfs(p) | 332 | self.check_arg_nfs(p) |
| 333 | elif os.path.basename(p).startswith('ovmf'): | ||
| 334 | self.ovmf_bios.append(p) | ||
| 324 | else: | 335 | else: |
| 325 | raise Exception("Unknown path arg %s" % p) | 336 | raise Exception("Unknown path arg %s" % p) |
| 326 | 337 | ||
| @@ -406,6 +417,8 @@ class BaseConfig(object): | |||
| 406 | elif re.search(r'-image-|-image$', arg): | 417 | elif re.search(r'-image-|-image$', arg): |
| 407 | # Lazy rootfs | 418 | # Lazy rootfs |
| 408 | self.rootfs = arg | 419 | self.rootfs = arg |
| 420 | elif arg.startswith('ovmf'): | ||
| 421 | self.ovmf_bios.append(arg) | ||
| 409 | else: | 422 | else: |
| 410 | # At last, assume is it the MACHINE | 423 | # At last, assume is it the MACHINE |
| 411 | if (not unknown_arg) or unknown_arg == arg: | 424 | if (not unknown_arg) or unknown_arg == arg: |
| @@ -504,6 +517,20 @@ class BaseConfig(object): | |||
| 504 | if not os.path.exists(self.rootfs): | 517 | if not os.path.exists(self.rootfs): |
| 505 | raise Exception("Can't find rootfs: %s" % self.rootfs) | 518 | raise Exception("Can't find rootfs: %s" % self.rootfs) |
| 506 | 519 | ||
| 520 | def check_ovmf(self): | ||
| 521 | """Check and set full path for OVMF firmware and variable file(s).""" | ||
| 522 | |||
| 523 | for index, ovmf in enumerate(self.ovmf_bios): | ||
| 524 | if os.path.exists(ovmf): | ||
| 525 | continue | ||
| 526 | for suffix in ('qcow2', 'bin'): | ||
| 527 | path = '%s/%s.%s' % (self.get('DEPLOY_DIR_IMAGE'), ovmf, suffix) | ||
| 528 | if os.path.exists(path): | ||
| 529 | self.ovmf_bios[index] = path | ||
| 530 | break | ||
| 531 | else: | ||
| 532 | raise Exception("Can't find OVMF firmware: %s" % ovmf) | ||
| 533 | |||
| 507 | def check_kernel(self): | 534 | def check_kernel(self): |
| 508 | """Check and set kernel, dtb""" | 535 | """Check and set kernel, dtb""" |
| 509 | # The vm image doesn't need a kernel | 536 | # The vm image doesn't need a kernel |
| @@ -598,6 +625,7 @@ class BaseConfig(object): | |||
| 598 | self.check_kvm() | 625 | self.check_kvm() |
| 599 | self.check_fstype() | 626 | self.check_fstype() |
| 600 | self.check_rootfs() | 627 | self.check_rootfs() |
| 628 | self.check_ovmf() | ||
| 601 | self.check_kernel() | 629 | self.check_kernel() |
| 602 | self.check_biosdir() | 630 | self.check_biosdir() |
| 603 | self.check_mem() | 631 | self.check_mem() |
| @@ -706,6 +734,8 @@ class BaseConfig(object): | |||
| 706 | print('NFS_DIR: [%s]' % self.nfs_dir) | 734 | print('NFS_DIR: [%s]' % self.nfs_dir) |
| 707 | else: | 735 | else: |
| 708 | print('ROOTFS: [%s]' % self.rootfs) | 736 | print('ROOTFS: [%s]' % self.rootfs) |
| 737 | if self.ovmf_bios: | ||
| 738 | print('OVMF: %s' % self.ovmf_bios) | ||
| 709 | print('CONFFILE: [%s]' % self.qemuboot) | 739 | print('CONFFILE: [%s]' % self.qemuboot) |
| 710 | print('') | 740 | print('') |
| 711 | 741 | ||
| @@ -1012,7 +1042,17 @@ class BaseConfig(object): | |||
| 1012 | 1042 | ||
| 1013 | check_libgl(qemu_bin) | 1043 | check_libgl(qemu_bin) |
| 1014 | 1044 | ||
| 1015 | 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) | 1045 | self.qemu_opt = "%s %s %s %s" % (qemu_bin, self.get('NETWORK_CMD'), self.get('ROOTFS_OPTIONS'), self.get('QB_OPT_APPEND')) |
| 1046 | |||
| 1047 | for ovmf in self.ovmf_bios: | ||
| 1048 | format = ovmf.rsplit('.', 1)[-1] | ||
| 1049 | self.qemu_opt += ' -drive if=pflash,format=%s,file=%s' % (format, ovmf) | ||
| 1050 | if self.ovmf_bios: | ||
| 1051 | # OVMF only supports normal VGA, i.e. we need to override a -vga vmware | ||
| 1052 | # that gets added for example for normal qemux86. | ||
| 1053 | self.qemu_opt += ' -vga std' | ||
| 1054 | |||
| 1055 | self.qemu_opt += ' ' + self.qemu_opt_script | ||
| 1016 | 1056 | ||
| 1017 | if self.snapshot: | 1057 | if self.snapshot: |
| 1018 | self.qemu_opt += " -snapshot" | 1058 | self.qemu_opt += " -snapshot" |
