Skip to content

Stop the SPL running a microSD image it never checked - #8

Closed
MrMati wants to merge 1 commit into
mainfrom
sd-boot-chain-clock-and-crc
Closed

Stop the SPL running a microSD image it never checked#8
MrMati wants to merge 1 commit into
mainfrom
sd-boot-chain-clock-and-crc

Conversation

@MrMati

@MrMati MrMati commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Boot chain in NAND works every time; boot chain on the card works once and then loops with the DDR banner reappearing right under Trying to boot from MMC1. That loop is the SoC back in the BootROM, and the two reasons it can happen silently are both here.

The bootloader clocks the card at 50 MHz on an untuned link. rv1106.dtsi asks for max-frequency = <200000000> and U-Boot's rockchip_dw_mmc puts MMC_MODE_HS into host_caps unconditionally (it never calls mmc_of_parse()), while nothing in mainline ever programs the CIU drive and sample phases: the ciu-drive/ciu-sample clocks the node names live in the GRF CRU, which has no U-Boot driver on any Rockchip SoC. Linux gets away with 50 MHz because dw_mmc-rockchip sets the drive phase and tunes the sample phase before it reads a block. The bootloader now stays in SD default speed, at the crystal rate so the CRU divider is 1:

&sdmmc {
	bus-width = <4>;
	disable-wp;
	/* ... why, at length ... */
	max-frequency = <24000000>;
	status = "okay";
};

The read that comes back corrupt is then silent, which is the worse half. Without SPL_LEGACY_IMAGE_CRC_CHECK a legacy uImage is booted on the strength of its magic and size alone, and an xPL build has no exception handlers at all — arch/arm/lib/vectors.S sends every fault to b . — so the SPL jumps into the payload and the board either stops dead or trips something that resets it, and the BootROM reloads the same image and does it again. The defconfig now checks the CRC (a crc32 over ~580 KiB, and SPL: Image data CRC check failed! when it fails) and turns on SPL_SHOW_ERRORS so the next failure names its device and errno.

Around that: flash.sh sd reads the first 8 MiB back off the card after writing, since everything past there is ext4 and reports its own damage while the boot chain reports nothing; check.sh holds the frequency cap and the CRC check in place; the README documents the failure signature and the mmc read/iminfo check to run from a NAND-booted U-Boot.

Costs about a third of a second on a 3 MB kernel load and ~2 KiB of SPL. The kernel devicetree still runs the card at 50 MHz, where the phases are tuned.


View with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is enabled.

Booting the whole chain off the card is the one path where the bootloader has
to read the card itself, and it is the path that loops. rv1106.dtsi asks for
max-frequency = <200000000> and U-Boot's rockchip_dw_mmc hardcodes MMC_MODE_HS,
so the SPL and U-Boot proper clock the card at 50 MHz -- with the CIU drive and
sample phases never programmed, because the ciu-drive/ciu-sample clocks live in
the GRF CRU and no U-Boot driver on any Rockchip SoC touches it. Linux is fine
at 50 MHz because dw_mmc-rockchip sets the drive phase and tunes the sample
phase first. Cap the bootloader at the 24 MHz crystal rate, which is SD default
speed with the CRU divider at 1.

The corrupt read that follows an untuned link is silent, which is the worse
half. Without SPL_LEGACY_IMAGE_CRC_CHECK a legacy uImage is booted on its magic
and size alone, and an xPL build has no exception handlers at all
(arch/arm/lib/vectors.S sends every fault to "b ."), so the SPL jumps into the
payload and the board either stops dead or resets into the BootROM, which
reloads the same image and does it again -- the DDR banner reappearing under
"Trying to boot from MMC1" with nothing else to go on. Check the CRC, and turn
on SPL_SHOW_ERRORS so the next failure names its device and errno.

flash.sh now reads the first 8 MiB back off the card after writing it: past
there it is ext4, which reports its own damage, but the boot chain reports
nothing. check.sh holds both the frequency cap and the CRC check in place.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@MrMati MrMati closed this Aug 1, 2026
@MrMati
MrMati deleted the sd-boot-chain-clock-and-crc branch August 1, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant