mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 20:04:46 +00:00

As discussed previously [1,2], the source command is not safe to use with verified boot unless there is a key with required = "images" (which has its own problems). This is because if such a key is absent, signatures are verified but not required. It is assumed that configuration nodes will provide the signature. Because the source command does not use configurations to determine the image to source, effectively no verification takes place. To address this, allow specifying configuration nodes. We use the same syntax as the bootm command (helpfully provided for us by fit_parse_conf). By default, we first try the default config and then the default image. To force using a config, # must be present in the command (e.g. `source $loadaddr#my-conf`). For convenience, the config may be omitted, just like the address may be (e.g. `source \#`). This also works for images (`source :` behaves exactly like `source` currently does). [1] https://lore.kernel.org/u-boot/7d711133-d513-5bcb-52f2-a9dbaa9eeded@prevas.dk/ [2] https://lore.kernel.org/u-boot/042dcb34-f85f-351e-1b0e-513f89005fdd@gmail.com/ Signed-off-by: Sean Anderson <sean.anderson@seco.com> Reviewed-by: Simon Glass <sjg@chromium.org>
199 lines
4.4 KiB
C
199 lines
4.4 KiB
C
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
|
/*
|
|
* Copyright (C) 2020, STMicroelectronics - All Rights Reserved
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <dfu.h>
|
|
#include <image.h>
|
|
#include <asm/arch/stm32prog.h>
|
|
#include "stm32prog.h"
|
|
|
|
struct stm32prog_data *stm32prog_data;
|
|
|
|
static void enable_vidconsole(void)
|
|
{
|
|
char *stdname;
|
|
char buf[64];
|
|
|
|
stdname = env_get("stdout");
|
|
if (!stdname || !strstr(stdname, "vidconsole")) {
|
|
if (!stdname)
|
|
snprintf(buf, sizeof(buf), "serial,vidconsole");
|
|
else
|
|
snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
|
|
env_set("stdout", buf);
|
|
}
|
|
|
|
stdname = env_get("stderr");
|
|
if (!stdname || !strstr(stdname, "vidconsole")) {
|
|
if (!stdname)
|
|
snprintf(buf, sizeof(buf), "serial,vidconsole");
|
|
else
|
|
snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
|
|
env_set("stderr", buf);
|
|
}
|
|
}
|
|
|
|
static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char * const argv[])
|
|
{
|
|
ulong addr, size;
|
|
int dev, ret;
|
|
enum stm32prog_link_t link = LINK_UNDEFINED;
|
|
bool reset = false;
|
|
struct image_header_s header;
|
|
struct stm32prog_data *data;
|
|
|
|
if (argc < 3 || argc > 5)
|
|
return CMD_RET_USAGE;
|
|
|
|
if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && !strcmp(argv[1], "usb"))
|
|
link = LINK_USB;
|
|
else if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && !strcmp(argv[1], "serial"))
|
|
link = LINK_SERIAL;
|
|
|
|
if (link == LINK_UNDEFINED) {
|
|
log_err("not supported link=%s\n", argv[1]);
|
|
return CMD_RET_USAGE;
|
|
}
|
|
|
|
dev = (int)dectoul(argv[2], NULL);
|
|
|
|
addr = CONFIG_SYS_LOAD_ADDR;
|
|
size = 0;
|
|
if (argc > 3) {
|
|
addr = hextoul(argv[3], NULL);
|
|
if (!addr)
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
if (argc > 4)
|
|
size = hextoul(argv[4], NULL);
|
|
|
|
/* check STM32IMAGE presence */
|
|
if (size == 0) {
|
|
stm32prog_header_check(addr, &header);
|
|
if (header.type == HEADER_STM32IMAGE) {
|
|
size = header.image_length + header.length;
|
|
}
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_VIDEO))
|
|
enable_vidconsole();
|
|
|
|
data = (struct stm32prog_data *)malloc(sizeof(*data));
|
|
|
|
if (!data) {
|
|
log_err("Alloc failed.");
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
stm32prog_data = data;
|
|
|
|
ret = stm32prog_init(data, addr, size);
|
|
if (ret)
|
|
log_debug("Invalid or missing layout file at 0x%lx.\n", addr);
|
|
|
|
/* prepare DFU for device read/write */
|
|
ret = stm32prog_dfu_init(data);
|
|
if (ret)
|
|
goto cleanup;
|
|
|
|
switch (link) {
|
|
case LINK_SERIAL:
|
|
ret = stm32prog_serial_init(data, dev);
|
|
if (ret)
|
|
goto cleanup;
|
|
reset = stm32prog_serial_loop(data);
|
|
break;
|
|
case LINK_USB:
|
|
reset = stm32prog_usb_loop(data, dev);
|
|
break;
|
|
default:
|
|
goto cleanup;
|
|
}
|
|
|
|
stm32prog_clean(data);
|
|
free(stm32prog_data);
|
|
stm32prog_data = NULL;
|
|
|
|
puts("Download done\n");
|
|
|
|
if (data->uimage) {
|
|
char boot_addr_start[20];
|
|
char dtb_addr[20];
|
|
char initrd_addr[40];
|
|
char *bootm_argv[5] = {
|
|
"bootm", boot_addr_start, "-", dtb_addr, NULL
|
|
};
|
|
const void *uimage = (void *)data->uimage;
|
|
const void *dtb = (void *)data->dtb;
|
|
const void *initrd = (void *)data->initrd;
|
|
|
|
if (!dtb)
|
|
bootm_argv[3] = env_get("fdtcontroladdr");
|
|
else
|
|
snprintf(dtb_addr, sizeof(dtb_addr) - 1,
|
|
"0x%p", dtb);
|
|
|
|
snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
|
|
"0x%p", uimage);
|
|
|
|
if (initrd) {
|
|
snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%p:0x%zx",
|
|
initrd, data->initrd_size);
|
|
bootm_argv[2] = initrd_addr;
|
|
}
|
|
|
|
printf("Booting kernel at %s %s %s...\n\n\n",
|
|
boot_addr_start, bootm_argv[2], bootm_argv[3]);
|
|
/* Try bootm for legacy and FIT format image */
|
|
if (genimg_get_format(uimage) != IMAGE_FORMAT_INVALID)
|
|
do_bootm(cmdtp, 0, 4, bootm_argv);
|
|
else if (CONFIG_IS_ENABLED(CMD_BOOTZ))
|
|
do_bootz(cmdtp, 0, 4, bootm_argv);
|
|
}
|
|
if (data->script)
|
|
image_source_script(data->script, NULL, NULL);
|
|
|
|
if (reset) {
|
|
puts("Reset...\n");
|
|
run_command("reset", 0);
|
|
}
|
|
|
|
return CMD_RET_SUCCESS;
|
|
|
|
cleanup:
|
|
stm32prog_clean(data);
|
|
free(stm32prog_data);
|
|
stm32prog_data = NULL;
|
|
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
|
|
U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
|
|
"start communication with tools STM32Cubeprogrammer",
|
|
"<link> <dev> [<addr>] [<size>]\n"
|
|
" <link> = serial|usb\n"
|
|
" <dev> = device instance\n"
|
|
" <addr> = address of flashlayout\n"
|
|
" <size> = size of flashlayout (optional for image with STM32 header)\n"
|
|
);
|
|
|
|
#ifdef CONFIG_STM32MP15x_STM32IMAGE
|
|
bool stm32prog_get_tee_partitions(void)
|
|
{
|
|
if (stm32prog_data)
|
|
return stm32prog_data->tee_detected;
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
bool stm32prog_get_fsbl_nor(void)
|
|
{
|
|
if (stm32prog_data)
|
|
return stm32prog_data->fsbl_nor_detected;
|
|
|
|
return false;
|
|
}
|