From b0dbbb7782409f9f5560bb40c6b53f75f0caf7d5 Mon Sep 17 00:00:00 2001 From: Luca Burelli Date: Thu, 9 Jan 2025 10:45:13 +0100 Subject: [PATCH] device: add CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH option This new option allows to export devices using identifiers generated from the hash of the devicetree node path, instead of the device's ordinal number. Identifiers generated this way are stable across rebuilds. Add new test cases to test this new option. Signed-off-by: Luca Burelli --- include/zephyr/device.h | 34 ++++++++++++++++++++++++++++---- subsys/llext/Kconfig | 8 ++++++++ tests/subsys/llext/testcase.yaml | 18 +++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 00e7da354f9..a1b3632fae2 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -101,9 +101,35 @@ typedef int16_t device_handle_t; * The ordinal used in this name can be mapped to the path by * examining zephyr/include/generated/zephyr/devicetree_generated.h. */ -#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id)) +#define Z_DEVICE_DT_DEP_ORD(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id)) -#if defined(CONFIG_LLEXT_EXPORT_DEVICES) +/* Same as above, but uses the hash of the node path instead of the ordinal. + * + * The hash used in this name can be mapped to the path by + * examining zephyr/include/generated/zephyr/devicetree_generated.h. + */ +#define Z_DEVICE_DT_HASH(node_id) _CONCAT(dts_, DT_NODE_HASH(node_id)) + +/* By default, device identifiers are obtained using the dependency ordinal. + * When LLEXT_EXPORT_DEV_IDS_BY_HASH is defined, the main Zephyr binary exports + * DT identifiers via EXPORT_SYMBOL_NAMED as hashed versions of their paths. + * When matching extensions are built, that is what they need to look for. + * + * The ordinal or hash used in this name can be mapped to the path by + * examining zephyr/include/generated/zephyr/devicetree_generated.h. + */ +#if defined(LL_EXTENSION_BUILD) && defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH) +#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_HASH(node_id) +#else +#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_DEP_ORD(node_id) +#endif + +#if defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH) +/* Export device identifiers by hash */ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ + DEVICE_NAME_GET(Z_DEVICE_DT_HASH(node_id))) +#elif defined(CONFIG_LLEXT_EXPORT_DEVICES) /* Export device identifiers using the builtin name */ #define Z_DEVICE_EXPORT(node_id) EXPORT_SYMBOL(DEVICE_DT_NAME_GET(node_id)) #endif @@ -175,8 +201,8 @@ typedef int16_t device_handle_t; * * This macro defines a @ref device that is automatically configured by the * kernel during system initialization. The global device object's name as a C - * identifier is derived from the node's dependency ordinal. @ref device.name is - * set to `DEVICE_DT_NAME(node_id)`. + * identifier is derived from the node's dependency ordinal or hash. + * @ref device.name is set to `DEVICE_DT_NAME(node_id)`. * * The device is declared with extern visibility, so a pointer to a global * device object can be obtained with `DEVICE_DT_GET(node_id)` from any source diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index 0e3ce5dd57d..5d98bf31e03 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -86,6 +86,14 @@ config LLEXT_EXPORT_DEVICES When enabled, all Zephyr devices defined in the device tree are made available to llexts via the standard DT_ / DEVICE_* macros. +config LLEXT_EXPORT_DEV_IDS_BY_HASH + bool "Use hash of device path in device name" + depends on LLEXT_EXPORT_DEVICES + help + When enabled, exported device names are generated from a hash of the + node path instead of an ordinal number. Identifiers generated this + way are stable across rebuilds. + config LLEXT_EXPORT_BUILTINS_BY_SLID bool "Export built-in symbols to llexts via SLIDs" help diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index c7fe918444c..507c580fcf0 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -124,3 +124,21 @@ tests: - CONFIG_LLEXT_STORAGE_WRITABLE=y - CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y - CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID=y + + # Test the export device IDs by hash feature on a single architecture in + # both normal and SLID mode. + llext.devices_by_hash: + arch_allow: arm + filter: not CONFIG_MPU and not CONFIG_MMU + extra_conf_files: ['no_mem_protection.conf'] + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH=y + llext.devices_by_hash_slid_linking: + arch_allow: arm + filter: not CONFIG_MPU and not CONFIG_MMU + extra_conf_files: ['no_mem_protection.conf'] + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH=y + - CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID=y