The TFTP path is compiled out with lwIP even though a common download-only helper is now available. It also parses the word tftp as a hexadecimal address, leaving the local boot address at zero after the transfer.
Use tftpb_run() with loadaddr and keep automatic boot disabled during the download. Reject failed and empty transfers, then use the actual image load address for the VxWorks handoff. Reject tftp explicitly when the download command is not configured. Exercise successful, failed and empty downloads in sandbox, stopping before the architecture-specific handoff by leaving bootaddr unset. Signed-off-by: James Hilliard <[email protected]> --- cmd/elf.c | 29 +++++++++++++++-------------- test/dm/tftp.c | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/cmd/elf.c b/cmd/elf.c index 53ec193aaa6..a3cc051991b 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -130,23 +130,23 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) * Check the loadaddr variable. * If we don't know where the image is then we're done. */ - if (argc < 2) - addr = image_load_addr; - else - addr = hextoul(argv[1], NULL); - -#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_LWIP) - /* - * Check to see if we need to tftp the image ourselves - * before starting - */ + addr = image_load_addr; if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) { - if (net_loop(TFTPGET) <= 0) +#if defined(CONFIG_CMD_TFTPBOOT) + /* VxWorks, not bootm(), owns the downloaded image. */ + addr = env_get_hex("loadaddr", image_load_addr); + if (tftpb_run(addr, NULL) || !net_boot_file_size) return 1; + addr = image_load_addr; printf("Automatic boot of VxWorks image at address 0x%08lx ...\n", - addr); - } + addr); +#else + puts("TFTP support is disabled\n"); + return CMD_RET_FAILURE; #endif + } else if (argc == 2) { + addr = hextoul(argv[1], NULL); + } /* * This should equate to @@ -333,6 +333,7 @@ U_BOOT_CMD( U_BOOT_CMD( bootvx, 2, 0, do_bootvx, "Boot vxWorks from an ELF image", - " [address] - load address of vxWorks ELF image." + " [address] - load address of vxWorks ELF image.\n" + "bootvx tftp - download the image using TFTP before booting" ); #endif diff --git a/test/dm/tftp.c b/test/dm/tftp.c index b70aa6f4722..45612e066e5 100644 --- a/test/dm/tftp.c +++ b/test/dm/tftp.c @@ -503,6 +503,31 @@ static int tftp_test_download(struct unit_test_state *uts, ut_assertok(env_set("tftptimeout", NULL)); #endif +#if IS_ENABLED(CONFIG_CMD_ELF_BOOTVX) + /* Stop before the VxWorks handoff by deliberately omitting bootaddr. */ + ut_assertok(env_set("bootaddr", NULL)); + ut_assertok(env_set("loadaddr", "2000000")); + ut_assertok(env_set("bootfile", "update.bin")); + *net_boot_file_name = '\0'; + ut_assertok(env_set("autostart", "yes")); + for (i = 0; i < 3; i++) { + memset(ctx, 0, sizeof(*ctx)); + ctx->fail = i == 1; + ctx->empty = i == 2; + image_load_addr = TFTP_TEST_ADDR + 4096; + net_boot_file_size = 1234; + ut_asserteq(CMD_RET_FAILURE, run_command("bootvx tftp", 0)); + ut_asserteq(1, ctx->requests); + ut_assert(!ctx->autostart); + ut_asserteq_str("yes", env_get("autostart")); + ut_asserteq(i ? 0 : sizeof(tftp_test_data), net_boot_file_size); + if (!i) { + ut_asserteq(TFTP_TEST_ADDR, image_load_addr); + ut_asserteq_mem(tftp_test_data, buffer, sizeof(tftp_test_data)); + } + } +#endif + for (i = 0; i < ARRAY_SIZE(autostart); i++) { timeout = i & 1 ? NULL : "7000"; retries = i & 1 ? NULL : "09"; -- 2.53.0
