U-Boot: automatic fallback to the known-good kernel (CONFIG_BOOTCOUNT_LIMIT) #36
Labels
No labels
blocked-physical
cleanup
hardware
infra
kernel
P1-critical
P2-high
P3-normal
P4-later
reliability
security
upstream
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
tiagoagueda/a80#36
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
uImage.known-goodanddtb.known-goodexist in/boot, but selecting them requiresa human on the serial console. On a headless board that means the fallback only works
when someone is already standing next to the failure.
Measured
Change
plus
bootlimitand analtbootcmdpointing at the known-good extlinux entry.Userspace clears the counter from a late systemd unit once the boot is judged good:
/etc/fw_env.configalready points at0xC0000, so no new plumbing is needed.Why it is possible now
BOOTCOUNT_ENVneeds somewhere persistent to write. The move fromENV_IS_IN_FATtoraw MMC at
0xC0000in 38-userspace-hardening.md is whatmakes this available — before that,
saveenvcould never work.Cost
One 64 KiB env write per boot at
0xC0000. Against eMMClife_time 0x02 0x02(10-20% used, per 41-production-plan.md) that is negligible.
Open questions
failed systemd units. Reset the counter from a unit ordered after
network-online.target.bootlimitvalue. 3 is the usual choice.Acceptance
known-good by itself and stays reachable.
Done and verified 2026-08-28.
Two gates this issue did not mention, both of which would have made it look broken:
bootcount_envdoes nothing unlessupgrade_availableis non-zero. Bothbootcount_store()andbootcount_load()open with that check and return early.bootcount > bootlimit, strictly greater - sobootlimit=3falls back onthe fourth unconfirmed boot, not the third.
And a dependency worth naming:
BOOTCOUNT_ENVneeds a working environment, and thechecked-in defconfig carried
CONFIG_ENV_IS_NOWHERE=y, which silently disables it. Fixed aspart of this work - it would have failed here in a way that looked like a bootcount bug.
altbootcmddeliberately does not go through the extlinux menu. The menu is another thingthat can be wrong; the fallback should depend on as little as possible.
Verified by breaking it on purpose.
bootcountforced to 5 againstbootlimit=3with themarking unit disabled, then a reboot:
rather than the
ge2df6e79588ftest kernel that was installed. Unattended, no console.The open question here - what counts as a good boot - is answered narrowly, in
tools/boot-mark-good/: a default route plus sshd, and deliberately not "no failedunits". On a headless board "good" means somebody can get in to fix it, and an unrelated
failed unit must not condemn a kernel that is otherwise fine and reachable. It also skips the
write when the counter is already zero, halving what this costs the eMMC.
bootlimit=3is still a guess; nobody has argued for it over 2 or 5. See50-uboot-resilience.md.