Restore the ten options f61a90d97 dropped, and gate against an eleventh - #5
Merged
Merged
Conversation
The boot menu renders as unstyled text on black on every legacy-BIOS client: no background picture, no colours, just the bare item list. Reported on the forums for dev-branch with undionly.kpxe. Same cause and same shape as the command trim list this repository already overrides in general.h. Upstream's console.h carries its own "not historically included in BIOS builds" block, and it arrived here with the same wholesale header copy in fogproject f61a90d97 (2026-01-26) that brought the command one. FOG's console.h had a plain "#define CONSOLE_FRAMEBUFFER" and no PLATFORM_pcbios block at all before that commit. Restoring the eight commands in #3 fixed the trim list one file over but left this one, so CONSOLE_CMD came back while the console it drives did not. CONSOLE_FRAMEBUFFER is what pulls in vesafb and fbcon, the only graphical console a BIOS build can have -- EFI gets its own through efifb, which is why no amount of UEFI testing was ever going to catch this. It fails silently rather than falling back. bootmenu.class.php emits console --picture <booturl>/ipxe/bg.png --left 100 --right 80 \ && goto console_set || goto alt_console and alt_console exists to catch exactly this. It never fires: with no console implementing .configure, console_configure() has nothing to hand the pixel buffer to and returns success, so the command reports success having drawn nothing. The picture is fetched over HTTP, PNG-decoded, and dropped. Only CONSOLE_FRAMEBUFFER is restored. FOG has never used the syslog consoles, so leaving those undefined keeps the BIOS binary's growth to what the boot menu actually needs: undionly.kkpxe goes from 91079 to 93499 bytes, +2.7%. Kept as an explicit override after upstream's block, matching general.h, so the next refresh onto a new upstream tag diffs cleanly and this reads as a FOG choice rather than more drift. Verified on a legacy-BIOS PXE client (VirtualBox, vboxvga, FOG 1.6): nm on the linked binary goes from 0 to 18 fbcon and 0 to 17 vesafb symbols, and the client's screen mode goes from 720x400 VGA text to 800x600 VESA graphics with the FOG background rendered.
An audit of all six headers that commit rewrote, comparing effective
macro state per platform against the pre-drift FOG headers rather than
diffing the text, turns up five more losses. HTTPS is the serious one.
DOWNLOAD_PROTO_HTTPS (BIOS) -- no https_uri_opener in the binary, so a
legacy-BIOS client cannot fetch an https:// URL at all. Every
-S/--force-https FOG install writes exactly such a URL into
default.ipxe, so every BIOS client on an HTTPS server dies at the
first chain and reboot-loops on "Chainloading failed". Those installs
are also the only ones that build from this tree instead of taking a
release asset, which is why the breakage rode in under a commit
titled "Fix iPXE compilation error for HTTPS FOG Installs".
DOWNLOAD_PROTO_FTP, DOWNLOAD_PROTO_NFS (both platforms)
NET_PROTO_LLDP (BIOS), PXE_CMD (BIOS)
-- nothing in FOG emits ftp://, nfs://, startpxe or stoppxe, so these
are parity rather than breakage. Restored on the same reasoning as
the six diagnostic commands in the trim-list override: FOG shipped
them for years, no one chose to drop them, and a silently narrowed
feature set is not a decision anybody made.
HTTP_AUTH_NTLM and NET_PROTO_IPV6 stay off. Upstream's undefs agree with
FOG's own header on both, so there is nothing to restore.
After this the effective option set for both platforms matches the
pre-f61a90d97 headers exactly, with no remaining losses on either.
undionly.kkpxe grows from 93499 to 101190 bytes, almost all of it TLS.
Verified by nm on the linked BIOS binary: the registered URI openers go
from {http, mtftp, tcp, tftm, tftp, udp, xfer} to that set plus https,
ftp and nfs.
Ten iPXE options were lost to fogproject f61a90d97 copying upstream's config headers in wholesale. They surfaced one at a time over six releases, each found by a user hitting a symptom rather than by anyone looking: a blank screen, a boot that dies on "params: command not found", a menu with no background, and -- still unreleased until now -- no HTTPS at all on legacy BIOS. Nothing in the repository could tell you the feature set had changed, so nothing did. This makes it a standing property instead. check-linked-objects.sh reads the linker's map files after buildipxe.sh and compares the set of objects pulled into each shipped binary against a committed baseline. CI runs it between the build and the release step, so a tag that would publish drifted binaries fails before it publishes anything. The linked object list rather than the headers, for two reasons. An option can be lost by a #define becoming a comment or by an #undef in a platform block hundreds of lines away, so no textual diff of a header tells you what the binary ends up containing -- which is exactly how these went unnoticed while people read the headers. And GH-958 was the inverse case: the #define was absent, so REQUIRE_OBJECT never fired and no console driver linked at all; an option-state audit would have called that header correct. The map file cannot be fooled by either, and it is produced by the real build rather than by a harness here that would reimplement the build's include paths and then rot. Three baselines, one per build tree, because they genuinely can disagree: BIOS and EFI are separate clones with separate headers, and arm64 is a separate compile whose object set differs by architecture. One target per tree is enough -- every binary in a tree links from the same blib.a against the same headers. A diff is not automatically a bug. Bumping IPXEVER or enabling an option on purpose both move the baseline; the check exists so a human sees the move and commits it deliberately in the same pull request. Verified by reintroducing the framebuffer regression in a build tree and rerunning: the check reports vesafb.o, fbcon.o and utf8.o removed and exits 1. Restored, it passes at 340/341/338 objects.
The first CI run of the check failed against baselines generated on a Fedora box, reporting nearly every object as both removed and added. Nothing had drifted: glibc's default collation ignores punctuation on its first pass, so en_US.UTF-8 and C disagree about whether "ipstat_cmd.o" sorts before or after "ipstat.o", and the sorted baseline is compared with diff. A check that fails because of the developer's locale is worse than no check -- it trains people to ignore it. LC_ALL=C makes byte order the contract everywhere. Baselines regenerated; the object sets are byte-identical when re-sorted, so this commit changes ordering only. Counts stay 340/341/338.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Three commits:
CONSOLE_FRAMEBUFFERon BIOS builds. This is what the forum report is about — the boot menu renders as unstyled text on a black screen on every legacy-BIOS client.DOWNLOAD_PROTO_HTTPSon BIOS is serious breakage.Why the menu was plain text
CONSOLE_FRAMEBUFFERis what pulls invesafbandfbcon, the only graphical console a BIOS build can have — EFI gets its own throughefifb, which is why no amount of UEFI testing was ever going to catch this.It fails silently rather than falling back.
bootmenu.class.phpemitsand
alt_consoleexists to catch exactly this. It never fires: with no console implementing.configure,console_configure()has nothing to hand the pixel buffer to and returns success, so the command reports success having drawn nothing. The picture is fetched over HTTP, PNG-decoded, and dropped.The HTTPS one
Without
DOWNLOAD_PROTO_HTTPSthere is nohttps_uri_openerin the binary at all, so a legacy-BIOS client cannot fetch anhttps://URL by any route.FOG hands it one on every
-S/--force-httpsinstall — the installer writeschain ${httpproto}://$ipaddress${webroot}service/ipxe/boot.php##paramsintodefault.ipxe. So on an HTTPS server every BIOS client chainloadsdefault.ipxeover TFTP, fails to open the firsthttps://URL, and lands inipxescript's "Chainloading failed" reboot loop.Those installs are also the only ones that build from this tree instead of taking a release asset, because
CERT=/TRUST=bake a per-server CA in — which is how it rode in under a commit titled "Fix iPXE compilation error for HTTPS FOG Installs".The full audit
Comparing effective macro state per platform against the pre-
f61a90d97headers, rather than diffing the text, finds every remaining loss at once:CONSOLE_FRAMEBUFFERDOWNLOAD_PROTO_HTTPSDOWNLOAD_PROTO_FTPDOWNLOAD_PROTO_NFSNET_PROTO_LLDPPXE_CMDAfter this, effective option state matches the pre-drift headers exactly on both platforms.
HTTP_AUTH_NTLMandNET_PROTO_IPV6stay off — upstream's#undefagrees with FOG's own header on both.The gate
tools/check-linked-objects.shreads the linker map files afterbuildipxe.shand compares the objects pulled into each shipped binary against a committed baseline. CI runs it between the build and the release step, so a tag that would publish drifted binaries fails before publishing.The linked object list rather than the headers, deliberately: an option can be lost by a
#definebecoming a comment or by an#undefin a platform block hundreds of lines away, so no textual header diff tells you what the binary contains — which is how these survived people reading the headers. GH-958 was the inverse case, where the#definewas absent soREQUIRE_OBJECTnever fired and no console driver linked at all; an option-state audit would have called that header correct.A diff is not automatically a bug. Bumping
IPXEVERor enabling an option on purpose both move the baseline; the check exists so a human sees the move and commits it in the same PR.Verification
buildipxe.shcompletes cleanly across BIOS, i386-efi, x86_64-efi and arm64-efi.nmon the linked BIOS binary:fbcon0 → 18 symbols,vesafb0 → 17. Registered URI openers go from{http, mtftp, tcp, tftm, tftp, udp, xfer}to that set plushttps,ftp,nfs.vesafb.o,fbcon.o,utf8.oremoved and exits 1.undionly.kkpxegrows 91,079 → 101,190 bytes, almost all of it TLS.Not verified: an end-to-end boot against an actual HTTPS FOG install (the HTTPS fix is proven at the binary level), and physical hardware rather than a VM.
🤖 Generated with Claude Code