Skip to content

sdcard.img installer: HDMI is blank for the whole ~1 min auto-expand/reformat, inviting a power-cycle that bricks the card #185

Description

@mcfbytes

Scope

This is about the sdcard.img auto-expand/reformat installer's first boot, and nothing else. A general-purpose boot splash for the installed system (normal boots, core loading, etc.) would be nice but is a separate idea and deliberately out of scope here.

What happened

Flashed sdcard.img.xz from v2026.09.16-beta to a brand-new 64 GB SD card, put it in a DE10-Nano, powered on:

  • The reformat/auto-expand install ran for about a minute.
  • HDMI displayed nothing for the entire minute — no picture, no text, no "no signal"-to-signal transition that a user would read as progress. The board looked dead.
  • The board then rebooted itself into the MiSTer menu, and the install was correct.

So the mechanism works. The problem is purely that the one window in which power-cycling destroys the card is also the one window in which the board gives a user with an enclosed case no sign of life at all.

Why this matters

The install is not idempotent-safe against an interruption at an arbitrary point: step order is copy-payload-to-RAM → re-partition → mkfs.exfat → copy back → write bootloader (docs/user/sdcard-flashing.md Step 3). A user who yanks power during the re-partition/format/copy-back window is left with a card that has neither the installer payload nor a valid filesystem — an aborted install at best, an unbootable card at worst, and no obvious recovery other than re-flashing from a PC.

A minute of a black screen on a brand-new device is exactly the prompt that makes a first-time user reach for the power switch. This is not hypothetical — ADR 0020 §6 opens by naming this precise failure mode:

The install below takes tens of seconds on a board that, during those seconds, looks completely dead — no HDMI picture, no menu, and no output at all unless a serial adapter is attached. The failure mode this invites is a user concluding the board has hung and pulling the power, and the window they are most likely to pull it in is the reformat — precisely the window that leaves an unbootable card.

We predicted it, shipped the mitigation we could afford, and the hardware run above shows the mitigation does not reach a user with a closed case.

What already exists (and why it isn't enough)

Thing Where Why it doesn't cover this
Console progress UI — banner, 9 numbered steps, progress bar, %, elapsed clock, spinner board/mister/de10nano/installer-overlay/init (splash section, ~L134–L520) console=ttyS0,115200 only (docs/boot-chain.md §4). Requires a serial adapter the target user does not own.
hps_led0 ≈0.5 Hz heartbeat same file, splash_led_* ADR 0020 §6 records it as a known limitation: HPS_LED is an on-board surface-mount LED. Invisible in a fully-enclosed case.
Unit test for the splash scripts/test-installer-splash.sh Tests the console/LED splash it has, not the channel it lacks.
menu.rbf staged at the FAT root so the fabric is configured during the install scripts/mk-sdcard.sh step 4c; ADR 0020 §7 Gets the ADV7513 a pixel clock; explicitly does not put a picture on screen.
User-facing warning docs/user/sdcard-flashing.md — "The screen stays blank the whole time… do not power off" Correct, and worth keeping, but a doc only helps the user who read it before plugging the card in.

What this run settles

ADR 0020 §7 left one question open and assigned it to TASKS.md P5.4 ([HW] SD image hardware matrix):

Whether the menu core lights the I/O board's Power LED or paints anything of its own before Main_MiSTer attaches is unverified and needs hardware — it is the specific question P5.4 should answer, because it determines whether a custom bitstream (§6's rejected option) has any remaining justification.

Answer, for the HDMI half: the menu core paints nothing. menu.rbf in the fabric is necessary but not sufficient — consistent with §6 blocker 2, /dev/fb0 is a window on DDR that the FPGA frame reader only scans out once Main_MiSTer programs it via fb_cmd0/fb_cmd1 on /dev/MiSTer_cmd (docs/abi-contract.md §4), and Main_MiSTer does not run in the installer initramfs.

Still unanswered from that same sentence, and worth capturing on the next hardware run: does the menu core light the I/O board's Power LED during the install? If it does, that is a free externally-facing "alive" indicator that §6 assumed was unavailable.

Directions worth evaluating

Listed cheapest-first; none is chosen here. ADR 0020 §6 rejected the full mr-fusion stack on cost, and that reasoning still stands — the point of this issue is that the other side of the trade got more expensive now that we have measured a full minute of black screen.

  1. Reconsider §6 blocker 2 without adopting mr-fusion's stack. The fabric now is configured (§7). The gap is that nothing programs the frame reader. If the fb_cmd0/fb_cmd1 sequence /usr/sbin/vmode emits can be replayed by a small static helper writing the FPGA registers directly — no Main_MiSTer, no FIFO — then /dev/fb0 becomes live and the installer can draw into it with the bytes it already has. Needs an ABI read and a hardware test; would add kilobytes, not megabytes, and touches no boot-critical component.
  2. Non-video channel that escapes the case. If the Power LED answer above is "yes", investigate whether the installer can drive an I/O board LED through the loaded menu core. Much weaker than a picture, but far cheaper.
  3. Ship a framebuffer bitstream (mr-fusion's actual approach: its own U-Boot + Terasic DTB + Terasic framebuffer RBF + ADV7513 register dump). ADR 0020 §6 rejected this — megabytes on the card plus a new brick surface, and it conflicts with ADR 0017 §Decision 4/5 keeping the stock uboot.img byte-identical. Re-open only if 1 and 2 both fail.
  4. U-Boot-stage splash via the mainline U-Boot capability artifact (ADR 0024, docs/uboot-mainline-port.md). Same ADR 0017 conflict as 3, and it can only paint before Linux starts — it cannot show progress during the reformat, which is the window that matters.
  5. Do nothing to the image; strengthen the docs and release notes. The honest floor. Cheap, and worth doing regardless of which of the above lands.

Whatever wins, ADR 0020 §6's hard rule is non-negotiable and applies unchanged: the splash must never be able to fail an install. No set -e, every write guarded, every path probed.

Suggested acceptance

  • A first-time user with a fully-enclosed case and no serial adapter can tell, from outside the case, that the board is working and should not be powered off.
  • Whatever is added cannot fail the install (ADR 0020 §6 hard rule), and is covered by scripts/test-installer-splash.sh / scripts/test-sdcard-install.sh.
  • The P5.4 hardware matrix records the install wall-clock per card size and the observed indicator state, in docs/testlogs/.
  • ADR 0020 §6/§7 amended with the hardware answer, whichever way it goes — including "we tried and it still isn't possible," if that is the outcome.

Environment

  • Image: sdcard.img.xz, v2026.09.16-beta (minimal variant, not -full)
  • Board: DE10-Nano
  • Card: new 64 GB SD
  • Install wall-clock: ~1 minute, correct result, self-reboot into the menu as designed

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions