U-Boot Redundant Environments: Trace CRC and Serial Selection After an Interrupted Save

A board restarts after a configuration save and returns to an older
boot target. The environment still prints sensible values, so the
failure looks like a boot-script bug. Before editing that script,
determine which persistent environment copy U-Boot selected and why. Two
stored copies provide a recovery mechanism only when their locations,
validity checks and selection rules agree with the actual storage
backend.

This article examines upstream U-Boot v2025.01. It proposes a
diagnostic and qualification method, not a report of power-cut testing.
Vendor patches and backend-specific save procedures require separate
inspection.

Separate
the working environment from its stored copies

The environment displayed at the prompt is working state. Changing it
with env set does not itself save it; env save
requests persistence. U-Boot also has compiled defaults for recovery.
These three identities belong in every failure report: values before the
save, bytes stored in each copy, and values imported after restart. The
versioned
environment guide
describes the in-memory and persistent
distinction.

Do not start by saving again. That may replace the evidence needed to
understand the previous interruption. On a recoverable laboratory
device, preserve the console transcript, exact firmware build,
environment configuration and read-only snapshots of the relevant
storage regions. Treat those snapshots as potentially sensitive because
environments can contain network settings or provisioning data.

Use an explicit case identifier rather than a remembered sequence of
button presses. Record whether reset came from a watchdog, a reset line
or removal of power. Those events are different test inputs; none should
be silently substituted for another.

Conceptual environment-selection flow showing read and CRC gates before serial comparison.

Follow the
selector before interpreting the values

In the tagged common
environment implementation
, env_check_redund()
considers read failures and checks each readable copy’s data CRC. One
valid copy wins over an invalid one. When both pass, it compares serial
flags, with explicit handling for the 255-to-0 transition. Equal flags
select the first copy in this implementation. If neither area can supply
a valid environment, env_import_redund() invokes
defaults.

This yields a useful diagnostic distinction. A newer-looking
application variable does not determine selection. First establish that
the containing record passed the loader’s checks. Then inspect the
selector’s metadata. An engineer comparing only
boot_targets or a slot name can miss the reason an older
set of values won.

The illustrated decision tree is a reading aid for this tagged
implementation. It is not a universal algorithm for every environment
driver, historical release or downstream fork. Confirm that the deployed
backend reaches these functions before applying the conclusions.

Prove that two
addresses mean two usable copies

Write a storage map before scheduling fault injection. Include the
selected backend, device identity, hardware partition, both offsets,
environment size and any erase-unit constraints. Identify which other
persistent objects occupy neighboring regions. Have a second reviewer
reconcile the map with the production partitioning and flashing
procedure.

U-Boot’s v2025.01
environment Kconfig
makes location interpretation backend-dependent.
For MMC, an offset can be relative to the end of a partition. Its
hardware-partition setting is distinct from a software partition-table
entry. Therefore, copying a hexadecimal offset from another board is not
a valid configuration method.

Use concrete questions during review. Does the manufacturing image
preserve both regions? Does an operating-system environment utility use
the same device and layout? Can a service operation erase both copies in
one action? If the answers are unknown, redundancy has not yet been
established at the product level.

Do not publish generic erase or raw-write commands as a repair
recipe. The correct operation depends on a verified board map, and an
incorrect target can destroy the bootloader or unrelated data. Perform
destructive cases only on recoverable test hardware with an independent
restoration path.

Build a small failure matrix

Begin with synthetic records in a disposable fixture or a
backend-aware test setup. Give the two payloads conspicuously different,
harmless marker variables so selection is observable without changing
the boot target. Keep the record format and CRC construction tied to the
same source version as the loader.

Cover these conditions:

  1. Both records valid, with different serial values.
  2. First record valid and second corrupt, then the reverse.
  3. One storage read failing, separately from a readable record with a
    bad CRC.
  4. Both records unusable, with an explicit expectation for the compiled
    defaults.
  5. The serial wrap boundary and equal-serial case.

For each case, retain the input bytes, observed diagnostics and
imported marker. A passing result means the selected record matched the
stated expectation. It does not demonstrate successful operating-system
boot, application health or protection against every power-loss timing
window.

Only then add interruption tests around the real save path. Trace the
selected backend’s write sequence and choose interruption points from
that sequence. Repeat the campaign across the supported storage
configuration and firmware revision. An arbitrary delay loop may
repeatedly hit the same harmless interval while missing the transition
the review intended to exercise.

Make fallback a product
decision

A valid environment record can still contain a boot policy that is
unsuitable for the current device. Similarly, compiled defaults can be
syntactically correct while referring to media absent from a shipped
unit. Review those defaults as a recovery configuration with an owner,
expected console behavior and a documented way to regain control.

Avoid defining success as “U-Boot found some environment.” Define it
as “the expected record was selected, its policy remained admissible,
and the recovery path remained usable.” Keep those outcomes separate in
the test report so a storage recovery does not conceal a boot-policy
failure.

Finally, a CRC is an integrity check, not a signature or
authorization policy. Redundant storage and authenticated boot solve
different problems. Document the mechanism’s boundary, retain the
failing input when something goes wrong, and make the selected copy
observable. That turns an intermittent old-setting symptom into a
reproducible decision path.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *