Re: [PATCH v2 01/10] libfdt: Introduce fdt_first_node()
From: Frank Li
Date: Thu Jun 04 2026 - 17:02:14 EST
On Thu, Apr 09, 2026 at 01:54:17PM +0200, Herve Codina wrote:
> In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present
> at the offset 0 of the structure block.
>
> This assumption is not correct. Indeed, a FDT_NOP can be present at the
> offset 0 and this is a legit case.
>
> Indeed, the device-tree specification [0] defines the FDT_NOP tag as
> follow:
>
> The FDT_NOP token will be ignored by any program parsing the device
> tree. This token has no extra data; so it is followed immediately by
> the next token, which can be any valid token. A property or node
> definition in the tree can be overwritten with FDT_NOP tokens to
> remove it from the tree without needing to move other sections of
> the tree’s representation in the devicetree blob.
>
> Nothing refers to any location for this tag and it has to be simply
> ignored. Having this tag at offset 0 doesn't make an exception, the tag
> has to be ignored.
>
> Introduce fdt_first_node() in order to get the offset of the first node
> (first FDT_BEGIN_NODE tag) available in a fdt blob taking care of
> FDT_NOP tags.
>
> [0] https://github.com/devicetree-org/devicetree-specification/blob/main/source/chapter5-flattened-format.rst?plain=1#L317
>
> Signed-off-by: Herve Codina <herve.codina@xxxxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> libfdt/fdt.c | 25 +++++++++++++++++++++++++
> libfdt/libfdt_internal.h | 1 +
> 2 files changed, 26 insertions(+)
>
> diff --git a/libfdt/fdt.c b/libfdt/fdt.c
> index 56d4dcb..676c7d7 100644
> --- a/libfdt/fdt.c
> +++ b/libfdt/fdt.c
> @@ -252,6 +252,31 @@ int fdt_check_prop_offset_(const void *fdt, int offset)
> return offset;
> }
>
> +int fdt_first_node(const void *fdt)
> +{
> + int nextoffset = 0;
> + int offset;
> + uint32_t tag;
> +
> + do {
> + offset = nextoffset;
> + tag = fdt_next_tag(fdt, offset, &nextoffset);
> + switch (tag) {
> + case FDT_END_NODE:
> + case FDT_PROP:
> + return -FDT_ERR_BADSTRUCTURE;
> +
> + case FDT_BEGIN_NODE:
> + return offset;
> +
> + default:
> + break;
> + }
> + } while (tag != FDT_END);
> +
> + return (nextoffset < 0) ? nextoffset : -FDT_ERR_NOTFOUND;
> +}
> +
> int fdt_next_node(const void *fdt, int offset, int *depth)
> {
> int nextoffset = 0;
> diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
> index 0e103ca..4c15264 100644
> --- a/libfdt/libfdt_internal.h
> +++ b/libfdt/libfdt_internal.h
> @@ -32,6 +32,7 @@ static inline const char *fdt_find_string_(const char *strtab, int tabsize,
> }
>
> int fdt_node_end_offset_(void *fdt, int nodeoffset);
> +int fdt_first_node(const void *fdt);
>
> static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
> {
> --
> 2.53.0
>