Skip to content

Commit 36eeb82

Browse files
tannevaledtannevaledjhheider
authored
new(tianocore.org/edk2): standalone OVMF firmware blobs (#13239)
Co-authored-by: tannevaled <david.delavennat@polytechnique.edu> Co-authored-by: Jacob Heider <jacob@pkgx.dev>
1 parent 9a29d92 commit 36eeb82

1 file changed

Lines changed: 202 additions & 0 deletions

File tree

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# EDK II — TianoCore reference UEFI implementation.
2+
#
3+
# Ships OVMF / ArmVirtPkg firmware blobs for qemu, matching qemu's
4+
# `share/qemu/` bundle layout so existing runners can pick them up
5+
# via env-var overrides (QEMU_EFI_BIOS, etc.) without code changes.
6+
#
7+
# Primary target: X64 (amd64) → edk2-x86_64-code.fd / edk2-i386-vars.fd
8+
# Secondary: AARCH64 (arm64) → edk2-aarch64-code.fd / edk2-arm-vars.fd
9+
#
10+
# RISCV64 and LOONGARCH64 are tracked as follow-ups: ArmVirtPkg/OvmfPkg
11+
# DSCs exist for them, but bottle layout + cross-toolchain wiring need
12+
# additional shake-out.
13+
#
14+
# Tag scheme is `edk2-stableYYYYMM[.N]`; pkgx strips the prefix so
15+
# `versions: github` exposes a YYYYMM[.N] series that orders correctly.
16+
#
17+
# Platform notes:
18+
# * Linux (GCC5) — fully self-contained on pantry deps.
19+
# * Darwin (CLANGPDB) — uses pantry's llvm.org (clang + lld-link) to
20+
# emit PE/COFF directly, sidestepping macOS-only `mtoc`. Slightly
21+
# slower than XCODE5 but reproducible across hosts.
22+
23+
distributable:
24+
url: git+https://github.com/tianocore/edk2
25+
ref: ${{version.tag}}
26+
27+
versions:
28+
github: tianocore/edk2/tags
29+
match: /^edk2-stable\d+(\.\d+)?$/
30+
strip: /^edk2-stable/
31+
32+
build:
33+
dependencies:
34+
git-scm.org: "*"
35+
python.org: ~3.11
36+
nasm.us: "*"
37+
# iasl (ACPI compiler) — EDK II compiles `.asl` ACPI tables to `.aml`
38+
# for several modules (RamDiskDxe's NFIT, etc.). It is not in qemu's
39+
# toolchain, so without this the X64 build dies with
40+
# `iasl: command not found` (exit 127) on every platform.
41+
acpica.org: "*"
42+
linux:
43+
gnu.org/gcc: "*"
44+
# BaseTools' GenFv #includes <uuid/uuid.h> and links -luuid; on
45+
# Linux that comes from util-linux's libuuid (on darwin it's in the
46+
# SDK). Without it the BaseTools build fails:
47+
# `GenFvInternalLib.c: fatal error: uuid/uuid.h: No such file`.
48+
github.com/util-linux/util-linux: "*"
49+
darwin:
50+
# CLANGPDB toolchain emits PE/COFF directly via lld-link, avoiding
51+
# the macOS-only `mtoc` that XCODE5 requires.
52+
llvm.org: 19
53+
env:
54+
darwin:
55+
# EDK II's CLANGPDB toolchain calls clang/lld-link as
56+
# `DEF(CLANG_BIN)<tool>`. Pin CLANG_BIN to our llvm.org bottle's bin
57+
# (trailing slash required) so it uses absolute paths. Without it the
58+
# bare `lld-link` hits brewkit's PATH shim, which execs a
59+
# non-existent /usr/bin/lld-link → `lld-link: No such file`. Using
60+
# the dep prefix (not `which clang`) avoids resolving to that shim.
61+
CLANG_BIN: "{{deps.llvm.org.prefix}}/bin/"
62+
TC: CLANGPDB
63+
linux:
64+
TC: GCC
65+
x86-64:
66+
NATIVE_FW: "{{prefix}}/share/qemu/edk2-x86_64-code.fd"
67+
HOST_ARCH: X64
68+
aarch64:
69+
NATIVE_FW: "{{prefix}}/share/qemu/edk2-aarch64-code.fd"
70+
HOST_ARCH: AARCH64
71+
WORKSPACE: "$SRCROOT"
72+
EDK_TOOLS_PATH: "$SRCROOT/BaseTools"
73+
CONF_PATH: "$SRCROOT/Conf"
74+
script:
75+
# EDK II pulls a pinned OpenSSL via submodule (CryptoPkg) and a
76+
# handful of others (BrotliCustomDecompressLib, MipiSysTLib, …).
77+
# We need them for SecureBoot-capable OVMF builds.
78+
- git submodule update --init --recursive --depth 1
79+
80+
# BaseTools — the C helpers (GenFv, GenFw, …) used by the build.
81+
#
82+
# Built SERIALLY on purpose. The VfrCompile sub-makefile has a
83+
# missing dependency between the `dlg`-generated VfrLexer.cpp and
84+
# its own compile step; under `make -j` the compiler races the
85+
# generator and reads a half-written file, failing with
86+
# `VfrLexer.cpp: error: expected expression`. With many cores
87+
# (CI runners) the race is near-deterministic, which is why every
88+
# platform's build was red. Serial BaseTools is quick (~1-2 min)
89+
# and the EDK II `build` below is still fully parallel via `-n`.
90+
- make -C BaseTools
91+
92+
# edksetup.sh is bash-only and expects to be sourced from $PWD.
93+
94+
- . ./edksetup.sh BaseTools
95+
96+
# ── X64 (amd64) → edk2-x86_64-code.fd / edk2-i386-vars.fd ──
97+
- if test "{{hw.platform}}+{{hw.arch}}" != "linux+aarch64"; then
98+
- build -a X64 -t "$TC" -b RELEASE
99+
-p OvmfPkg/OvmfPkgX64.dsc
100+
-D SECURE_BOOT_ENABLE=TRUE
101+
-D TPM2_ENABLE=TRUE
102+
-D NETWORK_IP6_ENABLE=TRUE
103+
-D NETWORK_HTTP_BOOT_ENABLE=TRUE
104+
-n {{ hw.concurrency }}
105+
106+
- find Build/OvmfX64 -name OVMF_CODE.fd -exec install -Dm0664 {} {{prefix}}/share/qemu/edk2-x86_64-code.fd \;
107+
- find Build/OvmfX64 -name OVMF_VARS.fd -exec install -Dm0664 {} {{prefix}}/share/qemu/edk2-i386-vars.fd \;
108+
# install if found
109+
- find Build/OvmfX64 -name OVMF.fd -exec install -Dm0664 {} {{prefix}}/share/qemu/edk2-x86_64.fd \; || true
110+
111+
- fi # !linux/aarch64
112+
113+
# ── AARCH64 (arm64) → edk2-aarch64-code.fd / edk2-arm-vars.fd ──
114+
# ArmVirtQemu emits QEMU_EFI.fd + QEMU_VARS.fd.
115+
- if test "{{hw.platform}}+{{hw.arch}}" != "linux+x86-64"; then
116+
117+
- build -a AARCH64 -t "$TC" -b RELEASE
118+
-p ArmVirtPkg/ArmVirtQemu.dsc
119+
-D NETWORK_HTTP_BOOT_ENABLE=TRUE
120+
-n {{ hw.concurrency }}
121+
# ArmVirtQemu.dsc names its output dir `ArmVirtQemu-AArch64`
122+
# (mixed case, from the DSC, not the -a flag). Hardcoding
123+
# `AARCH64` worked on darwin's case-insensitive FS but `install`
124+
# couldn't find it on case-sensitive Linux — glob it instead.
125+
- find Build/ArmVirtQemu* -name QEMU_EFI.fd -exec install -Dm0664 {} {{prefix}}/share/qemu/edk2-aarch64-code.fd \;
126+
- find Build/ArmVirtQemu* -name QEMU_VARS.fd -exec install -Dm0664 {} {{prefix}}/share/qemu/edk2-arm-vars.fd \;
127+
128+
- fi # !linux/x86-64
129+
130+
# Thin shim so pkgx has at least one `bin/*` entry to advertise
131+
# and so downstream tooling can discover the blob directory
132+
# without sourcing env vars.
133+
- run: install -Dm755 $PROP {{prefix}}/bin/edk2-firmware-path
134+
prop: |
135+
#!/bin/sh
136+
# Print the absolute path to an EDK II firmware blob.
137+
# Usage: edk2-firmware-path [x86_64-code|i386-vars|aarch64-code|arm-vars|dir]
138+
dir="$(cd "$(dirname "$0")/../share/qemu" && pwd)"
139+
case "${1:-dir}" in
140+
dir) echo "$dir" ;;
141+
x86_64-code|amd64-code) echo "$dir/edk2-x86_64-code.fd" ;;
142+
i386-vars|amd64-vars) echo "$dir/edk2-i386-vars.fd" ;;
143+
aarch64-code|arm64-code) echo "$dir/edk2-aarch64-code.fd" ;;
144+
arm-vars|arm64-vars) echo "$dir/edk2-arm-vars.fd" ;;
145+
*) echo "unknown firmware key: $1" >&2; exit 2 ;;
146+
esac
147+
148+
provides:
149+
- bin/edk2-firmware-path
150+
151+
runtime:
152+
env:
153+
EDK2_FIRMWARE_DIR: "{{prefix}}/share/qemu"
154+
# Backwards-compat names used by some libvirt / qemu wrappers.
155+
OVMF_CODE: "{{prefix}}/share/qemu/edk2-x86_64-code.fd"
156+
OVMF_VARS: "{{prefix}}/share/qemu/edk2-i386-vars.fd"
157+
AAVMF_CODE: "{{prefix}}/share/qemu/edk2-aarch64-code.fd"
158+
AAVMF_VARS: "{{prefix}}/share/qemu/edk2-arm-vars.fd"
159+
160+
test:
161+
dependencies:
162+
qemu.org: "*"
163+
# `timeout` is GNU coreutils — present on Linux runners but NOT on
164+
# macOS, where the test would otherwise die with `timeout: command
165+
# not found`.
166+
gnu.org/coreutils: "*"
167+
script:
168+
# Boot whichever firmware blobs this bottle shipped, each under its
169+
# matching qemu, and confirm UEFI reaches the Boot Manager (BdsDxe)
170+
# with no boot device. Which blobs exist is host-dependent: darwin
171+
# carries both (clang cross-compiles), Linux only its native arch.
172+
# We require at least one to boot.
173+
#
174+
# `-display none -serial stdio` is headless with the firmware console
175+
# on our pipe. Do NOT add `-nographic`: it also grabs stdio for the
176+
# monitor and qemu aborts ("cannot use stdio by multiple character
177+
# devices").
178+
179+
- test "$(edk2-firmware-path dir)" = "{{prefix}}/share/qemu"
180+
181+
# x86_64 firmware (x86_64 hosts + all darwin)
182+
- if test "{{hw.platform}}+{{hw.arch}}" != "linux+aarch64"; then
183+
- ( timeout 90 qemu-system-x86_64 -machine q35,accel=tcg -m 256
184+
-drive if=pflash,format=raw,readonly=on,file="$(edk2-firmware-path x86_64-code)"
185+
-drive if=pflash,format=raw,file="$(edk2-firmware-path i386-vars)"
186+
-display none -no-reboot -serial stdio 2>&1 | tee boot-x64.log ) || true
187+
- grep -E "(TianoCore|EDK II|UEFI Interactive Shell|BdsDxe)" boot-x64.log
188+
- fi
189+
190+
# aarch64 firmware (arm64 hosts + all darwin). ArmVirt pflash images
191+
# must be 64MiB, so pad the copies.
192+
- if test "{{hw.platform}}+{{hw.arch}}" != "linux+x86-64"; then
193+
- cp "$(edk2-firmware-path aarch64-code)" code-a64.fd
194+
- cp "$(edk2-firmware-path arm-vars)" vars-a64.fd
195+
- truncate -s 64m code-a64.fd vars-a64.fd
196+
- ( timeout 90 qemu-system-aarch64
197+
-machine virt -cpu cortex-a57 -m 256
198+
-drive if=pflash,format=raw,readonly=on,file=code-a64.fd
199+
-drive if=pflash,format=raw,file=vars-a64.fd
200+
-display none -no-reboot -serial stdio 2>&1 | tee boot-a64.log ) || true
201+
- grep -E "(TianoCore|EDK II|UEFI Interactive Shell|BdsDxe)" boot-a64.log
202+
- fi

0 commit comments

Comments
 (0)