[new uImage] ppc: Add new uImage format support to FDT handling routines
Support for new (FIT) format uImages is added to powerpc specific boot_get_fdt() routine which now recognizes, sanity checks FIT image and is able to access data sections of the requested component image. Signed-off-by: Marian Balakowicz <m8@semihalf.com>
This commit is contained in:
parent
a44a269a90
commit
bc8ed486b1
152
lib_ppc/bootm.c
152
lib_ppc/bootm.c
|
@ -254,10 +254,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
* r6: NULL
|
* r6: NULL
|
||||||
* r7: NULL
|
* r7: NULL
|
||||||
*/
|
*/
|
||||||
|
debug (" Booting using OF flat tree...\n");
|
||||||
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
|
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
|
||||||
/* does not return */
|
/* does not return */
|
||||||
}
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Linux Kernel Parameters (passing board info data):
|
* Linux Kernel Parameters (passing board info data):
|
||||||
* r3: ptr to board info data
|
* r3: ptr to board info data
|
||||||
|
@ -266,8 +268,10 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
* r6: Start of command line string
|
* r6: Start of command line string
|
||||||
* r7: End of command line string
|
* r7: End of command line string
|
||||||
*/
|
*/
|
||||||
|
debug (" Booting using board info...\n");
|
||||||
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
|
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
|
||||||
/* does not return */
|
/* does not return */
|
||||||
|
}
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -353,6 +357,47 @@ static image_header_t *image_get_fdt (ulong fdt_addr)
|
||||||
return fdt_hdr;
|
return fdt_hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fit_check_fdt - verify FIT format FDT subimage
|
||||||
|
* @fit_hdr: pointer to the FIT header
|
||||||
|
* fdt_noffset: FDT subimage node offset within FIT image
|
||||||
|
* @verify: data CRC verification flag
|
||||||
|
*
|
||||||
|
* fit_check_fdt() verifies integrity of the FDT subimage and from
|
||||||
|
* specified FIT image.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 1, on success
|
||||||
|
* 0, on failure
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_FIT)
|
||||||
|
static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
|
||||||
|
{
|
||||||
|
fit_image_print (fit, fdt_noffset, " ");
|
||||||
|
|
||||||
|
if (verify) {
|
||||||
|
puts (" Verifying Hash Integrity ... ");
|
||||||
|
if (!fit_image_check_hashes (fit, fdt_noffset)) {
|
||||||
|
fdt_error ("Bad Data Hash");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
puts ("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
|
||||||
|
fdt_error ("Not a FDT image");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
|
||||||
|
fdt_error ("FDT image is compressed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FIT */
|
||||||
|
|
||||||
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
|
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
|
||||||
{
|
{
|
||||||
|
@ -366,8 +411,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
const char *fit_uname_config = NULL;
|
const char *fit_uname_config = NULL;
|
||||||
const char *fit_uname_fdt = NULL;
|
const char *fit_uname_fdt = NULL;
|
||||||
ulong default_addr;
|
ulong default_addr;
|
||||||
|
int conf_noffset;
|
||||||
|
int fdt_noffset;
|
||||||
|
const void *data;
|
||||||
|
size_t size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
*of_flat_tree = NULL;
|
||||||
|
*of_size = 0;
|
||||||
|
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
#if defined(CONFIG_FIT)
|
#if defined(CONFIG_FIT)
|
||||||
/*
|
/*
|
||||||
|
@ -398,7 +450,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
fdt_addr);
|
fdt_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug ("## Checking for 'FDT'/'FDT image' at %08lx\n",
|
debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
|
||||||
fdt_addr);
|
fdt_addr);
|
||||||
|
|
||||||
/* copy from dataflash if needed */
|
/* copy from dataflash if needed */
|
||||||
|
@ -411,10 +463,8 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
*/
|
*/
|
||||||
switch (genimg_get_format ((void *)fdt_addr)) {
|
switch (genimg_get_format ((void *)fdt_addr)) {
|
||||||
case IMAGE_FORMAT_LEGACY:
|
case IMAGE_FORMAT_LEGACY:
|
||||||
debug ("* fdt: legacy format image\n");
|
|
||||||
|
|
||||||
/* verify fdt_addr points to a valid image header */
|
/* verify fdt_addr points to a valid image header */
|
||||||
printf ("## Flattened Device Tree Legacy Image at %08lx\n",
|
printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
|
||||||
fdt_addr);
|
fdt_addr);
|
||||||
fdt_hdr = image_get_fdt (fdt_addr);
|
fdt_hdr = image_get_fdt (fdt_addr);
|
||||||
if (!fdt_hdr)
|
if (!fdt_hdr)
|
||||||
|
@ -434,11 +484,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
fdt_error ("fdt overwritten");
|
fdt_error ("fdt overwritten");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
memmove ((void *)image_get_load (fdt_hdr),
|
|
||||||
|
debug (" Loading FDT from 0x%08lx to 0x%08lx\n",
|
||||||
|
image_get_data (fdt_hdr), load_start);
|
||||||
|
|
||||||
|
memmove ((void *)load_start,
|
||||||
(void *)image_get_data (fdt_hdr),
|
(void *)image_get_data (fdt_hdr),
|
||||||
image_get_data_size (fdt_hdr));
|
image_get_data_size (fdt_hdr));
|
||||||
|
|
||||||
fdt_blob = (char *)image_get_load (fdt_hdr);
|
fdt_blob = (char *)load_start;
|
||||||
break;
|
break;
|
||||||
case IMAGE_FORMAT_FIT:
|
case IMAGE_FORMAT_FIT:
|
||||||
/*
|
/*
|
||||||
|
@ -448,14 +502,90 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_FIT)
|
#if defined(CONFIG_FIT)
|
||||||
/* check FDT blob vs FIT blob */
|
/* check FDT blob vs FIT blob */
|
||||||
if (0) { /* FIXME: call FIT format verification */
|
if (fit_check_format ((const void *)fdt_addr)) {
|
||||||
/*
|
/*
|
||||||
* FIT image
|
* FIT image
|
||||||
*/
|
*/
|
||||||
fit_hdr = (void *)fdt_addr;
|
fit_hdr = (void *)fdt_addr;
|
||||||
debug ("* fdt: FIT format image\n");
|
printf ("## Flattened Device Tree from FIT Image at %08lx\n",
|
||||||
fit_unsupported_reset ("PPC fdt");
|
fdt_addr);
|
||||||
|
|
||||||
|
if (!fit_uname_fdt) {
|
||||||
|
/*
|
||||||
|
* no FDT blob image node unit name,
|
||||||
|
* try to get config node first. If
|
||||||
|
* config unit node name is NULL
|
||||||
|
* fit_conf_get_node() will try to
|
||||||
|
* find default config node
|
||||||
|
*/
|
||||||
|
conf_noffset = fit_conf_get_node (fit_hdr,
|
||||||
|
fit_uname_config);
|
||||||
|
if (conf_noffset < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
|
||||||
|
conf_noffset);
|
||||||
|
fit_uname_fdt = fit_get_name (fit_hdr,
|
||||||
|
fdt_noffset, NULL);
|
||||||
|
} else {
|
||||||
|
/* get FDT component image node offset */
|
||||||
|
fdt_noffset = fit_image_get_node (fit_hdr,
|
||||||
|
fit_uname_fdt);
|
||||||
|
}
|
||||||
|
if (fdt_noffset < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
printf (" Trying '%s' FDT blob subimage\n",
|
||||||
|
fit_uname_fdt);
|
||||||
|
|
||||||
|
if (!fit_check_fdt (fit_hdr, fdt_noffset,
|
||||||
|
images->verify))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* get ramdisk image data address and length */
|
||||||
|
if (fit_image_get_data (fit_hdr, fdt_noffset,
|
||||||
|
&data, &size)) {
|
||||||
|
fdt_error ("Could not find FDT subimage data");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verift that image data is a proper FDT blob */
|
||||||
|
if (fdt_check_header ((char *)data) != 0) {
|
||||||
|
fdt_error ("Subimage data is not a FTD");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move image data to the load address,
|
||||||
|
* make sure we don't overwrite initial image
|
||||||
|
*/
|
||||||
|
image_start = (ulong)fit_hdr;
|
||||||
|
image_end = fit_get_end (fit_hdr);
|
||||||
|
|
||||||
|
if (fit_image_get_load (fit_hdr, fdt_noffset,
|
||||||
|
&load_start) == 0) {
|
||||||
|
load_end = load_start + size;
|
||||||
|
|
||||||
|
if ((load_start < image_end) &&
|
||||||
|
(load_end > image_start)) {
|
||||||
|
fdt_error ("FDT overwritten");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (" Loading FDT from 0x%08lx to 0x%08lx\n",
|
||||||
|
(ulong)data, load_start);
|
||||||
|
|
||||||
|
memmove ((void *)load_start,
|
||||||
|
(void *)data, size);
|
||||||
|
|
||||||
|
fdt_blob = (char *)load_start;
|
||||||
|
} else {
|
||||||
|
fdt_blob = (char *)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
images->fit_hdr_fdt = fit_hdr;
|
||||||
|
images->fit_uname_fdt = fit_uname_fdt;
|
||||||
|
break;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -509,8 +639,6 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug ("## No Flattened Device Tree\n");
|
debug ("## No Flattened Device Tree\n");
|
||||||
*of_flat_tree = NULL;
|
|
||||||
*of_size = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue