[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