dfu: add 'SCRIPT' entity

Define a new 'SCRIPT' type for DFU entities. The downloaded data are
treated as simple u-boot's scripts and executed with run_command_list()
function.

Flashing the 'SCRIPT' entity might result in changing the 'dfu_alt_info'
environment variable from the flashed script, so add a global variable
for tracking the potential need to reinitialize the dfu_alt_info related
structures.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
This commit is contained in:
Marek Szyprowski 2020-12-22 11:32:22 +01:00 committed by Marek Vasut
parent b5f3405b9d
commit c533f94c10
4 changed files with 46 additions and 4 deletions

View File

@ -17,7 +17,7 @@ Overview:
- The access to mediums is done in DFU backends (driver/dfu)
Today the supported DFU backends are:
- MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system / SKIP)
- MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system / SKIP / SCRIPT)
- NAND
- RAM
- SF (serial flash)
@ -92,6 +92,7 @@ Commands:
<name> fat <dev> <part_id> [mmcpart <num>] file in FAT partition
<name> ext4 <dev> <part_id> [mmcpart <num>] file in EXT4 partition
<name> skip 0 0 ignore flashed data
<name> script 0 0 execute commands in shell
with <partid> being the GPT or DOS partition index,
with <num> being the eMMC hardware partition number.
@ -116,6 +117,20 @@ Commands:
"u-boot-<board1>.bin raw 0x80 0x800; u-boot-<board2>.bin skip 0 0"
When flashing new system image requires do some more complex things
than just writing data to the storage medium, one can use 'script'
type. Data written to such entity will be executed as a command list
in the u-boot's shell. This for example allows to re-create partition
layout and even set new dfu_alt_info for the newly created paritions.
Such script would look like:
--->8---
setenv dfu_alt_info ...
setenv mbr_parts ...
mbr write ...
--->8---
Please note that this means that user will be able to execute any
arbitrary commands just like in the u-boot's shell.
"nand" (raw slc nand device)
cmd: dfu 0 nand <dev>
each element in "dfu_alt_info" =

View File

@ -26,6 +26,8 @@ static struct hash_algo *dfu_hash_algo;
static unsigned long dfu_timeout = 0;
#endif
bool dfu_reinit_needed = false;
/*
* The purpose of the dfu_flush_callback() function is to
* provide callback for dfu user
@ -139,6 +141,8 @@ int dfu_init_env_entities(char *interface, char *devstr)
char *env_bkp;
int ret = 0;
dfu_reinit_needed = false;
#ifdef CONFIG_SET_DFU_ALT_INFO
set_dfu_alt_info(interface, devstr);
#endif
@ -614,7 +618,8 @@ const char *dfu_get_dev_type(enum dfu_device_type t)
const char *dfu_get_layout(enum dfu_layout l)
{
const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
"EXT3", "EXT4", "RAM_ADDR", "SKIP" };
"EXT3", "EXT4", "RAM_ADDR", "SKIP",
"SCRIPT" };
return dfu_layout[l];
}

View File

@ -16,6 +16,7 @@
#include <fat.h>
#include <mmc.h>
#include <part.h>
#include <command.h>
static unsigned char *dfu_file_buf;
static u64 dfu_file_buf_len;
@ -206,6 +207,9 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
case DFU_FS_EXT4:
ret = mmc_file_buf_write(dfu, offset, buf, len);
break;
case DFU_SCRIPT:
ret = run_command_list(buf, *len, 0);
break;
case DFU_SKIP:
ret = 0;
break;
@ -221,9 +225,21 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
{
int ret = 0;
if (dfu->layout != DFU_RAW_ADDR) {
/* Do stuff here. */
switch (dfu->layout) {
case DFU_FS_FAT:
case DFU_FS_EXT4:
ret = mmc_file_buf_write_finish(dfu);
break;
case DFU_SCRIPT:
/* script may have changed the dfu_alt_info */
dfu_reinit_needed = true;
break;
case DFU_RAW_ADDR:
case DFU_SKIP:
break;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
dfu_get_layout(dfu->layout));
}
return ret;
@ -243,6 +259,7 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 *size)
if (ret < 0)
return ret;
return 0;
case DFU_SCRIPT:
case DFU_SKIP:
return 0;
default:
@ -408,6 +425,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
dfu->layout = DFU_FS_EXT4;
} else if (!strcmp(entity_type, "skip")) {
dfu->layout = DFU_SKIP;
} else if (!strcmp(entity_type, "script")) {
dfu->layout = DFU_SCRIPT;
} else {
pr_err("Memory layout (%s) not supported!\n", entity_type);
return -ENODEV;

View File

@ -34,6 +34,7 @@ enum dfu_layout {
DFU_FS_EXT4,
DFU_RAM_ADDR,
DFU_SKIP,
DFU_SCRIPT,
};
enum dfu_op {
@ -497,6 +498,8 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr,
}
#endif
extern bool dfu_reinit_needed;
#if CONFIG_IS_ENABLED(DFU_WRITE_ALT)
/**
* dfu_write_by_name() - write data to DFU medium