boot: Split pxe label_boot() into two parts
This function is far too long. Split out the part which builds and runs the bootm/i/z commands into its own function. Add a function comment for the new label_run_boot() function. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
This commit is contained in:
284
boot/pxe_utils.c
284
boot/pxe_utils.c
@@ -433,142 +433,29 @@ skip_overlay:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* label_boot() - Boot according to the contents of a pxe_label
|
* label_run_boot() - Set up the FDT and call the appropriate bootm/z/i command
|
||||||
*
|
|
||||||
* If we can't boot for any reason, we return. A successful boot never
|
|
||||||
* returns.
|
|
||||||
*
|
|
||||||
* The kernel will be stored in the location given by the 'kernel_addr_r'
|
|
||||||
* environment variable.
|
|
||||||
*
|
|
||||||
* If the label specifies an initrd file, it will be stored in the location
|
|
||||||
* given by the 'ramdisk_addr_r' environment variable.
|
|
||||||
*
|
|
||||||
* If the label specifies an 'append' line, its contents will overwrite that
|
|
||||||
* of the 'bootargs' environment variable.
|
|
||||||
*
|
*
|
||||||
* @ctx: PXE context
|
* @ctx: PXE context
|
||||||
* @label: Label to process
|
* @label: Label to process
|
||||||
* Returns does not return on success, otherwise returns 0 if a localboot
|
* @kernel_addr: String containing kernel address (cannot be NULL)
|
||||||
* label was processed, or 1 on error
|
* @initrd_addr_str: String containing initrd address (NULL if none)
|
||||||
|
* @initrd_filesize: String containing initrd size (only used if
|
||||||
|
* @initrd_addr_str)
|
||||||
|
* @initrd_str: initrd string to process (only used if @initrd_addr_str)
|
||||||
|
* Return: does not return on success, or returns 0 if the boot command
|
||||||
|
* returned, or -ve error value on error
|
||||||
*/
|
*/
|
||||||
static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label,
|
||||||
|
char *kernel_addr, char *initrd_addr_str,
|
||||||
|
char *initrd_filesize, char *initrd_str)
|
||||||
{
|
{
|
||||||
char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
|
char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
|
||||||
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
|
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
|
||||||
char *kernel_addr = NULL;
|
ulong kernel_addr_r;
|
||||||
char *initrd_addr_str = NULL;
|
|
||||||
char initrd_filesize[10];
|
|
||||||
char initrd_str[28];
|
|
||||||
char mac_str[29] = "";
|
|
||||||
char ip_str[68] = "";
|
|
||||||
char *fit_addr = NULL;
|
|
||||||
int bootm_argc = 2;
|
int bootm_argc = 2;
|
||||||
int zboot_argc = 3;
|
int zboot_argc = 3;
|
||||||
int len = 0;
|
|
||||||
ulong kernel_addr_r;
|
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
label_print(label);
|
|
||||||
|
|
||||||
label->attempted = 1;
|
|
||||||
|
|
||||||
if (label->localboot) {
|
|
||||||
if (label->localboot_val >= 0)
|
|
||||||
label_localboot(label);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!label->kernel) {
|
|
||||||
printf("No kernel given, skipping %s\n",
|
|
||||||
label->name);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r",
|
|
||||||
(enum bootflow_img_t)IH_TYPE_KERNEL, NULL)
|
|
||||||
< 0) {
|
|
||||||
printf("Skipping %s for failure retrieving kernel\n",
|
|
||||||
label->name);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_addr = env_get("kernel_addr_r");
|
|
||||||
/* for FIT, append the configuration identifier */
|
|
||||||
if (label->config) {
|
|
||||||
int len = strlen(kernel_addr) + strlen(label->config) + 1;
|
|
||||||
|
|
||||||
fit_addr = malloc(len);
|
|
||||||
if (!fit_addr) {
|
|
||||||
printf("malloc fail (FIT address)\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
snprintf(fit_addr, len, "%s%s", kernel_addr, label->config);
|
|
||||||
kernel_addr = fit_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For FIT, the label can be identical to kernel one */
|
|
||||||
if (label->initrd && !strcmp(label->kernel_label, label->initrd)) {
|
|
||||||
initrd_addr_str = kernel_addr;
|
|
||||||
} else if (label->initrd) {
|
|
||||||
ulong size;
|
|
||||||
if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
|
|
||||||
(enum bootflow_img_t)IH_TYPE_RAMDISK,
|
|
||||||
&size) < 0) {
|
|
||||||
printf("Skipping %s for failure retrieving initrd\n",
|
|
||||||
label->name);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
strcpy(initrd_filesize, simple_xtoa(size));
|
|
||||||
initrd_addr_str = env_get("ramdisk_addr_r");
|
|
||||||
size = snprintf(initrd_str, sizeof(initrd_str), "%s:%lx",
|
|
||||||
initrd_addr_str, size);
|
|
||||||
if (size >= sizeof(initrd_str))
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label->ipappend & 0x1) {
|
|
||||||
sprintf(ip_str, " ip=%s:%s:%s:%s",
|
|
||||||
env_get("ipaddr"), env_get("serverip"),
|
|
||||||
env_get("gatewayip"), env_get("netmask"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_CMD_NET)) {
|
|
||||||
if (label->ipappend & 0x2) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
strcpy(mac_str, " BOOTIF=");
|
|
||||||
err = format_mac_pxe(mac_str + 8, sizeof(mac_str) - 8);
|
|
||||||
if (err < 0)
|
|
||||||
mac_str[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((label->ipappend & 0x3) || label->append) {
|
|
||||||
char bootargs[CONFIG_SYS_CBSIZE] = "";
|
|
||||||
char finalbootargs[CONFIG_SYS_CBSIZE];
|
|
||||||
|
|
||||||
if (strlen(label->append ?: "") +
|
|
||||||
strlen(ip_str) + strlen(mac_str) + 1 > sizeof(bootargs)) {
|
|
||||||
printf("bootarg overflow %zd+%zd+%zd+1 > %zd\n",
|
|
||||||
strlen(label->append ?: ""),
|
|
||||||
strlen(ip_str), strlen(mac_str),
|
|
||||||
sizeof(bootargs));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label->append)
|
|
||||||
strlcpy(bootargs, label->append, sizeof(bootargs));
|
|
||||||
|
|
||||||
strcat(bootargs, ip_str);
|
|
||||||
strcat(bootargs, mac_str);
|
|
||||||
|
|
||||||
cli_simple_process_macros(bootargs, finalbootargs,
|
|
||||||
sizeof(finalbootargs));
|
|
||||||
env_set("bootargs", finalbootargs);
|
|
||||||
printf("append: %s\n", finalbootargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fdt usage is optional:
|
* fdt usage is optional:
|
||||||
* It handles the following scenarios.
|
* It handles the following scenarios.
|
||||||
@@ -607,6 +494,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||||||
}
|
}
|
||||||
} else if (label->fdtdir) {
|
} else if (label->fdtdir) {
|
||||||
char *f1, *f2, *f3, *f4, *slash;
|
char *f1, *f2, *f3, *f4, *slash;
|
||||||
|
int len;
|
||||||
|
|
||||||
f1 = env_get("fdtfile");
|
f1 = env_get("fdtfile");
|
||||||
if (f1) {
|
if (f1) {
|
||||||
@@ -649,7 +537,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||||||
fdtfilefree = malloc(len);
|
fdtfilefree = malloc(len);
|
||||||
if (!fdtfilefree) {
|
if (!fdtfilefree) {
|
||||||
printf("malloc fail (FDT filename)\n");
|
printf("malloc fail (FDT filename)\n");
|
||||||
goto cleanup;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
|
snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
|
||||||
@@ -669,7 +557,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||||||
if (label->fdt) {
|
if (label->fdt) {
|
||||||
printf("Skipping %s for failure retrieving FDT\n",
|
printf("Skipping %s for failure retrieving FDT\n",
|
||||||
label->name);
|
label->name);
|
||||||
goto cleanup;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label->fdtdir) {
|
if (label->fdtdir) {
|
||||||
@@ -750,10 +638,150 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||||||
|
|
||||||
unmap_sysmem(buf);
|
unmap_sysmem(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* label_boot() - Boot according to the contents of a pxe_label
|
||||||
|
*
|
||||||
|
* If we can't boot for any reason, we return. A successful boot never
|
||||||
|
* returns.
|
||||||
|
*
|
||||||
|
* The kernel will be stored in the location given by the 'kernel_addr_r'
|
||||||
|
* environment variable.
|
||||||
|
*
|
||||||
|
* If the label specifies an initrd file, it will be stored in the location
|
||||||
|
* given by the 'ramdisk_addr_r' environment variable.
|
||||||
|
*
|
||||||
|
* If the label specifies an 'append' line, its contents will overwrite that
|
||||||
|
* of the 'bootargs' environment variable.
|
||||||
|
*
|
||||||
|
* @ctx: PXE context
|
||||||
|
* @label: Label to process
|
||||||
|
* Returns does not return on success, otherwise returns 0 if a localboot
|
||||||
|
* label was processed, or 1 on error
|
||||||
|
*/
|
||||||
|
static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
||||||
|
{
|
||||||
|
char *kernel_addr = NULL;
|
||||||
|
char *initrd_addr_str = NULL;
|
||||||
|
char initrd_filesize[10];
|
||||||
|
char initrd_str[28];
|
||||||
|
char mac_str[29] = "";
|
||||||
|
char ip_str[68] = "";
|
||||||
|
char *fit_addr = NULL;
|
||||||
|
|
||||||
|
label_print(label);
|
||||||
|
|
||||||
|
label->attempted = 1;
|
||||||
|
|
||||||
|
if (label->localboot) {
|
||||||
|
if (label->localboot_val >= 0)
|
||||||
|
label_localboot(label);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!label->kernel) {
|
||||||
|
printf("No kernel given, skipping %s\n",
|
||||||
|
label->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r",
|
||||||
|
(enum bootflow_img_t)IH_TYPE_KERNEL, NULL)
|
||||||
|
< 0) {
|
||||||
|
printf("Skipping %s for failure retrieving kernel\n",
|
||||||
|
label->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_addr = env_get("kernel_addr_r");
|
||||||
|
/* for FIT, append the configuration identifier */
|
||||||
|
if (label->config) {
|
||||||
|
int len = strlen(kernel_addr) + strlen(label->config) + 1;
|
||||||
|
|
||||||
|
fit_addr = malloc(len);
|
||||||
|
if (!fit_addr) {
|
||||||
|
printf("malloc fail (FIT address)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(fit_addr, len, "%s%s", kernel_addr, label->config);
|
||||||
|
kernel_addr = fit_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For FIT, the label can be identical to kernel one */
|
||||||
|
if (label->initrd && !strcmp(label->kernel_label, label->initrd)) {
|
||||||
|
initrd_addr_str = kernel_addr;
|
||||||
|
} else if (label->initrd) {
|
||||||
|
ulong size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
|
||||||
|
(enum bootflow_img_t)IH_TYPE_RAMDISK,
|
||||||
|
&size);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Skipping %s for failure retrieving initrd\n",
|
||||||
|
label->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
strcpy(initrd_filesize, simple_xtoa(size));
|
||||||
|
initrd_addr_str = env_get("ramdisk_addr_r");
|
||||||
|
size = snprintf(initrd_str, sizeof(initrd_str), "%s:%lx",
|
||||||
|
initrd_addr_str, size);
|
||||||
|
if (size >= sizeof(initrd_str))
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label->ipappend & 0x1) {
|
||||||
|
sprintf(ip_str, " ip=%s:%s:%s:%s",
|
||||||
|
env_get("ipaddr"), env_get("serverip"),
|
||||||
|
env_get("gatewayip"), env_get("netmask"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_CMD_NET)) {
|
||||||
|
if (label->ipappend & 0x2) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
strcpy(mac_str, " BOOTIF=");
|
||||||
|
err = format_mac_pxe(mac_str + 8, sizeof(mac_str) - 8);
|
||||||
|
if (err < 0)
|
||||||
|
mac_str[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((label->ipappend & 0x3) || label->append) {
|
||||||
|
char bootargs[CONFIG_SYS_CBSIZE] = "";
|
||||||
|
char finalbootargs[CONFIG_SYS_CBSIZE];
|
||||||
|
|
||||||
|
if (strlen(label->append ?: "") +
|
||||||
|
strlen(ip_str) + strlen(mac_str) + 1 > sizeof(bootargs)) {
|
||||||
|
printf("bootarg overflow %zd+%zd+%zd+1 > %zd\n",
|
||||||
|
strlen(label->append ?: ""),
|
||||||
|
strlen(ip_str), strlen(mac_str),
|
||||||
|
sizeof(bootargs));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label->append)
|
||||||
|
strlcpy(bootargs, label->append, sizeof(bootargs));
|
||||||
|
|
||||||
|
strcat(bootargs, ip_str);
|
||||||
|
strcat(bootargs, mac_str);
|
||||||
|
|
||||||
|
cli_simple_process_macros(bootargs, finalbootargs,
|
||||||
|
sizeof(finalbootargs));
|
||||||
|
env_set("bootargs", finalbootargs);
|
||||||
|
printf("append: %s\n", finalbootargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
label_run_boot(ctx, label, kernel_addr, initrd_addr_str,
|
||||||
|
initrd_filesize, initrd_str);
|
||||||
|
/* ignore the error value since we are going to fail anyway */
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
free(fit_addr);
|
free(fit_addr);
|
||||||
|
|
||||||
return 1;
|
return 1; /* returning is always failure */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** enum token_type - Tokens for the pxe file parser */
|
/** enum token_type - Tokens for the pxe file parser */
|
||||||
|
Reference in New Issue
Block a user