[U-Boot, v4, 1/1] misc: fs_loader: Add request_firmware_into_buf_via_script() for flexible firmware loading via U-Boot script

Marek Vasut marek.vasut at mailbox.org
Wed Aug 13 23:41:03 CEST 2025


On 8/4/25 5:07 PM, Lucien.Jheng wrote:

> +/**
> + * request_firmware_into_buf_via_script() -
> + * Load firmware using a U-Boot script and copy to buffer
> + * @buf: Pointer to a pointer where the firmware buffer will be stored.
> + * @max_size: Maximum allowed size for the firmware to be loaded.
> + * @script_name: Name of the U-Boot script to execute for firmware loading.
> + *
> + * Executes a U-Boot script (@script_name) that loads firmware into
> + * memory and sets the environment variables 'fw_addr' (address) and
> + * 'fw_size' (size in bytes)

- Allocates a buffer, copies the firmware
- from the given address, and returns the pointer via @buf.

+ On success, copies the firmware
+ from the given address to user buffer @buf.

> + *
> + * The script must set these environment variables:
> + *   fw_addr - Address where firmware is loaded in memory
> + *   fw_size - Size of the firmware in bytes
> + *
> + * The script should be defined in the U-Boot environment, for example:
> + *   env set script_name 'load mmc 0:1 ${loadaddr} firmware.bin &&
> + *   env set fw_addr ${loadaddr} && env set fw_size ${filesize}
> + * Return: 0 on success, negative value on error.
> + */

This function description can be present only in one copy in the header 
file include/fs_loader.h , drop this redundant copy.

> +int request_firmware_into_buf_via_script(void **buf, size_t max_size,
> +					 const char *script_name)
> +{
> +	ulong addr, size;
> +	int ret;
> +	char cmd[32];
> +
> +	if (!buf || !script_name || !max_size)
> +		return -EINVAL;
> +
> +	/* Create command to run the firmware loading script */
> +	snprintf(cmd, sizeof(cmd), "run %s", script_name);
> +
> +	/* Run the firmware loading script */
> +	ret = run_command_list(cmd, -1, 0);
> +	if (ret) {
> +		log_err("Firmware loading script '%s' not defined or failed.\n",
> +			script_name);
> +		return -EINVAL;
> +	}
> +
> +	/* Find out where the firmware got loaded and how long it is */
> +	addr = env_get_hex("fw_addr", 0);
> +	size = env_get_hex("fw_size", 0);
> +
> +	/* Clear the variables set by the firmware loading script */
> +	env_set("fw_addr", NULL);
> +	env_set("fw_size", NULL);
> +
> +	if (!addr || !size) {
> +		log_err("Firmware address (0x%lx) or size (0x%lx) are invalid.\n",
> +			addr, size);
> +		return -EINVAL;
> +	}

Please also add one more check:

if (size > max_size) {
   log_err("Loaded firmware size 0x%lx exceeded maximum allowed size 
0x%lx.\n", size, max_size);
   return -E2BIG;
}

> +	memcpy(*buf, (void *)addr, min(size, max_size));
> +
> +	return 0;
> +}
With these two nitpicks above fixed, it looks perfect. Thanks !


More information about the U-Boot mailing list