Conversation
6216eb4 to
2089028
Compare
|
merge-drain: STALLED. #998 is failing cpu matrix (riscv64 across QEMU CPU models) (Milestone 243: something to say before kernel_main, and a screen on the boards) |
|
Lane: milestone/243-no-serial-port, written by an agent; calef's account is the author GitHub shows. The red
|
script/cpu-matrix sifive-u54 |
0 — and its log mentions screen-boot zero times, so the matrix job runs exactly what it ran before this branch |
cargo xtask screen-boot riscv64, with target/initrd.img absent |
0, 45 rows |
cargo xtask screen-boot aarch64 |
0, 33 rows |
script/lint, script/names |
0, 0 |
On the diagnostic line
Noted in the block and in notes/serial-less-output.md as a shape to copy, since it is what made a red matrix readable without a local re-run:
screen-boot: nothing decodable was ever on the screen (did QEMU get a ramfb and a monitor?)
screen-boot: the tour never reached the SERIAL line either, so this is a boot failure and not a screen one
The second line is a control, not a detail. A screen gate that only reports "the screen was blank" sends the next reader into the framebuffer path, which is where I would have gone and where nothing was wrong. Asserting the same marker on the channel the screen is replacing costs one contains and separates "this milestone's mechanism is broken" from "the machine did not boot". Any gate reading a machine through one channel should do the same.
🤖 Generated with Claude Code
|
merge-drain: STALLED. #998 has conflicts a person must resolve (Milestone 243: something to say before kernel_main, and a screen on the boards) |
0930152 to
4a8289c
Compare
|
Lane: milestone/243-no-serial-port, written by an agent; calef's account is the author GitHub shows. Rebased onto 365's xtask split, and one flake fixed that was not mineTwo things happened after the last comment, and the second is worth reading. 1. Milestone 365 split
|
script/test (three architectures, uefi-boot, uefi-test, both screen-boot legs) |
0 |
script/lint, script/names |
0, 0 |
script/cpu-matrix sifive-u54 |
0, and its log mentions screen-boot zero times |
cargo xtask uefi-boot x5 after the marker change |
0 x5 |
cargo xtask screen-boot riscv64 with target/initrd.img absent |
0 |
No leaked QEMU, clean tree, branch on top of main.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
… for a screen Milestone 243's second outstanding item is that aarch64 and riscv64 have no screen at all: `machine_discovery::framebuffer` and `screen_console` are arch-neutral and nothing on those boards ever calls them, because QEMU's `virt` is entered from `-kernel` with no firmware stage that has lit a display. `ramfb` is what the emulator can present, and its whole contract is that the guest supplies the memory and tells the device where it is over `fw_cfg`. Every field of every structure in that conversation is big-endian on a little-endian-only tree, which is the mistake worth making unrepresentable, so the encoders take native values and hand back bytes and the arithmetic is proved on the host before any MMIO exists to get wrong. Name provisional: QEMU calls the interface `fw_cfg` and this tree spells crate names out. The refusals are in the Cargo.toml. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
… one Milestone 243's second outstanding item. The console-on-a-framebuffer path was written arch-neutrally and wired up on x86_64 alone, because x86_64 is the only one of the three whose boot chain has a stage that has already configured a display. QEMU's `virt` boards are entered from `-kernel` with nothing lit, so `machine_discovery::framebuffer` and `screen_console` sat unused there. `ramfb` inverts the UEFI arrangement: the guest owns the pixels and tells the emulator where they are. So the discovery half becomes a `fw_cfg` conversation and everything above `console::attach_screen` is unchanged, which is what the arch-neutral halves were for. The surprise worth recording is what that inversion breaks. Milestone 400's handover maps the screen's physical range into a userspace driver, which is right for a display adapter's BAR and is a hole for a framebuffer that is the kernel's own `.bss`. `boot_screen_terminal` now refuses a screen inside the kernel image, before the yield rather than after, so a refusal leaves the kernel still painting instead of a cleared screen nobody owns. It is a range test, so milestone 157's U-Boot aperture will pass it without anybody remembering to. `kernel/src/screen.rs` and `console::peek_screen`: names provisional. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
The claim a serial transcript cannot make. Both board boots print the same tour on the UART whether or not a single pixel was written, so the only way to know the screen worked is to photograph it and decode the glyphs, which is exactly what `uefi-boot` already does on x86_64. This is its twin, using `board_console::screen` unchanged. Measured on 2026-09-19: 33 non-blank rows off the aarch64 screen ending in `nife self-test: 5 of 5 passed`, and 63 off the riscv64 one. It is a boot of its own rather than a stage of the suite, and that is forced rather than chosen: `ramfb` adds a QEMU console, `screendump` with no device argument writes console 0, and the suite's machine already has a virtio-gpu there. A boot carrying both would be photographing whichever QEMU ordered first. `screen-boot` and `NIFE_SCREEN`: names provisional. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Milestone 243's first outstanding item, early boot, and what is buyable here is narrower than the item's wording suggests. From `ExitBootServices` to the kernel's own `attach_screen` nothing can speak on a machine with no serial port: the firmware's console is gone, the kernel's is not up, and a fault in between is a triple fault with no IDT to catch it. That window cannot be narrated, because the code in it is thirty-two bit and does not know where the screen is. It can be bounded. The loader clears the screen and writes one sentence as its final act, so a person at a monitor can tell the four outcomes apart: the firmware never started the stick, the loader refused and said why over ConOut, the kernel never reached its first statement (this line is still there), or the kernel armed its console and died after (a cleared screen). Only the third of those was previously indistinguishable from the fourth. Proved rather than reasoned: with a temporary halt in place of the jump, `cargo xtask uefi-boot`'s screendump has ink in exactly the top sixteen pixel rows and they read the two lines of `HANDOFF`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
…ot be Both Outstanding items are closed and the block says how, including the half of the early-boot item that turned out to be unanswerable rather than unanswered: the window between ExitBootServices and the kernel's console runs 32-bit with no IDT, so it can be bounded and cannot be narrated. Saying that plainly is worth more than the line it prints. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
script/lint green. Four things it asked for and each is a real improvement rather than a formality: the loader's banner moved into `uefi_loader::screen` where it is host-tested (three tests, one doctest) instead of being a constant only a boot could exercise; the `fw_cfg` refusal got a named type instead of `()`; the driver reads its control word a byte at a time, so it asks nothing of the caller's alignment; and both fences carry their PAIR comment, with the inventory in notes/memory-ordering.md grown from twelve to fourteen. One of them is the only fence in this tree whose partner is host code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
…alf-built Milestone 441 landed `uefi_loader` boot files for aarch64 and riscv64 while this lane was running, which changes the premise this lane worked from: those boards now have a firmware stage that has already lit a display, so a `ramfb` is not their only possible screen and the 1.9 MB of `.bss` behind it has an exit. Two pieces, and the split is the point. Moving the handoff banner to the boards is small and needs no agreement between stages. Carrying a real GOP aperture to the kernel means synthesising the `simple-framebuffer` node milestone 157 will read from U-Boot, into the device tree the loader already copies, which is a wire format between two boot stages and belongs with 157's own premise check rather than with a lane that found it on the way past. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Milestone 441 moved this code into `arch/x86_64/mod.rs` and turned the screen into a field of `Found` while this lane was rebasing onto it; the banner was re-applied against the old shape and only the UEFI-target build says so, which `script/lint` does not run. Caught by script/test's x86_64 leg. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Two decisions and one lesson, recorded where a reader meets them rather than in a pull request nobody reads twice. The screen legs do not run under `--cpu`, and that is priced on its own merits: the matrix narrows the ISA, and nothing on this path varies with `-cpu`. The failure that exposed it reproduces on `rv64` as well and is fixed, so this is not the "do not route around it by dropping the model" that script/cpu-matrix warns about. The lesson is the dismissal rather than the bug: a `MEASURED BOOT REFUSED` line inside an otherwise green gate was the same defect an hour earlier, and was read as noise because the gate's own assertion passed. And the gate's second diagnostic line is written up as a shape to copy: a check that reads a machine through one channel should assert the same fact through the channel it replaces, and say which one failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
Milestone 365 split `xtask/src/main.rs` into twenty modules while this lane was in the merge queue, so this gate could not be rebased: its file stopped existing in the shape it was written against. Re-landed rather than replayed, which is why it arrives as one commit instead of the three it was. Nothing about it changed except where it lives and what it imports. The gate is `xtask/src/screen.rs`, beside `uefi.rs` whose `uefi_boot` it is the twin of; the dispatch entry is in `main.rs`, the two suite legs are in `suite.rs` behind the `--cpu` guard, and the icount boot's device exclusions are in `icount.rs`. Re-verified after the move rather than assumed: `cargo xtask screen-boot riscv64` reads 61 rows off the screen with no measured-boot refusal, and `aarch64` reads 34. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
…d a race Re-verifying after the rebase turned `uefi-boot`'s tour stage red intermittently: four consecutive runs read 19, 27, 40 and 0 rows. Milestone 400's BUGS predicted this in those words. Tested rather than assumed, because the obvious suspect was this lane's own loader banner: with the banner's paint disabled and nothing else changed, the same gate failed two runs in four, which is worse. Not the cause. The cause is a premise that was already false when it was written. The marker was the self-test verdict, chosen "near the end of the boot on purpose" because a 1280x800 screen is 100 rows and the boot was believed longer, so early lines would have scrolled off. The tour tops out at 98 non-blank rows: nothing scrolls, the banner is on screen the whole time, and what the marker selected for was the last line before the handover's clear, a few hundred milliseconds. The comment describes the flake it was written to avoid. The total claim does not change. The screen proves the pixels, and any decoded row proves all five things that path can get wrong; that the boot reached the self-test is asserted unconditionally on the serial transcript already. Depth is now reported instead of required. Five consecutive runs: 52, 68, 78, 84, 89 rows, all green. This touches milestone 400's gate rather than 243's, and leaves 400's BUGS entry stale in its last clause. Named in 243's block for the integrator, since a lane may not edit another milestone's block. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2
9503d88 to
e54fa9c
Compare
Lane: milestone/243-no-serial-port, written by an agent; calef's account is the author GitHub shows.
Closes milestone 243's two Outstanding items. 243 is now BUILT.
1. Early boot: bounded, and it cannot be more than bounded
The premise was checked before it was answered, and half of it turned out to be unanswerable rather than unanswered. From
ExitBootServicestoconsole::attach_screenthere is no console on a serial-less machine: the firmware's is gone by specification, the kernel's is not up, and everything in between (the loader's trampoline,boot.s's 32-bit half, the page tables, the long-mode jump) runs 32-bit with no IDT, so a fault there is a triple fault and a silent reset. No code in that window knows where the screen is.So it is bounded instead.
uefi_loaderclears the screen and writes two lines as its final act, afterExitBootServicesand before the jump:Five outcomes are now distinguishable where four shared one black rectangle. The third is the one that did not exist: the firmware never started the stick / the loader refused and said why over
ConOut/ the kernel never reached its first statement / the kernel armed its console and died after (black) / the boot tour.Proved rather than reasoned. With a temporary halt in place of the jump,
cargo xtask uefi-boot's screendump had ink in exactly the top sixteen pixel rows of a 1280x800 screen and they read those two lines. The painting itself is host-tested inuefi_loader::screen(three tests plus a doctest).2. aarch64 and riscv64: a screen, through
ramfbx86_64gets a screen because UEFI already lit one. QEMU'svirtboards are entered from-kernelwith nothing configured, so there was nothing to discover.ramfbis what they can present, and it inverts the arrangement: the guest owns the pixels and tells the emulator where they are overfw_cfg.fw_cfgwire format, 8 host tests + 2 doctestscrates/firmware_configuration(name provisional)arch::mmu::initkernel/src/drivers/ramfb.rskernel/src/screen.rs(provisional),console::peek_screen(provisional)crates/screen_console, unchangedcargo xtask screen-boot <arch>(provisional),board_console::screenunchangedMeasured, and both legs run inside
script/test:The surprise worth reading the diff for: the inversion breaks milestone 400's handover, which maps the screen's physical range into a userspace driver. Right for a display adapter's BAR, a hole for a framebuffer that is the kernel's own
.bss.user::boot_screen_terminalnow refuses a screen inside the kernel image, checked before the yield so a refusal leaves the kernel still painting. It is a range test rather than a flag, so milestone 157's U-Boot aperture passes it with nothing to remember.script/shell-check --graphicaland--graphical-serialare green, so the one-painter invariant still holds.Gates, all from this worktree
NIFE_CC=… script/lintscript/names(refusals unchanged)script/test(all three architectures, plus both newscreen-bootlegs)script/shell-check,--graphical,--graphical-serialscript/bench --checkscript/icountscript/fastpath-footprintThis lane took the machine-global
nife-devlink, as every gating lane does. It did not runscript/roadmap --write; only its own block was edited.Identified work, with a home
design/roadmap/proposals/the-boards-screen-under-uefi.md(new). Milestone 441 landeduefi_loaderboot files for aarch64 and riscv64 while this lane was running, so those boards now have a firmware stage that has lit a display. The banner could move there, and the loader could hand the kernel a real GOP aperture by synthesising thesimple-framebuffernode milestone 157 will read from U-Boot, retiring theramfb's 1.9 MB of.bss. The second half is a wire format between two boot stages and wants a decision rather than a lane.BUGSwhere a reader meets them: the.bsscost, the missing cache maintenance (QEMU-only by construction), the handover refusal, and the fact that the loader's banner is unobservable in a healthy boot.🤖 Generated with Claude Code
https://claude.ai/code/session_01STu3VeDYnEHem3iKCbzBF2