* [PATCH] libfdt: overlay: Add export-symbols support
@ 2025-01-11 19:28 Ayush Singh
2025-01-16 13:40 ` Herve Codina
0 siblings, 1 reply; 3+ messages in thread
From: Ayush Singh @ 2025-01-11 19:28 UTC (permalink / raw)
To: d-gole, lorforlinux, jkridner, robertcnelson, nenad.marinkovic,
Andrew Davis, Geert Uytterhoeven, Robert Nelson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Greg Kroah-Hartman, Saravana Kannan, Herve Codina, David Gibson
Cc: devicetree-compiler, Ayush Singh
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@beagleboard.org/T/#m8259c8754f680b9da7b91f7b7dd89f10da91d8ed
Signed-off-by: Ayush Singh <ayush@beagleboard.org>
---
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@bootlin.com/
[1]: https://lore.kernel.org/r/20250110-export-symbols-v1-1-b6213fcd6c82@beagleboard.org
---
libfdt/fdt_overlay.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 222 insertions(+), 23 deletions(-)
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index e6b9eb6439585364ff4e84eecacea7a61bcc67eb..7cb22308d524244fef1b1700c116a2284cb5d840 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -352,26 +352,58 @@ static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
}
/**
- * overlay_fixup_phandle - Set an overlay phandle to the base one
+ * is_fragment_target - Check if fixup entry is fragment target.
+ * @fixup_str: fixup string
+ * @fixup_len: fixup string length
+ * returns:
+ * 0 on is not fragment target
+ * 1 on is fragment target
+ * Negative error code on failure
+ */
+static int is_fragment_target(const char *fixup_str, uint32_t fixup_len,
+ uint32_t *flen)
+{
+ const char *sep;
+ char *endptr;
+
+ sep = memchr(fixup_str, '@', fixup_len);
+ if (!sep || *sep != '@')
+ return -FDT_ERR_BADOVERLAY;
+
+ strtoul(sep + 1, &endptr, 10);
+ if (endptr <= (sep + 1))
+ return -FDT_ERR_BADOVERLAY;
+
+ *flen = endptr - fixup_str;
+
+ if (*endptr == '/' || strcmp(endptr, ":target:0") != 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * overlay_fixup_target_phandle - Set an overlay phandle to the base one for
+ * fragment targets.
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
* @symbols_off: Node offset of the symbols node in the base device tree
* @property: Property offset in the overlay holding the list of fixups
*
- * overlay_fixup_phandle() resolves all the overlay phandles pointed
- * to in a __fixups__ property, and updates them to match the phandles
+ * overlay_fixup_target_phandle() resolves overlay fragment target phandles
+ * pointed to in a __fixups__ property, and updates them to match the phandles
* in use in the base device tree.
*
* This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
+ * you want all the target phandles in the overlay to point to the actual
* base dt nodes.
*
* returns:
* 0 on success
* Negative error code on failure
*/
-static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
- int property)
+static int overlay_fixup_target_phandle(void *fdt, void *fdto, int symbols_off,
+ int property)
{
const char *value;
const char *label;
@@ -390,23 +422,155 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
return len;
}
+ /* symbol_path should not be NULL for target phandles, but we cannot find out
+ * if the fixup has any fragment targets in advance.
+ */
symbol_path = fdt_getprop(fdt, symbols_off, label, &prop_len);
- if (!symbol_path)
- return prop_len;
-
- symbol_off = fdt_path_offset(fdt, symbol_path);
- if (symbol_off < 0)
- return symbol_off;
-
- phandle = fdt_get_phandle(fdt, symbol_off);
- if (!phandle)
- return -FDT_ERR_NOTFOUND;
+ if (symbol_path) {
+ symbol_off = fdt_path_offset(fdt, symbol_path);
+ if (symbol_off < 0)
+ return symbol_off;
+
+ phandle = fdt_get_phandle(fdt, symbol_off);
+ if (!phandle)
+ return -FDT_ERR_NOTFOUND;
+ }
+ /* Fragment targets have a format of `/fragment@{num}:target:0` while all
+ * other nodes will have a format
+ * `/fragment@{num}/__overlay__{optional_subnode}:{property}:{offset}`
+ */
do {
- const char *path, *name, *fixup_end;
+ const char *path, *fixup_end;
const char *fixup_str = value;
- uint32_t path_len, name_len;
- uint32_t fixup_len;
+ uint32_t path_len, fixup_len;
+ int ret;
+
+ fixup_end = memchr(value, '\0', len);
+ if (!fixup_end)
+ return -FDT_ERR_BADOVERLAY;
+ fixup_len = fixup_end - fixup_str;
+
+ len -= fixup_len + 1;
+ value += fixup_len + 1;
+
+ ret = is_fragment_target(fixup_str, fixup_len, &path_len);
+ if (ret < 0)
+ return ret;
+ else if (ret == 0)
+ continue;
+
+ /* Since found a target property, check that symbol_path is not empty */
+ if (!symbol_path)
+ return -FDT_ERR_NOTFOUND;
+
+ path = fixup_str;
+ if (path_len == (fixup_len - 1))
+ return -FDT_ERR_BADOVERLAY;
+
+ ret = overlay_fixup_one_phandle(fdto, symbols_off, path,
+ path_len, "target",
+ sizeof("target") - 1, 0,
+ phandle);
+ if (ret)
+ return ret;
+ } while (len > 0);
+
+ return 0;
+}
+
+/*
+ * find_export_symbol - retrieves the phandle to a symbol from export-symbols
+ * in a node in the base devicetreee.
+ * @fdt: pointer to base devicetreee blob
+ * @parent: base node offset
+ * @symbol: symbol name
+ *
+ * returns:
+ * the phandle pointed by the target property
+ * 0, if the phandle was not found
+ */
+static fdt32_t find_export_symbol(void *fdt, int parent, const char *symbol)
+{
+ int child;
+ int property;
+ int lenp;
+ const char *value;
+ const char *label;
+
+ fdt_for_each_subnode(child, fdt, parent) {
+ const char *node_name = fdt_get_name(fdt, child, NULL);
+ if (strcmp(node_name, "export-symbols") == 0) {
+ fdt_for_each_property_offset(property, fdt, child) {
+ value = fdt_getprop_by_offset(fdt, property,
+ &label, &lenp);
+
+ if (strcmp(label, symbol) == 0) {
+ return fdt32_ld((const fdt32_t *)value);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_fixup_non_target_phandle - Set an overlay phandle to the base one for
+ * phandles other than fragment targets.
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @property: Property offset in the overlay holding the list of fixups
+ *
+ * overlay_fixup_non_target_phandle() resolves all overlay phandles except
+ * fragment targets pointed to in a __fixups__ property, and updates them to
+ * match the phandles in use in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_non_target_phandle(void *fdt, void *fdto,
+ int symbols_off, int property)
+{
+ const char *value;
+ const char *label;
+ int len;
+ const char *symbol_path;
+ int prop_len;
+ int symbol_off;
+ uint32_t symbol_phandle;
+
+ value = fdt_getprop_by_offset(fdto, property, &label, &len);
+ if (!value) {
+ if (len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+
+ return len;
+ }
+
+ /* The node can still be present in export-symbols */
+ symbol_path = fdt_getprop(fdt, symbols_off, label, &prop_len);
+ if (symbol_path) {
+ symbol_off = fdt_path_offset(fdt, symbol_path);
+ if (symbol_off < 0)
+ return symbol_off;
+
+ symbol_phandle = fdt_get_phandle(fdt, symbol_off);
+ if (!symbol_phandle)
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ do {
+ const char *path, *name, *fixup_end, *target_path;
+ const char *fixup_str = value;
+ uint32_t path_len, name_len, fixup_len, fragment_len,
+ target_phandle;
char *sep, *endptr;
int poffset, ret;
@@ -418,7 +582,14 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
len -= fixup_len + 1;
value += fixup_len + 1;
+ ret = is_fragment_target(fixup_str, fixup_len, &fragment_len);
+ if (ret < 0)
+ return ret;
+ else if (ret == 1)
+ continue;
+
path = fixup_str;
+
sep = memchr(fixup_str, ':', fixup_len);
if (!sep || *sep != ':')
return -FDT_ERR_BADOVERLAY;
@@ -441,9 +612,25 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
if ((*endptr != '\0') || (endptr <= (sep + 1)))
return -FDT_ERR_BADOVERLAY;
- ret = overlay_fixup_one_phandle(fdto, symbols_off,
- path, path_len, name, name_len,
- poffset, phandle);
+ ret = fdt_path_offset_namelen(fdto, path, fragment_len);
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+
+ ret = fdt_overlay_target_offset(fdt, fdto, ret, &target_path);
+ if (ret < 0)
+ return ret;
+
+ target_phandle = find_export_symbol(fdt, ret, label);
+ if (!target_phandle) {
+ if (!symbol_path)
+ return -FDT_ERR_NOTFOUND;
+
+ target_phandle = symbol_phandle;
+ }
+
+ ret = overlay_fixup_one_phandle(fdto, symbols_off, path,
+ path_len, name, name_len,
+ poffset, target_phandle);
if (ret)
return ret;
} while (len > 0);
@@ -485,10 +672,22 @@ static int overlay_fixup_phandles(void *fdt, void *fdto)
if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
return symbols_off;
+ /* Resolve all target phandles */
+ fdt_for_each_property_offset(property, fdto, fixups_off) {
+ int ret;
+
+ ret = overlay_fixup_target_phandle(fdt, fdto, symbols_off,
+ property);
+ if (ret)
+ return ret;
+ }
+
+ /* Resolve all other phandles */
fdt_for_each_property_offset(property, fdto, fixups_off) {
int ret;
- ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
+ ret = overlay_fixup_non_target_phandle(fdt, fdto, symbols_off,
+ property);
if (ret)
return ret;
}
---
base-commit: 18f4f305fdd7e14c8941658a29c7b85c27d41de4
change-id: 20250111-export-symbols-overlay-a49e06c2d7b5
Best regards,
--
Ayush Singh <ayush@beagleboard.org>
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] libfdt: overlay: Add export-symbols support
2025-01-11 19:28 [PATCH] libfdt: overlay: Add export-symbols support Ayush Singh
@ 2025-01-16 13:40 ` Herve Codina
2025-01-19 13:19 ` Ayush Singh
0 siblings, 1 reply; 3+ messages in thread
From: Herve Codina @ 2025-01-16 13:40 UTC (permalink / raw)
To: Ayush Singh
Cc: d-gole, lorforlinux, jkridner, robertcnelson, nenad.marinkovic,
Andrew Davis, Geert Uytterhoeven, Robert Nelson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Greg Kroah-Hartman, Saravana Kannan, David Gibson,
devicetree-compiler, Thomas Petazzoni, Luca Ceresoli
Hi Ayush,
Cc Thomas and Lucas (interested in this topic).
On Sun, 12 Jan 2025 00:58:52 +0530
Ayush Singh <ayush@beagleboard.org> 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@beagleboard.org/T/#m8259c8754f680b9da7b91f7b7dd89f10da91d8ed
>
> Signed-off-by: Ayush Singh <ayush@beagleboard.org>
> ---
> 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@bootlin.com/
> [1]: https://lore.kernel.org/r/20250110-export-symbols-v1-1-b6213fcd6c82@beagleboard.org
> ---
> 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é
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] libfdt: overlay: Add export-symbols support
2025-01-16 13:40 ` Herve Codina
@ 2025-01-19 13:19 ` Ayush Singh
0 siblings, 0 replies; 3+ messages in thread
From: Ayush Singh @ 2025-01-19 13:19 UTC (permalink / raw)
To: Herve Codina
Cc: d-gole, lorforlinux, jkridner, robertcnelson, nenad.marinkovic,
Andrew Davis, Geert Uytterhoeven, Robert Nelson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Greg Kroah-Hartman, Saravana Kannan, David Gibson,
devicetree-compiler, Thomas Petazzoni, Luca Ceresoli
On 16/01/25 19:10, Herve Codina wrote:
> Hi Ayush,
>
> Cc Thomas and Lucas (interested in this topic).
>
>
> On Sun, 12 Jan 2025 00:58:52 +0530
> Ayush Singh <ayush@beagleboard.org> 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@beagleboard.org/T/#m8259c8754f680b9da7b91f7b7dd89f10da91d8ed
>>
>> Signed-off-by: Ayush Singh <ayush@beagleboard.org>
>> ---
>> 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@bootlin.com/
>> [1]: https://lore.kernel.org/r/20250110-export-symbols-v1-1-b6213fcd6c82@beagleboard.org
>> ---
>> 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é
Thanks for the feedback.
I will add the changes in v2 of the patch.
I will also be sending a patch series to devicetree-spec mailing list
[0] to see if any changes would be needed to make it part of the spec
rather than linux specific node.
[0]: https://lore.kernel.org/devicetree-spec/
Ayush Singh
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-01-19 13:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-11 19:28 [PATCH] libfdt: overlay: Add export-symbols support Ayush Singh
2025-01-16 13:40 ` Herve Codina
2025-01-19 13:19 ` Ayush Singh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).