[PATCH] rpi: copy /system/linux, {serial, revision} from firmware FDT

Peter Robinson pbrobinson at gmail.com
Sun Jun 15 14:15:50 CEST 2025


On Wed, 14 May 2025 at 15:47, Fiona Klute <fiona.klute at gmx.de> wrote:
>
> Both the Raspberry Pi downstream kernel [1] and some userspace tools
> [2] use the revision property to identify the board, and the latter
> fails if it is absent. The firmware creates the /system node which is
> not present in Linux DTS (mainline or vendor) for the Raspberry Pi
> boards, so we need to do the same.
>
> [1] https://github.com/raspberrypi/linux/blob/0f292fbb6346b05766152902076895558ac23f9a/arch/arm/mach-bcm/board_bcm2835.c#L23-L33
> [2] https://github.com/jgarff/rpi_ws281x/blob/7fc0bf8b31d715bbecf28e852ede5aaa388180da/rpihw.c#L579
>
> Signed-off-by: Fiona Klute <fiona.klute at gmx.de>
> Cc: Matthias Brugger <mbrugger at suse.com>
> Cc: Peter Robinson <pbrobinson at gmail.com>
> Cc: Tom Rini <trini at konsulko.com>
> ---
> I sent an RFC version of this patch [3] a while ago with the question
> if there's a better way to create the /system node than creating a
> temporary overlay. I didn't receive any response to that question, so
> I guess not.

Apologies, it got lost, replied on that thread.

> [3] https://lists.denx.de/pipermail/u-boot/2025-February/580364.html
>
>  board/raspberrypi/rpi/rpi.c | 70 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>
> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index 1b0b664fa2b..6545306f6da 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -562,6 +562,74 @@ int copy_property(void *dst, void *src, char *path, char *property)
>         return fdt_setprop(dst, dst_offset, property, prop, len);
>  }
>
> +void copy_system_node(void *fdt, void *fw_fdt)
> +{
> +       void *fdt_copy = NULL;
> +       const fdt32_t *prop;
> +       char fdto[1024];
> +       int src_offset;
> +       u32 fdt_size;
> +       int len;
> +
> +       /*
> +        * If the firmware FDT does not have a /system node, there's
> +        * nothing to do.
> +        */
> +       src_offset = fdt_path_offset(fw_fdt, "/system");
> +       if (src_offset < 0)
> +               return;
> +
> +       /* Create a temporary overlay that adds the /system node. */
> +       if (fdt_create(fdto, sizeof(fdto)))
> +               return;
> +       if (fdt_finish_reservemap(fdto))
> +               return;
> +       if (fdt_begin_node(fdto, ""))
> +               return;
> +       if (fdt_begin_node(fdto, "fragment"))
> +               return;
> +       if (fdt_property_string(fdto, "target-path", "/"))
> +               return;
> +       if (fdt_begin_node(fdto, "__overlay__"))
> +               return;
> +       if (fdt_begin_node(fdto, "system"))
> +               return;
> +
> +       prop = fdt_getprop(fw_fdt, src_offset, "linux,serial", &len);
> +       if (prop)
> +               fdt_property(fdto, "linux,serial", prop, len);
> +       prop = fdt_getprop(fw_fdt, src_offset, "linux,revision", &len);
> +       if (prop)
> +               fdt_property(fdto, "linux,revision", prop, len);
> +
> +       if (fdt_end_node(fdto))
> +               return;
> +       if (fdt_end_node(fdto))
> +               return;
> +       if (fdt_end_node(fdto))
> +               return;
> +       if (fdt_end_node(fdto))
> +               return;
> +       if (fdt_finish(fdto))
> +               return;
> +
> +       /*
> +        * A failed overlay apply is destructive to the target, so use
> +        * a temporary copy and replace the FDT if successful.
> +        */
> +       fdt_size = fdt_totalsize(fdt);
> +       fdt_copy = malloc(fdt_size);
> +       if (!fdt_copy)
> +               return;
> +       memcpy(fdt_copy, fdt, fdt_size);
> +       if (fdt_overlay_apply_verbose(fdt_copy, fdto))
> +               goto cleanup;
> +       memcpy(fdt, fdt_copy, fdt_size);
> +
> + cleanup:
> +       free(fdt_copy);
> +}
> +
>  /* Copy tweaks from the firmware dtb to the loaded dtb */
>  void  update_fdt_from_fw(void *fdt, void *fw_fdt)
>  {
> @@ -572,6 +640,8 @@ void  update_fdt_from_fw(void *fdt, void *fw_fdt)
>         /* The firmware provides a more precise model; so copy that */
>         copy_property(fdt, fw_fdt, "/", "model");
>
> +       copy_system_node(fdt, fw_fdt);
> +
>         /* memory reserve as suggested by the firmware */
>         copy_property(fdt, fw_fdt, "/", "memreserve");
>
> --
> 2.49.0
>


More information about the U-Boot mailing list