Skip to main content

max / alloy

Drop efi_uga on arm, and check the modules before the squashfs Found by building an arm ISO on astra, which is what the aarch64 work was for. The previous commit asserted the GRUB module list was architecture-independent, on the strength of the plan saying so. It is not: of the 30 modules, arm64-efi carries 29. The exception is efi_uga and its absence is correct rather than a packaging gap. UGA is EFI 1.x's pre-GOP graphics protocol and only ever existed on x86 firmware; arm64 UEFI has always had GOP, and efi_gop is in the list and present on both. So it is dropped on arm, not substituted. The failure it produced is the argument for the other half of this commit. `grub2-mkimage: error: cannot open /usr/lib/grub/arm64-efi/efi_uga.mod` arrived after the rootfs image and the initramfs, several minutes in, and named one module when there could have been several. The list is now built and checked at the top of the file beside the architecture block, so a missing module fails in the first second and names all of them. One list with a conditional addition rather than two lists. A second copy of the 29 shared names drifts the day anything is added to one of them.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-06 20:33 UTC
Signed with PGP, not checked
Commit: 961b4a15f8590fc195ffb85163608f03d1406b9d
Parent: e3c8a75
1 file changed, +42 insertions, -7 deletions
@@ -73,6 +73,36 @@
73 73 # would otherwise run first.
74 74 [ -d "/usr/lib/grub/$GRUB_FORMAT" ] \
75 75 || { echo "no GRUB modules for $GRUB_FORMAT; the builder needs $GRUB_MODULE_PKG" >&2; exit 1; }
76 +
77 + # The modules the EFI binary is built from, checked here for the same reason:
78 + # grub2-mkimage runs at the end and stops at the first module it cannot open,
79 + # so an absent one costs a whole build to discover and names only itself.
80 + #
81 + # The list is *almost* architecture-independent. Measured on astra 2026-08-06 by
82 + # building an arm ISO rather than assumed: of the 30 names, arm64-efi carries
83 + # 29. The exception is `efi_uga`, and its absence is correct. UGA is EFI 1.x's
84 + # pre-GOP graphics protocol and only ever existed on x86 firmware; arm64 UEFI
85 + # has always had GOP, and `efi_gop` is in the list and present on both. So the
86 + # module is dropped on arm rather than substituted for.
87 + #
88 + # One list with a conditional addition, not two lists: a second copy of 29
89 + # shared names drifts the day anything is added to one of them.
90 + MODULES="part_gpt part_msdos fat iso9660 udf normal linux echo all_video test
91 + search search_label search_fs_uuid search_fs_file gfxterm gfxterm_background
92 + configfile loadenv chain efi_gop ls cat halt reboot minicmd
93 + font terminal squash4 loopback probe regexp"
94 + [ "$ARCH" = "x86_64" ] && MODULES="$MODULES efi_uga"
95 +
96 + missing=""
97 + for module in $MODULES; do
98 + [ -f "/usr/lib/grub/$GRUB_FORMAT/$module.mod" ] || missing="$missing $module"
99 + done
100 + [ -z "$missing" ] || {
101 + echo "the $GRUB_FORMAT target is missing:$missing" >&2
102 + echo "either $GRUB_MODULE_PKG is incomplete, or the module does not exist on this architecture and this list needs another exception" >&2
103 + exit 1
104 + }
105 +
76 106 say "architecture $ARCH, $GRUB_FORMAT, $EFI_NAME"
77 107
78 108 # Version-sorted, not `head -1`: `ls` collates 7.1.10 before 7.1.3, so the
@@ -345,17 +375,22 @@
345 375 # is in front of it. Signing is a distribution problem and distribution is
346 376 # not set up (GO task 0d7505b5); when it is, this is where shim goes.
347 377 #
348 - # Every module named below is present in both the x86_64-efi and the
349 - # arm64-efi target, so the list is architecture-independent and only the
350 - # format and the output name change.
378 + # The module list is *almost* architecture-independent. Measured on astra
379 + # 2026-08-06 by building an arm ISO, rather than assumed: of the 30 modules
380 + # below, arm64-efi carries 29. The exception is `efi_uga`, and its absence is
381 + # correct. UGA is EFI 1.x's pre-GOP graphics protocol, which only ever existed
382 + # on x86 firmware; arm64 UEFI has always had GOP, and `efi_gop` is in the list
383 + # and present. So the module is dropped on arm rather than replaced.
384 + #
385 + # The list itself is built at the top of this file, and checked there, so a
386 + # missing module fails before the several minutes of squashfs rather than after.
387 + #
388 + # shellcheck disable=SC2086 # $MODULES is a deliberate word-split list
351 389 grub2-mkimage \
352 390 --format="$GRUB_FORMAT" \
353 391 --prefix="/EFI/BOOT" \
354 392 --output="$WORK/iso/EFI/BOOT/$EFI_NAME" \
355 - part_gpt part_msdos fat iso9660 udf normal linux echo all_video test \
356 - search search_label search_fs_uuid search_fs_file gfxterm gfxterm_background \
357 - configfile loadenv chain efi_gop efi_uga ls cat halt reboot minicmd \
358 - font terminal squash4 loopback probe regexp
393 + $MODULES
359 394
360 395 # The EFI system partition the firmware actually mounts. Sized to contents
361 396 # rather than a round number, because a fixed size is a future failure the