mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00
boot: Add logic to enable booting from fallback option
The "fallback" extlinux config option allows us to set an alternative default boot option for when it has been detected that the default is failing. Implement the logic required to boot from this option when desired. Signed-off-by: Martyn Welch <martyn.welch@collabora.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
d2faad3ff3
commit
8ba82a91b3
6 changed files with 27 additions and 7 deletions
|
@ -149,7 +149,7 @@ static int extlinux_boot(struct udevice *dev, struct bootflow *bflow)
|
||||||
info.dev = dev;
|
info.dev = dev;
|
||||||
info.bflow = bflow;
|
info.bflow = bflow;
|
||||||
ret = pxe_setup_ctx(&ctx, &cmdtp, extlinux_getfile, &info, true,
|
ret = pxe_setup_ctx(&ctx, &cmdtp, extlinux_getfile, &info, true,
|
||||||
bflow->fname, false);
|
bflow->fname, false, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("ctx", -EINVAL);
|
return log_msg_ret("ctx", -EINVAL);
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ static int extlinux_pxe_boot(struct udevice *dev, struct bootflow *bflow)
|
||||||
info.bflow = bflow;
|
info.bflow = bflow;
|
||||||
info.cmdtp = &cmdtp;
|
info.cmdtp = &cmdtp;
|
||||||
ret = pxe_setup_ctx(ctx, &cmdtp, extlinux_pxe_getfile, &info, false,
|
ret = pxe_setup_ctx(ctx, &cmdtp, extlinux_pxe_getfile, &info, false,
|
||||||
bflow->subdir, false);
|
bflow->subdir, false, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("ctx", -EINVAL);
|
return log_msg_ret("ctx", -EINVAL);
|
||||||
|
|
||||||
|
|
|
@ -1436,6 +1436,16 @@ struct pxe_menu *parse_pxefile(struct pxe_context *ctx, unsigned long menucfg)
|
||||||
|
|
||||||
buf = map_sysmem(menucfg, 0);
|
buf = map_sysmem(menucfg, 0);
|
||||||
r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
|
r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
|
||||||
|
|
||||||
|
if (ctx->use_fallback) {
|
||||||
|
if (cfg->fallback_label) {
|
||||||
|
printf("Setting use of fallback\n");
|
||||||
|
cfg->default_label = cfg->fallback_label;
|
||||||
|
} else {
|
||||||
|
printf("Selected fallback option, but not set\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unmap_sysmem(buf);
|
unmap_sysmem(buf);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
destroy_pxe_menu(cfg);
|
destroy_pxe_menu(cfg);
|
||||||
|
@ -1586,7 +1596,8 @@ void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg)
|
||||||
|
|
||||||
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
|
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
|
||||||
pxe_getfile_func getfile, void *userdata,
|
pxe_getfile_func getfile, void *userdata,
|
||||||
bool allow_abs_path, const char *bootfile, bool use_ipv6)
|
bool allow_abs_path, const char *bootfile, bool use_ipv6,
|
||||||
|
bool use_fallback)
|
||||||
{
|
{
|
||||||
const char *last_slash;
|
const char *last_slash;
|
||||||
size_t path_len = 0;
|
size_t path_len = 0;
|
||||||
|
@ -1597,6 +1608,7 @@ int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
|
||||||
ctx->userdata = userdata;
|
ctx->userdata = userdata;
|
||||||
ctx->allow_abs_path = allow_abs_path;
|
ctx->allow_abs_path = allow_abs_path;
|
||||||
ctx->use_ipv6 = use_ipv6;
|
ctx->use_ipv6 = use_ipv6;
|
||||||
|
ctx->use_fallback = use_fallback;
|
||||||
|
|
||||||
/* figure out the boot directory, if there is one */
|
/* figure out the boot directory, if there is one */
|
||||||
if (bootfile && strlen(bootfile) >= MAX_TFTP_PATH_LEN)
|
if (bootfile && strlen(bootfile) >= MAX_TFTP_PATH_LEN)
|
||||||
|
|
|
@ -138,7 +138,7 @@ int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep, bool use_ipv6)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
|
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
|
||||||
env_get("bootfile"), use_ipv6))
|
env_get("bootfile"), use_ipv6, false))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BOOTP_PXE_DHCP_OPTION) &&
|
if (IS_ENABLED(CONFIG_BOOTP_PXE_DHCP_OPTION) &&
|
||||||
|
@ -288,7 +288,7 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
|
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
|
||||||
env_get("bootfile"), use_ipv6)) {
|
env_get("bootfile"), use_ipv6, false)) {
|
||||||
printf("Out of memory\n");
|
printf("Out of memory\n");
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pxe_setup_ctx(&ctx, cmdtp, sysboot_read_file, &info, true,
|
if (pxe_setup_ctx(&ctx, cmdtp, sysboot_read_file, &info, true,
|
||||||
filename, false)) {
|
filename, false, false)) {
|
||||||
printf("Out of memory\n");
|
printf("Out of memory\n");
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,8 @@ typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path,
|
||||||
* allocated
|
* allocated
|
||||||
* @pxe_file_size: Size of the PXE file
|
* @pxe_file_size: Size of the PXE file
|
||||||
* @use_ipv6: TRUE : use IPv6 addressing, FALSE : use IPv4 addressing
|
* @use_ipv6: TRUE : use IPv6 addressing, FALSE : use IPv4 addressing
|
||||||
|
* @use_fallback: TRUE : use "fallback" option as default, FALSE : use
|
||||||
|
* "default" option as default
|
||||||
*/
|
*/
|
||||||
struct pxe_context {
|
struct pxe_context {
|
||||||
struct cmd_tbl *cmdtp;
|
struct cmd_tbl *cmdtp;
|
||||||
|
@ -116,6 +118,7 @@ struct pxe_context {
|
||||||
char *bootdir;
|
char *bootdir;
|
||||||
ulong pxe_file_size;
|
ulong pxe_file_size;
|
||||||
bool use_ipv6;
|
bool use_ipv6;
|
||||||
|
bool use_fallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,12 +218,17 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len);
|
||||||
* none
|
* none
|
||||||
* @use_ipv6: TRUE : use IPv6 addressing
|
* @use_ipv6: TRUE : use IPv6 addressing
|
||||||
* FALSE : use IPv4 addressing
|
* FALSE : use IPv4 addressing
|
||||||
|
* @use_fallback: TRUE : Use "fallback" option instead of "default" should no
|
||||||
|
* other choice be selected
|
||||||
|
* FALSE : Use "default" option should no other choice be
|
||||||
|
* selected
|
||||||
* Return: 0 if OK, -ENOMEM if out of memory, -E2BIG if bootfile is larger than
|
* Return: 0 if OK, -ENOMEM if out of memory, -E2BIG if bootfile is larger than
|
||||||
* MAX_TFTP_PATH_LEN bytes
|
* MAX_TFTP_PATH_LEN bytes
|
||||||
*/
|
*/
|
||||||
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
|
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
|
||||||
pxe_getfile_func getfile, void *userdata,
|
pxe_getfile_func getfile, void *userdata,
|
||||||
bool allow_abs_path, const char *bootfile, bool use_ipv6);
|
bool allow_abs_path, const char *bootfile, bool use_ipv6,
|
||||||
|
bool use_fallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pxe_destroy_ctx() - Destroy a PXE context
|
* pxe_destroy_ctx() - Destroy a PXE context
|
||||||
|
|
Loading…
Add table
Reference in a new issue