U-Boot FIT Phase Selection: Confirm Which Firmware Each Loader Stage Actually Loads
Trace the actual loader caller before relying on a FIT image’s phase property. The property is selection metadata, not a universal rule that every SPL or VPL path applies automatically. A correctly labelled image can remain unused, and an unlabelled image can be selected first.
This article pins U-Boot v2024.10. It compares the generic fit_image_load() phase-selection mechanism with the simple and full SPL paths in that tag. Board overrides and later releases may differ. No U-Boot build, image-loading fixture or hardware boot test was executed.
1. Write a per-caller selection record
For each loading stage, record the binary identity, source entry point, chosen configuration, requested image type, requested phase and whether a specific image node name is supplied. Also record which boot medium delivered the FIT; a correct selector cannot compensate for reading a different container.
The FIT how-to’s SPL section describes phase-qualified calls such as a firmware request for SPL. Treat that as a mechanism to inspect, not proof that every board’s SPL invokes it.
| Selection input | Question to answer from code or evidence |
|---|---|
| Configuration | Explicit name, default, compatibility match or board-specific choice? |
| Image role/type | Which configuration property is searched? |
| Phase request | Specific phase or no phase filter? |
| Explicit image name | Does the caller already identify a node directly? |
| Fallback path | Which next property or boot path is tried after failure? |
Do not infer the selected phase from the stage’s name printed on a serial console. The important evidence is the value passed to the selection API and the path that resolves the image node.

2. Understand the generic phase helper’s boundary
In v2024.10’s FIT implementation, fit_conf_get_prop_node() immediately takes property-list index zero when the requested phase is IH_PHASE_NONE. With a specific phase, it scans the references in order and returns the first image whose phase matches or whose phase property is absent.
An absent phase is therefore eligible for any requested phase in this helper. It is not automatically excluded, nor is a later explicitly matching image preferred over an earlier untagged image. An invalid phase value encountered during the scan produces an error rather than acting as a harmless mismatch.
The higher-level fit_image_load() uses this property-based selection when resolving an image through a configuration. If a specific image name is already supplied, it resolves that node directly instead. Keep those call forms separate in the acceptance matrix.
3. Check the concrete SPL implementation
The tagged SPL source contains distinct simple and full FIT loaders. The simple path resolves indexed configuration references; its primary-image search tries firmware, optionally kernel with the relevant OS-boot support, then the first loadables entry.
The full path calls the generic loader with plain image types rather than a phase-qualified request in the shown implementation, and supplies explicit names while iterating loadables. Thus a phase property alone does not turn those calls into the phase-filtered example from the how-to.
Read the final board path, including overrides and build selection, before applying either description. A vendor integration may invoke another caller or alter these functions. Preserve the exact commit and configuration alongside the selection worksheet.
4. Build a first-match fixture
Use distinct, inert image identities in a recoverable test arrangement. The following matrix isolates the generic property helper with an SPL phase request; it does not prescribe executable payload addresses.
| Ordered references | Expected helper selection | What the case detects |
|---|---|---|
| VPL-tagged A, SPL-tagged B | B | Mismatched valid phase skipped |
| Untagged A, SPL-tagged B | A | Untagged first match wins |
| SPL-tagged B, untagged A | B | Order changes the first eligible image |
| Only VPL-tagged A | No matching image | Missing selected-phase candidate |
| Invalid phase value before B | Error | Invalid metadata is not merely skipped |
| No phase requested, A then B | A at index zero | No phase filtering in this call |
Add a separate case where the caller supplies B’s explicit node name. Verify that the observed path is direct-name resolution, rather than incorrectly crediting the phase filter for choosing B.
These are selection expectations only. Later type, architecture, hash, signature, load-address and decompression checks can still fail. A selection result should never be reported as a successful authenticated boot.
5. Record every loaded image, not just the entry point
Track the primary firmware and each additional loadable separately. For each, record resolved node name, source payload digest, intended destination, actual loaded identity and any reported size. Distinguish an image that is merely present in the FIT from one actually loaded.
A successful next-stage banner does not prove that auxiliary firmware was loaded, that the intended DTB was supplied, or that an older copy was not reused. Use benign identity markers or controlled observations appropriate to the board rather than changing security policy to expose internals.
Review fallback after a missing image. A loader may try another role or boot source. The test must show whether that fallback is intended, rather than treating any eventual boot as a pass for the original phase selection.
Hypothetical untagged compatibility image
A combined FIT contains a legacy untagged firmware image followed by a newer image explicitly marked for SPL. A phase-qualified generic caller still chooses the legacy image first. The new image’s label is correct, but the ordering and wildcard behavior make the integration expectation wrong.
The corrective review identifies the intended caller contract and regenerates the approved package through the normal release process. It then repeats the selection matrix. It does not assume that relabelling a field, without checking generated references and callers, establishes the desired boot path.
6. Close with separate selection and verification evidence
Deliver the per-stage selection worksheet, generated FIT inventory, caller trace and observed load identities. Add independent evidence that each selected image is authenticated under the intended policy; this article’s matrix does not supply that proof.
When upgrading U-Boot or changing simple/full loader configuration, rerun the path review. A source-level API feature is useful only when the deployed stage actually calls it with the expected inputs.