From: Daan De Meyer Date: Thu, 20 Mar 2025 13:20:50 +0000 (+0100) Subject: Implement linux-noinitrd firmware X-Git-Tag: v26~308 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f7e99583d60470e3aafd56a10d8bc3bad0ed200;p=thirdparty%2Fmkosi.git Implement linux-noinitrd firmware Useful for direct kernel booting without an initrd even if one was built. --- diff --git a/mkosi/config.py b/mkosi/config.py index 8a80e9783..77d25e997 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -321,6 +321,7 @@ class Cacheonly(StrEnum): class Firmware(StrEnum): auto = enum.auto() linux = enum.auto() + linux_noinitrd = enum.auto() uefi = enum.auto() uefi_secure_boot = enum.auto() bios = enum.auto() @@ -328,6 +329,9 @@ class Firmware(StrEnum): def is_uefi(self) -> bool: return self in (Firmware.uefi, Firmware.uefi_secure_boot) + def is_linux(self) -> bool: + return self in (Firmware.linux, Firmware.linux_noinitrd) + class ConsoleMode(StrEnum): interactive = enum.auto() diff --git a/mkosi/qemu.py b/mkosi/qemu.py index 865a758e0..b9605286f 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -812,6 +812,20 @@ def finalize_drive(drive: Drive) -> Iterator[Path]: yield Path(file.name) +@contextlib.contextmanager +def finalize_initrd(config: Config) -> Iterator[Optional[Path]]: + with contextlib.ExitStack() as stack: + if (config.output_dir_or_cwd() / config.output_split_initrd).exists(): + yield config.output_dir_or_cwd() / config.output_split_initrd + elif config.initrds: + initrd = config.output_dir_or_cwd() / f"initrd-{uuid.uuid4().hex}" + join_initrds(config, config.initrds, initrd) + stack.callback(lambda: initrd.unlink()) + yield initrd + else: + yield None + + @contextlib.contextmanager def finalize_state(config: Config, cid: int) -> Iterator[None]: (INVOKING_USER.runtime_dir() / "machine").mkdir(parents=True, exist_ok=True) @@ -1100,8 +1114,9 @@ def run_qemu(args: Args, config: Config) -> None: if ( config.output_format in (OutputFormat.cpio, OutputFormat.uki, OutputFormat.esp) - and config.firmware not in (Firmware.auto, Firmware.linux) + and not config.firmware.is_linux() and not config.firmware.is_uefi() + and config.firmware != Firmware.auto ): die(f"{config.output_format} images cannot be booted with the '{config.firmware}' firmware") @@ -1169,7 +1184,7 @@ def run_qemu(args: Args, config: Config) -> None: firmware = finalize_firmware(config, kernel, kerneltype) if not kernel and ( - firmware == Firmware.linux + firmware.is_linux() or config.output_format in (OutputFormat.cpio, OutputFormat.directory, OutputFormat.uki) ): if firmware.is_uefi(): @@ -1433,14 +1448,14 @@ def run_qemu(args: Args, config: Config) -> None: if config.output_format == OutputFormat.cpio: cmdline += ["-initrd", fname] - elif kernel and kerneltype != KernelType.uki and "-initrd" not in args.cmdline: - if (config.output_dir_or_cwd() / config.output_split_initrd).exists(): - cmdline += ["-initrd", config.output_dir_or_cwd() / config.output_split_initrd] - elif config.initrds: - initrd = config.output_dir_or_cwd() / f"initrd-{uuid.uuid4().hex}" - join_initrds(config, config.initrds, initrd) - stack.callback(lambda: initrd.unlink()) - cmdline += ["-initrd", initrd] + elif ( + kernel + and kerneltype != KernelType.uki + and "-initrd" not in args.cmdline + and firmware != Firmware.linux_noinitrd + and (initrd := stack.enter_context(finalize_initrd(config))) + ): + cmdline += ["-initrd", initrd] if config.output_format in (OutputFormat.disk, OutputFormat.esp): blockdev = [ diff --git a/mkosi/resources/man/mkosi.1.md b/mkosi/resources/man/mkosi.1.md index 80c4a0f22..faa08d2bd 100644 --- a/mkosi/resources/man/mkosi.1.md +++ b/mkosi/resources/man/mkosi.1.md @@ -1736,14 +1736,16 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, `Firmware=`, `--firmware=` : Configures the virtual machine firmware to use. Takes one of `uefi`, - `uefi-secure-boot`, `bios`, `linux`, or `auto`. Defaults to `auto`. - When set to `uefi`, the OVMF firmware without secure boot support - is used. When set to `uefi-secure-boot`, the OVMF firmware with - secure boot support is used. When set to `bios`, the default SeaBIOS - firmware is used. When set to `linux`, direct kernel boot is used. - See the `Linux=` option for more details on which kernel image is - used with direct kernel boot. When set to `auto`, `uefi-secure-boot` - is used if possible and `linux` otherwise. + `uefi-secure-boot`, `bios`, `linux`, `linux-noinitrd` or `auto`. + Defaults to `auto`. When set to `uefi`, the OVMF firmware without + secure boot support is used. When set to `uefi-secure-boot`, the + OVMF firmware with secure boot support is used. When set to `bios`, + the default SeaBIOS firmware is used. When set to `linux`, direct + kernel boot is used. See the `Linux=` option for more details on + which kernel image is used with direct kernel boot. + `linux-noinitrd` is identical to `linux` except that no initrd is + used. When set to `auto`, `uefi-secure-boot` is used if possible and + `linux` otherwise. `FirmwareVariables=`, `--firmware-variables=` : Configures the path to the the virtual machine firmware variables file diff --git a/mkosi/vmspawn.py b/mkosi/vmspawn.py index dd5623256..0d04d12c8 100644 --- a/mkosi/vmspawn.py +++ b/mkosi/vmspawn.py @@ -19,6 +19,7 @@ from mkosi.qemu import ( copy_ephemeral, finalize_credentials, finalize_firmware, + finalize_initrd, finalize_kernel_command_line_extra, finalize_register, ) @@ -42,7 +43,7 @@ def run_vmspawn(args: Args, config: Config) -> None: kernel = config.expand_linux_specifiers() if config.linux else None firmware = finalize_firmware(config, kernel) - if not kernel and firmware == Firmware.linux: + if not kernel and firmware.is_linux(): kernel = config.output_dir_or_cwd() / config.output_split_kernel if not kernel.exists(): die( @@ -92,6 +93,11 @@ def run_vmspawn(args: Args, config: Config) -> None: if kernel: cmdline += ["--linux", kernel] + if firmware != Firmware.linux_noinitrd and ( + initrd := stack.enter_context(finalize_initrd(config)) + ): + cmdline += ["--initrd", initrd] + if config.output_format == OutputFormat.directory: cmdline += ["--directory", fname]