]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Generalize QemuBios to QemuFirmware
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 1 Sep 2023 12:33:09 +0000 (14:33 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 1 Sep 2023 14:03:15 +0000 (16:03 +0200)
We also add a third option "none", in which case we'll use direct
kernel boot.

.github/workflows/ci.yml
mkosi/config.py
mkosi/qemu.py
mkosi/resources/mkosi.md

index f68d9297dd09b8b504a5e2ae5bcadb03a534daee..df7d978e66ce7e5b070456d146070a9e4e0deaa4 100644 (file)
@@ -144,4 +144,4 @@ jobs:
 
     - name: Boot ${{ matrix.distro }}/${{ matrix.format }} BIOS
       if: matrix.format == 'disk'
-      run: timeout -k 30 10m mkosi --debug --qemu-bios qemu
+      run: timeout -k 30 10m mkosi --debug --qemu-firmware bios qemu
index 4694b3be5928f1daeaa46073208a277bc41d3c03..a2c3e3733cfe97ed82a8924d1ec567e85e612f1c 100644 (file)
@@ -127,6 +127,12 @@ class BiosBootloader(StrEnum):
     grub = enum.auto()
 
 
+class QemuFirmware(StrEnum):
+    direct = enum.auto()
+    uefi   = enum.auto()
+    bios   = enum.auto()
+
+
 def parse_boolean(s: str) -> bool:
     "Parse 1/true/yes/y/t/on as true and 0/false/no/n/f/off/None as false"
     s_l = s.lower()
@@ -724,7 +730,7 @@ class MkosiConfig:
     qemu_vsock: ConfigFeature
     qemu_swtpm: ConfigFeature
     qemu_cdrom: bool
-    qemu_bios: bool
+    qemu_firmware: QemuFirmware
     qemu_args: Sequence[str]
 
     preset: Optional[str]
@@ -1567,12 +1573,13 @@ SETTINGS = (
         help="Attach the image as a CD-ROM to the virtual machine",
     ),
     MkosiConfigSetting(
-        dest="qemu_bios",
-        metavar="BOOLEAN",
-        nargs="?",
+        dest="qemu_firmware",
+        metavar="FIRMWARE",
         section="Host",
-        parse=config_parse_boolean,
-        help="Boot QEMU with SeaBIOS instead of EDK2",
+        parse=config_make_enum_parser(QemuFirmware),
+        default=QemuFirmware.uefi,
+        help="Set qemu firmware to use",
+        choices=QemuFirmware.values(),
     ),
     MkosiConfigSetting(
         dest="qemu_args",
@@ -2385,7 +2392,7 @@ Clean Package Manager Metadata: {yes_no_auto(config.clean_package_metadata)}
                 QEMU Use VSock: {config.qemu_vsock}
                 QEMU Use Swtpm: {config.qemu_swtpm}
                QEMU Use CD-ROM: {yes_no(config.qemu_cdrom)}
-                     QEMU BIOS: {yes_no(config.qemu_bios)}
+                 QEMU Firmware: {config.qemu_firmware}
           QEMU Extra Arguments: {line_join_list(config.qemu_args)}
 """
 
index 6c9fffe68428d978eecd534801120f9cd6354cc3..02f8dcc18ff780df5c235d635bf7d55d3e639102 100644 (file)
@@ -16,7 +16,13 @@ from pathlib import Path
 from typing import Iterator, Optional
 
 from mkosi.architecture import Architecture
-from mkosi.config import ConfigFeature, MkosiArgs, MkosiConfig, OutputFormat
+from mkosi.config import (
+    ConfigFeature,
+    MkosiArgs,
+    MkosiConfig,
+    OutputFormat,
+    QemuFirmware,
+)
 from mkosi.log import die
 from mkosi.run import MkosiAsyncioThread, run, spawn
 from mkosi.tree import copy_tree, rmtree
@@ -39,7 +45,7 @@ def find_qemu_binary(config: MkosiConfig) -> str:
     die("Couldn't find QEMU/KVM binary")
 
 
-def find_qemu_firmware(config: MkosiConfig) -> tuple[Path, bool]:
+def find_ovmf_firmware(config: MkosiConfig) -> tuple[Path, bool]:
     FIRMWARE_LOCATIONS = {
         Architecture.x86_64: ["/usr/share/ovmf/x64/OVMF_CODE.secboot.fd"],
         Architecture.x86: [
@@ -211,8 +217,8 @@ def run_qemu(args: MkosiArgs, config: MkosiConfig) -> None:
     if config.qemu_kvm == ConfigFeature.enabled or auto:
         accel = "kvm"
 
-    firmware, fw_supports_sb = find_qemu_firmware(config)
-    smm = "on" if fw_supports_sb and not config.qemu_bios else "off"
+    firmware, fw_supports_sb = find_ovmf_firmware(config)
+    smm = "on" if config.qemu_firmware == QemuFirmware.uefi and fw_supports_sb else "off"
 
     if config.architecture == Architecture.arm64:
         machine = f"type=virt,accel={accel}"
@@ -254,13 +260,13 @@ def run_qemu(args: MkosiArgs, config: MkosiConfig) -> None:
     cmdline += ["-smbios", f"type=11,value=io.systemd.stub.kernel-cmdline-extra={' '.join(config.kernel_command_line_extra)}"]
 
     # QEMU has built-in logic to look for the BIOS firmware so we don't need to do anything special for that.
-    if not config.qemu_bios:
+    if config.qemu_firmware == QemuFirmware.uefi:
         cmdline += ["-drive", f"if=pflash,format=raw,readonly=on,file={firmware}"]
 
     notifications: dict[str, str] = {}
 
     with contextlib.ExitStack() as stack:
-        if fw_supports_sb and not config.qemu_bios:
+        if config.qemu_firmware == QemuFirmware.uefi and fw_supports_sb:
             ovmf_vars = stack.enter_context(tempfile.NamedTemporaryFile(prefix=".mkosi-"))
             shutil.copy2(find_ovmf_vars(config), Path(ovmf_vars.name))
             cmdline += [
@@ -298,19 +304,22 @@ def run_qemu(args: MkosiArgs, config: MkosiConfig) -> None:
                  "--offline=yes",
                  fname])
 
-        if config.output_format == OutputFormat.cpio:
+        if config.qemu_firmware == QemuFirmware.direct or config.output_format == OutputFormat.cpio:
             kernel = config.output_dir / config.output_split_kernel
             if not kernel.exists() and "-kernel" not in args.cmdline:
-                die("No kernel found, please install a kernel in the cpio or provide a -kernel argument to mkosi qemu")
+                die("No kernel found, please install a kernel in the image or provide a -kernel argument to mkosi qemu")
+
             cmdline += ["-kernel", kernel,
-                        "-initrd", fname,
                         "-append", " ".join(config.kernel_command_line + config.kernel_command_line_extra)]
 
-        cmdline += ["-drive", f"if=none,id=mkosi,file={fname},format=raw",
-                    "-device", "virtio-scsi-pci,id=scsi",
-                    "-device", f"scsi-{'cd' if config.qemu_cdrom else 'hd'},drive=mkosi,bootindex=1"]
+        if config.output_format == OutputFormat.cpio:
+            cmdline += ["-initrd", fname]
+        else:
+            cmdline += ["-drive", f"if=none,id=mkosi,file={fname},format=raw",
+                        "-device", "virtio-scsi-pci,id=scsi",
+                        "-device", f"scsi-{'cd' if config.qemu_cdrom else 'hd'},drive=mkosi,bootindex=1"]
 
-        if config.qemu_swtpm != ConfigFeature.disabled and shutil.which("swtpm") is not None and not config.qemu_bios:
+        if config.qemu_firmware == QemuFirmware.uefi and config.qemu_swtpm != ConfigFeature.disabled and shutil.which("swtpm") is not None:
             sock = stack.enter_context(start_swtpm())
             cmdline += ["-chardev", f"socket,id=chrtpm,path={sock}",
                         "-tpmdev", "emulator,id=tpm0,chardev=chrtpm"]
index 5670c85c9b89000720fba20039f1bad09d5f77ff..f645fddb439e93744010e6402a011b71e8b6490a 100644 (file)
@@ -1047,11 +1047,21 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
   attach the image to the virtual machine as a CD-ROM device. Takes a
   boolean. Defaults to `no`.
 
-`QemuBios=`, `--qemu-bios=`
-
-: When used with the `qemu` verb, this option specifies whether to use
-  the BIOS firmware instead of the UEFI firmware. Takes a boolean.
-  Defaults to `no`.
+`QemuFirmware=`, `--qemu-firmware=`
+
+: When used with the `qemu` verb, this option which firmware to use.
+  Takes one of `uefi`, `bios` or `direct`. Defaults to `uefi`. When set
+  to `uefi`, the OVMF firmware is used. When set to `bios`, the default
+  SeaBIOS firmware is used. When set to `direct`, direct kernel boot is
+  used. The kernel used for direct kernel boot can either be provided by
+  passing qemu's `-kernel` option on the mkosi command line or by
+  installing a kernel into the image, in which case it will be picked up
+  automatically.
+
+: Note that when the `cpio` output format is used, direct kernel boot is
+  used regardless of the configured firmware. Depending on the
+  configured firmware, qemu might boot the kernel itself or using the
+  configured firmware.
 
 `QemuArgs=`