Re: [PATCH] libfdt: overlay: Add export-symbols support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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é




[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux