U-Boot Log Filters: Why Adding One Deny Rule Can Silence Everything

A narrowly targeted deny rule can unexpectedly remove unrelated
U-Boot messages. In v2025.01, adding the first explicit filter changes
how the destination decides which records to emit. The default log-level
rule applies only while that destination’s filter list is empty.

This article covers initialized U-Boot logging devices and ordinary
records. Early logging, direct console output and forced-debug records
have separate behavior. The goal is to predict the filter decision, not
to diagnose an unavailable UART.

Empty and
nonempty lists use different policies

The logging
implementation
first checks for a forced-debug record. For an
ordinary record and an empty filter list, it compares the record level
with gd->default_log_level.

With any explicit filter present, that fallback is no longer
evaluated. Instead, the code visits filters in list order. The first
matching filter decides whether the record passes; if none matches, the
record is rejected.

Consider one deny rule matching a noisy category. Matching records
are rejected by the rule. Records from other categories reach the end of
the list and are rejected there. The rule did not broaden its category
match: the destination lost its implicit allowance for everything
else.

The official
logging guide
therefore pairs a deny filter with an explicit allow
filter for the remaining desired levels. The important design choice is
the complete allow/deny policy, not just the noisy category to
suppress.

Empty list uses runtime default; explicit list uses first match with deny head insertion and unmatched rejection, plus forced-debug bypass.

Filter
numbers are identifiers, not evaluation order

When adding filters, the implementation puts deny entries at the
front of the list and allow entries at the back. Filter numbers increase
as entries are created, but the list is not sorted by those numbers.

A later deny can appear before an earlier allow. Inspect the
displayed list order rather than replaying creation history mentally.
For ordinary records, the first match returns immediately; it does not
accumulate votes or apply a later exception after a decision.

This makes a broad deny followed by a narrow allow a poor way to
express an exception: the matching deny is encountered first. Define the
deny’s own criteria narrowly enough that the records intended for the
allow rule can reach it.

Understand what constitutes
a match

A filter’s level condition, optional category set and optional file
list must all pass. Within the category set, matching any listed
category is sufficient. File-list matching uses comma-separated suffixes
of the source filename; it is not a shell-glob operation.

A short suffix can therefore match more source paths than intended.
Use sufficiently specific suffixes when two drivers share a basename,
and check the record’s actual source path in the selected build.

The log
command parser
distinguishes an upper numeric level bound from a
lower numeric level bound. U-Boot’s higher numeric levels are more
verbose, so read the displayed comparison sign instead of interpreting
“minimum level” as “minimum severity.” The command also selects the
destination driver; a filter attached to one destination does not
configure every other logging device.

Keep
build-time and forced-debug boundaries visible

The logging
macros
gate ordinary record generation using the build’s maximum
level. A runtime allow filter cannot recover an ordinary call that was
excluded by that gate.

LOG_DEBUG is another important exception. It can force
record generation, and the runtime filter function accepts forced-debug
records before evaluating the filter list. Destination enablement still
matters. A deny rule is therefore not a universal suppression or
sensitive-data protection mechanism.

For qualification, construct a small record matrix covering matching
and nonmatching categories, levels and filename suffixes. Compare the
empty-list case, deny-only case and complete deny-plus-allow policy on
the intended destination. Include a forced-debug case separately so its
bypass is explicit.

No logging configuration or target execution was performed here. The
source-derived result is precise: the first explicit filter replaces the
empty-list default, and every ordinary record then needs an explicit
matching allowance to be emitted.

Similar Posts

Leave a Reply

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