From: Daan De Meyer Date: Fri, 1 Sep 2023 12:33:09 +0000 (+0200) Subject: Generalize QemuBios to QemuFirmware X-Git-Tag: v16~22^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2b69625cdc80d4315478b9bd62a65182391c108;p=thirdparty%2Fmkosi.git Generalize QemuBios to QemuFirmware We also add a third option "none", in which case we'll use direct kernel boot. --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f68d9297d..df7d978e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/mkosi/config.py b/mkosi/config.py index 4694b3be5..a2c3e3733 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -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)} """ diff --git a/mkosi/qemu.py b/mkosi/qemu.py index 6c9fffe68..02f8dcc18 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -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"] diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index 5670c85c9..f645fddb4 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -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=`