[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