Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at fix-function-merge 196 lines 7.1 kB view raw
1{ stdenv, nixosTests, lib, edk2, util-linux, nasm, acpica-tools, llvmPackages 2, fetchurl, python3, pexpect, xorriso, qemu, dosfstools, mtools 3, fdSize2MB ? false 4, fdSize4MB ? secureBoot 5, secureBoot ? false 6, systemManagementModeRequired ? secureBoot && stdenv.hostPlatform.isx86 7# Whether to create an nvram variables template 8# which includes the MSFT secure boot keys 9, msVarsTemplate ? false 10# When creating the nvram variables template with 11# the MSFT keys, we also must provide a certificate 12# to use as the PK and first KEK for the keystore. 13# 14# By default, we use Debian's cert. This default 15# should chnage to a NixOS cert once we have our 16# own secure boot signing infrastructure. 17# 18# Ignored if msVarsTemplate is false. 19, vendorPkKek ? "$NIX_BUILD_TOP/debian/PkKek-1-Debian.pem" 20, httpSupport ? false 21, tpmSupport ? false 22, tlsSupport ? false 23, debug ? false 24# Usually, this option is broken, do not use it except if you know what you are 25# doing. 26, sourceDebug ? false 27, projectDscPath ? { 28 i686 = "OvmfPkg/OvmfPkgIa32.dsc"; 29 x86_64 = "OvmfPkg/OvmfPkgX64.dsc"; 30 aarch64 = "ArmVirtPkg/ArmVirtQemu.dsc"; 31 riscv64 = "OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc"; 32 }.${stdenv.hostPlatform.parsed.cpu.name} 33 or (throw "Unsupported OVMF `projectDscPath` on ${stdenv.hostPlatform.parsed.cpu.name}") 34, fwPrefix ? { 35 i686 = "OVMF"; 36 x86_64 = "OVMF"; 37 aarch64 = "AAVMF"; 38 riscv64 = "RISCV_VIRT"; 39 }.${stdenv.hostPlatform.parsed.cpu.name} 40 or (throw "Unsupported OVMF `fwPrefix` on ${stdenv.hostPlatform.parsed.cpu.name}") 41, metaPlatforms ? edk2.meta.platforms 42}: 43 44let 45 46 platformSpecific = { 47 i686.msVarsArgs = { 48 flavor = "OVMF"; 49 archDir = "Ia32"; 50 }; 51 x86_64.msVarsArgs = { 52 flavor = "OVMF_4M"; 53 archDir = "X64"; 54 }; 55 aarch64.msVarsArgs = { 56 flavor = "AAVMF"; 57 archDir = "AARCH64"; 58 }; 59 }; 60 61 cpuName = stdenv.hostPlatform.parsed.cpu.name; 62 63 inherit (platformSpecific.${cpuName}) msVarsArgs; 64 65 version = lib.getVersion edk2; 66 67 OvmfPkKek1AppPrefix = "4e32566d-8e9e-4f52-81d3-5bb9715f9727"; 68 69 debian-edk-src = fetchurl { 70 url = "http://deb.debian.org/debian/pool/main/e/edk2/edk2_2023.11-5.debian.tar.xz"; 71 sha256 = "1yxlab4md30pxvjadr6b4xn6cyfw0c292q63pyfv4vylvhsb24g4"; 72 }; 73 74 buildPrefix = "Build/*/*"; 75 76in 77 78assert platformSpecific ? ${cpuName}; 79assert msVarsTemplate -> fdSize4MB; 80assert msVarsTemplate -> platformSpecific.${cpuName} ? msVarsArgs; 81 82edk2.mkDerivation projectDscPath (finalAttrs: { 83 pname = "OVMF"; 84 inherit version; 85 86 outputs = [ "out" "fd" ]; 87 88 nativeBuildInputs = [ util-linux nasm acpica-tools ] 89 ++ lib.optionals stdenv.cc.isClang [ llvmPackages.bintools llvmPackages.llvm ] 90 ++ lib.optionals msVarsTemplate [ python3 pexpect xorriso qemu dosfstools mtools ]; 91 strictDeps = true; 92 93 hardeningDisable = [ "format" "stackprotector" "pic" "fortify" ]; 94 95 buildFlags = 96 # IPv6 has no reason to be disabled. 97 [ "-D NETWORK_IP6_ENABLE=TRUE" ] 98 ++ lib.optionals debug [ "-D DEBUG_ON_SERIAL_PORT=TRUE" ] 99 ++ lib.optionals sourceDebug [ "-D SOURCE_DEBUG_ENABLE=TRUE" ] 100 ++ lib.optionals secureBoot [ "-D SECURE_BOOT_ENABLE=TRUE" ] 101 ++ lib.optionals systemManagementModeRequired [ "-D SMM_REQUIRE=TRUE" ] 102 ++ lib.optionals fdSize2MB ["-D FD_SIZE_2MB"] 103 ++ lib.optionals fdSize4MB ["-D FD_SIZE_4MB"] 104 ++ lib.optionals httpSupport [ "-D NETWORK_HTTP_ENABLE=TRUE" "-D NETWORK_HTTP_BOOT_ENABLE=TRUE" ] 105 ++ lib.optionals tlsSupport [ "-D NETWORK_TLS_ENABLE=TRUE" ] 106 ++ lib.optionals tpmSupport [ "-D TPM_ENABLE" "-D TPM2_ENABLE" "-D TPM2_CONFIG_ENABLE"]; 107 108 buildConfig = if debug then "DEBUG" else "RELEASE"; 109 env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Qunused-arguments"; 110 111 env.PYTHON_COMMAND = "python3"; 112 113 postUnpack = lib.optionalDrvAttr msVarsTemplate '' 114 unpackFile ${debian-edk-src} 115 ''; 116 117 postConfigure = lib.optionalDrvAttr msVarsTemplate '' 118 tr -d '\n' < ${vendorPkKek} | sed \ 119 -e 's/.*-----BEGIN CERTIFICATE-----/${OvmfPkKek1AppPrefix}:/' \ 120 -e 's/-----END CERTIFICATE-----//' > vendor-cert-string 121 export PYTHONPATH=$NIX_BUILD_TOP/debian/python:$PYTHONPATH 122 ''; 123 124 postBuild = lib.optionalString stdenv.hostPlatform.isAarch '' 125 ( 126 cd ${buildPrefix}/FV 127 cp QEMU_EFI.fd ${fwPrefix}_CODE.fd 128 cp QEMU_VARS.fd ${fwPrefix}_VARS.fd 129 130 # QEMU expects 64MiB CODE and VARS files on ARM/AARCH64 architectures 131 # Truncate the firmware files to the expected size 132 truncate -s 64M ${fwPrefix}_CODE.fd 133 truncate -s 64M ${fwPrefix}_VARS.fd 134 ) 135 '' + lib.optionalString stdenv.hostPlatform.isRiscV '' 136 truncate -s 32M ${buildPrefix}/FV/${fwPrefix}_CODE.fd 137 truncate -s 32M ${buildPrefix}/FV/${fwPrefix}_VARS.fd 138 '' + lib.optionalString msVarsTemplate '' 139 ( 140 cd ${buildPrefix} 141 python3 $NIX_BUILD_TOP/debian/edk2-vars-generator.py \ 142 --flavor ${msVarsArgs.flavor} \ 143 --enrolldefaultkeys ${msVarsArgs.archDir}/EnrollDefaultKeys.efi \ 144 --shell ${msVarsArgs.archDir}/Shell.efi \ 145 --code FV/${fwPrefix}_CODE.fd \ 146 --vars-template FV/${fwPrefix}_VARS.fd \ 147 --certificate `< $NIX_BUILD_TOP/$sourceRoot/vendor-cert-string` \ 148 --out-file FV/${fwPrefix}_VARS.ms.fd 149 ) 150 ''; 151 152 # TODO: Usage of -bios OVMF.fd is discouraged: https://lists.katacontainers.io/pipermail/kata-dev/2021-January/001650.html 153 # We should remove the isx86-specifc block here once we're ready to update nixpkgs to stop using that and update the 154 # release notes accordingly. 155 postInstall = '' 156 mkdir -vp $fd/FV 157 '' + lib.optionalString (builtins.elem fwPrefix [ 158 "OVMF" "AAVMF" "RISCV_VIRT" 159 ]) '' 160 mv -v $out/FV/${fwPrefix}_{CODE,VARS}.fd $fd/FV 161 '' + lib.optionalString stdenv.hostPlatform.isx86 '' 162 mv -v $out/FV/${fwPrefix}.fd $fd/FV 163 '' + lib.optionalString msVarsTemplate '' 164 mv -v $out/FV/${fwPrefix}_VARS.ms.fd $fd/FV 165 ln -sv $fd/FV/${fwPrefix}_CODE{,.ms}.fd 166 '' + lib.optionalString stdenv.hostPlatform.isAarch '' 167 mv -v $out/FV/QEMU_{EFI,VARS}.fd $fd/FV 168 # Add symlinks for Fedora dir layout: https://src.fedoraproject.org/cgit/rpms/edk2.git/tree/edk2.spec 169 mkdir -vp $fd/AAVMF 170 ln -s $fd/FV/AAVMF_CODE.fd $fd/AAVMF/QEMU_EFI-pflash.raw 171 ln -s $fd/FV/AAVMF_VARS.fd $fd/AAVMF/vars-template-pflash.raw 172 ''; 173 174 dontPatchELF = true; 175 176 passthru = 177 let 178 prefix = "${finalAttrs.finalPackage.fd}/FV/${fwPrefix}"; 179 in { 180 firmware = "${prefix}_CODE.fd"; 181 variables = "${prefix}_VARS.fd"; 182 # This will test the EFI firmware for the host platform as part of the NixOS Tests setup. 183 tests.basic-systemd-boot = nixosTests.systemd-boot.basic; 184 tests.secureBoot-systemd-boot = nixosTests.systemd-boot.secureBoot; 185 inherit secureBoot systemManagementModeRequired; 186 }; 187 188 meta = { 189 description = "Sample UEFI firmware for QEMU and KVM"; 190 homepage = "https://github.com/tianocore/tianocore.github.io/wiki/OVMF"; 191 license = lib.licenses.bsd2; 192 platforms = metaPlatforms; 193 maintainers = with lib.maintainers; [ adamcstephens raitobezarius ]; 194 broken = stdenv.isDarwin; 195 }; 196})