Hi Ayush, Cc Thomas and Lucas (interested in this topic). On Sun, 12 Jan 2025 00:58:52 +0530 Ayush Singh <ayush@xxxxxxxxxxxxxxx> wrote: > The export symbols node adds some additional symbols that can be used > in the symbols resolution. The resolver tries to match unresolved > symbols first using the export symbols node and, if a match is not > found, it tries the normal route and searches the __symbols__ node. > > Contrary to symbols available in the global __symbols__ node, symbols > listed in the export symbols node can be considered as local symbols. > Indeed, they can be changed depending on the node the overlay is going > to be applied to and are only visible from the current node properties. > > export-symbols are phandle based as opposed to global __symbols__. This > allows for much simpler use with overlays as opposed to __symbols__ > where paths require resizing of overlays as show in [0]. > > The phandle resolution in overlay is now broken into 2 steps: > - fragment target phandles > - All other phandles > > The reason this is required is because to find the export-symbols node > in the target node, we first need to resolve the target phandles. Here > is an example of overlay that will generate the target __fixup__ after > the property fixup, and thus fail without this 2 step resolution. > > ``` > /dts-v1/; > /plugin/; > > &connectora { > prop = <&gpio_connector>; > }; > > &connectorb { > prop = <&gpio_connector>; > }; > ``` > > Using fdtdump, we get the following: > > ``` > **** fdtdump is a low-level debugging tool, not meant for general use. > **** If you want to decompile a dtb, you probably want > **** dtc -I dtb -O dts <filename> > > /dts-v1/; > // magic: 0xd00dfeed > // totalsize: 0x1b1 (433) > // off_dt_struct: 0x38 > // off_dt_strings: 0x180 > // off_mem_rsvmap: 0x28 > // version: 17 > // last_comp_version: 16 > // boot_cpuid_phys: 0x0 > // size_dt_strings: 0x31 > // size_dt_struct: 0x148 > > / { > fragment@0 { > target = <0xffffffff>; > __overlay__ { > prop = <0xffffffff>; > }; > }; > fragment@1 { > target = <0xffffffff>; > __overlay__ { > prop = <0xffffffff>; > }; > }; > __fixups__ { > connectora = "/fragment@0:target:0"; > gpio_connector = "/fragment@0/__overlay__:prop:0", "/fragment@1/__overlay__:prop:0"; > connectorb = "/fragment@1:target:0"; > }; > }; > ``` > > [0]: https://lore.kernel.org/devicetree-compiler/6b2dba90-3c52-4933-88f3-b47f96dc7710@xxxxxxxxxxxxxxx/T/#m8259c8754f680b9da7b91f7b7dd89f10da91d8ed > > Signed-off-by: Ayush Singh <ayush@xxxxxxxxxxxxxxx> > --- > As discussed in the export-symbols kernel patch series [0] and [1], the > following patch series adds support for export-symbols in fdtoverlay. > > This patch series is mostly a prototype for the functionality. Depending > on the direction, next revision of the patch will add tests. > > [0]: https://lore.kernel.org/all/20241209151830.95723-1-herve.codina@xxxxxxxxxxx/ > [1]: https://lore.kernel.org/r/20250110-export-symbols-v1-1-b6213fcd6c82@xxxxxxxxxxxxxxx > --- > libfdt/fdt_overlay.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 222 insertions(+), 23 deletions(-) Thanks a lot for this patch! I did a little modification related to unitialized variables leading to compilation errors. Here is my modification. --- 8< --- diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c index 7cb2230..12745b5 100644 --- a/libfdt/fdt_overlay.c +++ b/libfdt/fdt_overlay.c @@ -411,7 +411,7 @@ static int overlay_fixup_target_phandle(void *fdt, void *fdto, int symbols_off, const char *symbol_path; int prop_len; int symbol_off; - uint32_t phandle; + uint32_t phandle = 0; value = fdt_getprop_by_offset(fdto, property, &label, &len); @@ -544,7 +544,7 @@ static int overlay_fixup_non_target_phandle(void *fdt, void *fdto, const char *symbol_path; int prop_len; int symbol_off; - uint32_t symbol_phandle; + uint32_t symbol_phandle = 0; value = fdt_getprop_by_offset(fdto, property, &label, &len); if (!value) { --- 8< --- I tested your code and fdtoverlay failed when the __symbols__ node is not in the base devicetree. With the export-symbols node, the resolution can be successful without the need of the global __symbols__ node. The error was just related to a check in overlay_fixup_one_phandle(). All verification are already done in previous operations. And so, I removed the check and the symbols_off parameter (not needed anymore). Here is the exact modification I did: --- 8< --- diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c index 12745b5..a9f0465 100644 --- a/libfdt/fdt_overlay.c +++ b/libfdt/fdt_overlay.c @@ -308,7 +308,6 @@ static int overlay_update_local_references(void *fdto, uint32_t delta) /** * overlay_fixup_one_phandle - Set an overlay phandle to the base one * @fdto: Device tree overlay blob - * @symbols_off: Node offset of the symbols node in the base device tree * @path: Path to a node holding a phandle in the overlay * @path_len: number of path characters to consider * @name: Name of the property holding the phandle reference in the overlay @@ -327,7 +326,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta) * 0 on success * Negative error code on failure */ -static int overlay_fixup_one_phandle(void *fdto, int symbols_off, +static int overlay_fixup_one_phandle(void *fdto, const char *path, uint32_t path_len, const char *name, uint32_t name_len, int poffset, uint32_t phandle) @@ -335,9 +334,6 @@ static int overlay_fixup_one_phandle(void *fdto, int symbols_off, fdt32_t phandle_prop; int fixup_off; - if (symbols_off < 0) - return symbols_off; - fixup_off = fdt_path_offset_namelen(fdto, path, path_len); if (fixup_off == -FDT_ERR_NOTFOUND) return -FDT_ERR_BADOVERLAY; @@ -468,7 +464,7 @@ static int overlay_fixup_target_phandle(void *fdt, void *fdto, int symbols_off, if (path_len == (fixup_len - 1)) return -FDT_ERR_BADOVERLAY; - ret = overlay_fixup_one_phandle(fdto, symbols_off, path, + ret = overlay_fixup_one_phandle(fdto, path, path_len, "target", sizeof("target") - 1, 0, phandle); @@ -628,7 +624,7 @@ static int overlay_fixup_non_target_phandle(void *fdt, void *fdto, target_phandle = symbol_phandle; } - ret = overlay_fixup_one_phandle(fdto, symbols_off, path, + ret = overlay_fixup_one_phandle(fdto, path, path_len, name, name_len, poffset, target_phandle); if (ret) --- 8< --- With this modification applied, fdtoverlay worked without any issue using the following commands: dtc -I dts -O dtb base.dts > base.dtb dtc -I dts -O dtb overlay.dtso > overlay.dtbo fdtoverlay -i base.dtb -o full.dtb overlay.dtbo The resulting full.dtb was correct. The file base.dts used for the test was: --- 8< --- /dts-v1/; /{ somewhere { base_node1: base-node1 { prop = "base,node1"; }; base-node2 { prop = "base,node2"; ref-base-node1 = <&base_node1>; }; base_node3: base-node3 { prop = "base,node3"; }; export-symbols { base_node = <&base_node3>; }; }; }; --- 8< --- And the overlay.dso: --- 8< --- /dts-v1/; /plugin/; / { fragment@0 { target-path = "/somewhere"; __overlay__ { ovl_node1: ovl_node1 { prop = "ovl,node1"; }; ovl_node2 { prop = "ovl,node2"; ref-ovl-node1 = <&ovl_node1>; }; ovl_node3 { prop = "ovl,node3"; ref-base-node = <&base_node>; }; }; }; }; --- 8< --- Hope this will help moving forward on this topic. Best regards, Hervé