[PATCH v1 3/7] commands: nvmem: Add support for creating dynamic rmem devices
Sascha Hauer
s.hauer at pengutronix.de
Mon Jun 2 02:41:55 PDT 2025
On Fri, May 30, 2025 at 01:41:02PM +0200, Oleksij Rempel wrote:
> The 'nvmem' command is extended to allow the creation of dynamic
> RAM-backed NVMEM devices (rmem). This functionality is useful for
> testing NVMEM operations, for scripts that require temporary, writable
> NVMEM areas, or when a persistent NVMEM device is not available or
> necessary.
>
> This patch introduces the following new options to the 'nvmem' command:
>
> -c : Creates a new rmem NVMEM device of the specified . The size can be
> given with common suffixes (e.g., K, M). The command enforces that the
> size is non-zero and does not exceed a defined maximum (NVMEM_MAX_SIZE,
> defaulting to 1MB). This option requires CONFIG_NVMEM_RMEM to be
> enabled.
>
> -v : When used in conjunction with the -c option, this stores the name
> of the newly created rmem device (e.g., "rmem0") into the environment
> variable specified by . This allows subsequent commands or scripts to
> easily reference the dynamic NVMEM device.
>
> If invoked without any options, the 'nvmem' command retains its original
> behavior of listing all currently available NVMEM devices.
>
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> ---
> commands/nvmem.c | 124 ++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 118 insertions(+), 6 deletions(-)
>
> diff --git a/commands/nvmem.c b/commands/nvmem.c
> index a0e3d092e3cf..5f60e70e62c3 100644
> --- a/commands/nvmem.c
> +++ b/commands/nvmem.c
> @@ -1,24 +1,136 @@
> // SPDX-License-Identifier: GPL-2.0
> // SPDX-FileCopyrightText: © 2021 Ahmad Fatoum, Pengutronix
>
> -#include <common.h>
> #include <command.h>
> +#include <common.h>
> +#include <environment.h>
> +#include <getopt.h>
> #include <linux/nvmem-consumer.h>
> +#include <linux/sizes.h>
>
> -static int do_nvmem(int argc, char *argv[])
> +/* Maximum size for dynamically created NVMEM devices.
> + * This is a reasonable limit for RAM-backed devices, but can be adjusted
> + * based on system capabilities and requirements.
> + */
> +#define NVMEM_MAX_SIZE SZ_1M
> +
> +/* Static counter to ensure unique device IDs for dynamically created rmem
> + * devices
> + */
> +static int dynamic_rmem_idx;
> +
> +/**
> + * nvmem_create_dynamic_rmem - Creates a dynamic RAM-backed NVMEM device.
> + * @create_size: Size of the NVMEM device to create.
> + * @var_name: Optional environment variable name to store the created device's
> + * name.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +static int nvmem_create_dynamic_rmem(unsigned long create_size,
> + const char *var_name)
> +{
> + struct device *dev;
> + void *buffer;
> + int ret = 0;
> +
> + buffer = xzalloc(create_size);
> + if (!buffer)
> + return -ENOMEM;
xzalloc does not fail.
> +
> + dev = add_generic_device("rmem", dynamic_rmem_idx, NULL,
> + (resource_size_t)(uintptr_t)buffer,
> + (resource_size_t)create_size,
> + IORESOURCE_MEM, NULL);
> +
> + if (var_name)
> + ret = setenv(var_name, dev_name(dev));
> +
> + dynamic_rmem_idx++;
> +
> + return ret;
> +}
> +
> +static int nvmem_parse_and_validate_create_size(const char *size_arg,
> + unsigned long *out_size)
> {
> - nvmem_devices_print();
> +
> + if (!IS_ENABLED(CONFIG_NVMEM_RMEM)) {
> + printf("Error: rmem NVMEM driver (CONFIG_NVMEM_RMEM) is not enabled in this build.\n");
> + return -EINVAL;
> + }
> +
> + *out_size = strtoul_suffix(optarg, NULL, 0);
> + if (!*out_size) {
> + printf("Error: Invalid size '%s' for -c option. Must be non-zero.\n",
> + optarg);
> + return COMMAND_ERROR_USAGE;
> + }
> +
> + if (*out_size > NVMEM_MAX_SIZE) {
> + printf("Error: Size '%lu' exceeds maximum allowed size of %d bytes.\n",
> + *out_size, NVMEM_MAX_SIZE);
> + return COMMAND_ERROR_USAGE;
> + }
>
> return 0;
> }
>
> +static int do_nvmem(int argc, char *argv[])
> +{
> + unsigned long create_size = 0;
> + char *optarg_v = NULL;
> + int ret = 0;
> + int opt;
> +
> + while ((opt = getopt(argc, argv, "c:v:h")) != -1) {
> + switch (opt) {
> + case 'c':
> + ret = nvmem_parse_and_validate_create_size(optarg,
> + &create_size);
> + if (ret < 0)
> + return ret;
You return COMMAND_ERROR_USAGE from
nvmem_parse_and_validate_create_size() which is > 0, so the error check
won't trigger in this case.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list