ovmf: expose EFI prefixes and refactor qemu-vm with it

This commit is contained in:
Raito Bezarius 2022-08-22 16:15:40 +02:00
parent ce907408b8
commit c91d0713ac
3 changed files with 49 additions and 13 deletions

View file

@ -98,12 +98,6 @@ let
addDeviceNames = addDeviceNames =
imap1 (idx: drive: drive // { device = driveDeviceName idx; }); imap1 (idx: drive: drive // { device = driveDeviceName idx; });
efiPrefix =
if pkgs.stdenv.hostPlatform.isx86 then "${pkgs.OVMF.fd}/FV/OVMF"
else if pkgs.stdenv.isAarch64 then "${pkgs.OVMF.fd}/FV/AAVMF"
else throw "No EFI firmware available for platform";
efiFirmware = "${efiPrefix}_CODE.fd";
efiVarsDefault = "${efiPrefix}_VARS.fd";
# Shell script to start the VM. # Shell script to start the VM.
startVM = startVM =
@ -218,14 +212,14 @@ let
${qemu}/bin/qemu-img create -f qcow2 $diskImage "60M" ${qemu}/bin/qemu-img create -f qcow2 $diskImage "60M"
${if cfg.useEFIBoot then '' ${if cfg.useEFIBoot then ''
efiVars=$out/efi-vars.fd efiVars=$out/efi-vars.fd
cp ${efiVarsDefault} $efiVars cp ${cfg.efi.variables} $efiVars
chmod 0644 $efiVars chmod 0644 $efiVars
'' else ""} '' else ""}
''; '';
buildInputs = [ pkgs.util-linux ]; buildInputs = [ pkgs.util-linux ];
QEMU_OPTS = "-nographic -serial stdio -monitor none" QEMU_OPTS = "-nographic -serial stdio -monitor none"
+ lib.optionalString cfg.useEFIBoot ( + lib.optionalString cfg.useEFIBoot (
" -drive if=pflash,format=raw,unit=0,readonly=on,file=${efiFirmware}" " -drive if=pflash,format=raw,unit=0,readonly=on,file=${cfg.efi.firmware}"
+ " -drive if=pflash,format=raw,unit=1,file=$efiVars"); + " -drive if=pflash,format=raw,unit=1,file=$efiVars");
} }
'' ''
@ -705,8 +699,31 @@ in
manager. manager.
useEFIBoot is ignored if useBootLoader == false. useEFIBoot is ignored if useBootLoader == false.
''; '';
};
virtualisation.efi = {
firmware = mkOption {
type = types.path;
default = pkgs.OVMF.firmware;
defaultText = "pkgs.OVMF.firmware";
description =
lib.mdDoc ''
Firmware binary for EFI implementation, defaults to OVMF.
'';
}; };
variables = mkOption {
type = types.path;
default = pkgs.OVMF.variables;
defaultText = "pkgs.OVMF.variables";
description =
lib.mdDoc ''
Platform-specific flash binary for EFI variables, implementation-dependent to the EFI firmware.
Defaults to OVMF.
'';
};
};
virtualisation.useDefaultFilesystems = virtualisation.useDefaultFilesystems =
mkOption { mkOption {
type = types.bool; type = types.bool;
@ -928,7 +945,7 @@ in
''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"'' ''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"''
]) ])
(mkIf cfg.useEFIBoot [ (mkIf cfg.useEFIBoot [
"-drive if=pflash,format=raw,unit=0,readonly=on,file=${efiFirmware}" "-drive if=pflash,format=raw,unit=0,readonly=on,file=${cfg.efi.firmware}"
"-drive if=pflash,format=raw,unit=1,file=$NIX_EFI_VARS" "-drive if=pflash,format=raw,unit=1,file=$NIX_EFI_VARS"
]) ])
(mkIf (cfg.bios != null) [ (mkIf (cfg.bios != null) [

View file

@ -1,4 +1,4 @@
{ stdenv, lib, edk2, util-linux, nasm, acpica-tools { stdenv, nixosTests, lib, edk2, util-linux, nasm, acpica-tools
, csmSupport ? false, seabios ? null , csmSupport ? false, seabios ? null
, secureBoot ? false , secureBoot ? false
, httpSupport ? false , httpSupport ? false
@ -19,9 +19,15 @@ let
throw "Unsupported architecture"; throw "Unsupported architecture";
version = lib.getVersion edk2; version = lib.getVersion edk2;
suffixes = {
x86_64 = "FV/OVMF";
aarch64 = "FV/AAVMF";
};
in in
edk2.mkDerivation projectDscPath { edk2.mkDerivation projectDscPath (finalAttrs: {
pname = "OVMF"; pname = "OVMF";
inherit version; inherit version;
@ -62,10 +68,23 @@ edk2.mkDerivation projectDscPath {
dontPatchELF = true; dontPatchELF = true;
passthru =
let
cpuName = stdenv.hostPlatform.parsed.cpu.name;
suffix = suffixes."${cpuName}" or (throw "Host cpu name `${cpuName}` is not supported in this OVMF derivation!");
prefix = "${finalAttrs.finalPackage.fd}/${suffix}";
in {
firmware = "${prefix}_CODE.fd";
variables = "${prefix}_VARS.fd";
# This will test the EFI firmware for the host platform as part of the NixOS Tests setup.
tests.basic-systemd-boot = nixosTests.systemd-boot.basic;
};
meta = { meta = {
description = "Sample UEFI firmware for QEMU and KVM"; description = "Sample UEFI firmware for QEMU and KVM";
homepage = "https://github.com/tianocore/tianocore.github.io/wiki/OVMF"; homepage = "https://github.com/tianocore/tianocore.github.io/wiki/OVMF";
license = lib.licenses.bsd2; license = lib.licenses.bsd2;
platforms = ["x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin"]; platforms = ["x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin"];
maintainers = [ lib.maintainers.raitobezarius ];
}; };
} })

View file

@ -89,7 +89,7 @@ edk2 = buildStdenv.mkDerivation {
passthru = { passthru = {
mkDerivation = projectDscPath: attrsOrFun: buildStdenv.mkDerivation (finalAttrs: mkDerivation = projectDscPath: attrsOrFun: buildStdenv.mkDerivation (finalAttrs:
let let
attrs = if lib.isFunction attrsOrFun then (attrsOrFun finalAttrs) else attrsOrFun; attrs = lib.toFunction attrsOrFun finalAttrs;
in in
{ {
inherit (edk2) src; inherit (edk2) src;