spl: fit: support load kernel fit
Support load kernel fit image from boot/recovery partition and ignore U-Boot proper if we expect to boot kernel in SPL. Signed-off-by: Joseph Chen <chenjh@rock-chips.com> Change-Id: I220c70c784e2327feea591756cbbde97ada8335f
This commit is contained in:
parent
3d94fb2890
commit
e12dde2d59
|
|
@ -6,12 +6,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <boot_rkimg.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <linux/libfdt.h>
|
#include <linux/libfdt.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <optee_include/OpteeClientInterface.h>
|
|
||||||
|
|
||||||
#ifndef CONFIG_SYS_BOOTM_LEN
|
#ifndef CONFIG_SYS_BOOTM_LEN
|
||||||
#define CONFIG_SYS_BOOTM_LEN (64 << 20)
|
#define CONFIG_SYS_BOOTM_LEN (64 << 20)
|
||||||
|
|
@ -395,6 +395,120 @@ static void *spl_fit_load_blob(struct spl_load_info *info,
|
||||||
return fit;
|
return fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_FIT_LOAD_KERNEL
|
||||||
|
#ifdef CONFIG_SPL_LIBDISK_SUPPORT
|
||||||
|
__weak const char *spl_kernel_partition(struct spl_image_info *spl,
|
||||||
|
struct spl_load_info *info)
|
||||||
|
{
|
||||||
|
return PART_BOOT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int spl_load_kernel_fit(struct spl_image_info *spl_image,
|
||||||
|
struct spl_load_info *info)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Never change the image order.
|
||||||
|
*
|
||||||
|
* Considering thunder-boot feature, there maybe asynchronous
|
||||||
|
* loading operation of these images and ramdisk is usually to
|
||||||
|
* be the last one.
|
||||||
|
*
|
||||||
|
* The .its content rule of kernel fit image follows U-Boot proper.
|
||||||
|
*/
|
||||||
|
const char *images[] = { FIT_FDT_PROP, FIT_KERNEL_PROP, FIT_RAMDISK_PROP, };
|
||||||
|
struct spl_image_info image_info;
|
||||||
|
char fit_header[info->bl_len];
|
||||||
|
int images_noffset;
|
||||||
|
int base_offset;
|
||||||
|
int sector;
|
||||||
|
int node, ret, i;
|
||||||
|
void *fit;
|
||||||
|
|
||||||
|
if (spl_image->next_stage != SPL_NEXT_STAGE_KERNEL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_LIBDISK_SUPPORT
|
||||||
|
const char *part_name = PART_BOOT;
|
||||||
|
disk_partition_t part_info;
|
||||||
|
|
||||||
|
part_name = spl_kernel_partition(spl_image, info);
|
||||||
|
if (part_get_info_by_name(info->dev, part_name, &part_info) <= 0) {
|
||||||
|
printf("%s: no partition\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
sector = part_info.start;
|
||||||
|
#else
|
||||||
|
sector = CONFIG_SPL_FIT_LOAD_KERNEL_SECTOR;
|
||||||
|
#endif
|
||||||
|
if (info->read(info, sector, 1, &fit_header) != 1) {
|
||||||
|
debug("%s: no memory\n", __func__);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image_get_magic((void *)&fit_header) != FDT_MAGIC) {
|
||||||
|
debug("%s: Not fit magic\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fit = spl_fit_load_blob(info, sector, fit_header, &base_offset);
|
||||||
|
if (!fit) {
|
||||||
|
debug("%s: Cannot load blob\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify the configure node by keys, if required */
|
||||||
|
#ifdef CONFIG_SPL_FIT_SIGNATURE
|
||||||
|
int conf_noffset;
|
||||||
|
|
||||||
|
conf_noffset = fit_conf_get_node(fit, NULL);
|
||||||
|
if (conf_noffset <= 0) {
|
||||||
|
printf("No default config node\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fit_config_verify(fit, conf_noffset);
|
||||||
|
if (ret) {
|
||||||
|
printf("fit verify configure failed, ret=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
|
||||||
|
if (images_noffset < 0) {
|
||||||
|
debug("%s: Cannot find /images node: %d\n",
|
||||||
|
__func__, images_noffset);
|
||||||
|
return images_noffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(images); i++) {
|
||||||
|
node = spl_fit_get_image_node(fit, images_noffset,
|
||||||
|
images[i], 0);
|
||||||
|
if (node < 0) {
|
||||||
|
debug("No image: %s\n", images[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = spl_load_fit_image(info, sector, fit, base_offset,
|
||||||
|
node, &image_info);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* initial addr or entry point */
|
||||||
|
if (!strcmp(images[i], FIT_FDT_PROP))
|
||||||
|
spl_image->fdt_addr = (void *)image_info.load_addr;
|
||||||
|
else if (!strcmp(images[i], FIT_KERNEL_PROP))
|
||||||
|
spl_image->entry_point_os = image_info.load_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("entry_point=0x%08lx, entry_point_os=0x%08lx, fdt_addr=0x%08lx\n",
|
||||||
|
spl_image->entry_point, spl_image->entry_point_os,
|
||||||
|
(ulong)spl_image->fdt_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int spl_internal_load_simple_fit(struct spl_image_info *spl_image,
|
static int spl_internal_load_simple_fit(struct spl_image_info *spl_image,
|
||||||
struct spl_load_info *info,
|
struct spl_load_info *info,
|
||||||
ulong sector, void *fit_header)
|
ulong sector, void *fit_header)
|
||||||
|
|
@ -485,6 +599,7 @@ static int spl_internal_load_simple_fit(struct spl_image_info *spl_image,
|
||||||
ret);
|
ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* standalone is special one, continue to find others */
|
||||||
node = -1;
|
node = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -549,14 +664,19 @@ static int spl_internal_load_simple_fit(struct spl_image_info *spl_image,
|
||||||
if (node < 0)
|
if (node < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!spl_fit_image_get_os(fit, node, &os_type))
|
||||||
|
debug("Loadable is %s\n", genimg_get_os_name(os_type));
|
||||||
|
|
||||||
|
/* skip U-Boot ? */
|
||||||
|
if (spl_image->next_stage == SPL_NEXT_STAGE_KERNEL &&
|
||||||
|
os_type == IH_OS_U_BOOT)
|
||||||
|
continue;
|
||||||
|
|
||||||
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
|
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
|
||||||
&image_info);
|
&image_info);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!spl_fit_image_get_os(fit, node, &os_type))
|
|
||||||
debug("Loadable is %s\n", genimg_get_os_name(os_type));
|
|
||||||
|
|
||||||
if (os_type == IH_OS_U_BOOT) {
|
if (os_type == IH_OS_U_BOOT) {
|
||||||
spl_fit_append_fdt(&image_info, info, sector,
|
spl_fit_append_fdt(&image_info, info, sector,
|
||||||
fit, images, base_offset);
|
fit, images, base_offset);
|
||||||
|
|
@ -593,6 +713,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
||||||
struct spl_load_info *info, ulong sector, void *fit)
|
struct spl_load_info *info, ulong sector, void *fit)
|
||||||
{
|
{
|
||||||
ulong sector_offs = sector;
|
ulong sector_offs = sector;
|
||||||
|
int ret = -EINVAL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_SPL_FIT_IMAGE_MULTIPLE; i++) {
|
for (i = 0; i < CONFIG_SPL_FIT_IMAGE_MULTIPLE; i++) {
|
||||||
|
|
@ -607,15 +728,20 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_get_magic(fit) != FDT_MAGIC) {
|
if (image_get_magic(fit) != FDT_MAGIC) {
|
||||||
printf("Bad fit magic\n");
|
printf("Not fit magic\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spl_internal_load_simple_fit(spl_image, info,
|
ret = spl_internal_load_simple_fit(spl_image, info,
|
||||||
sector_offs, fit))
|
sector_offs, fit);
|
||||||
return 0;
|
if (!ret) {
|
||||||
|
#ifdef CONFIG_SPL_FIT_LOAD_KERNEL
|
||||||
|
ret = spl_load_kernel_fit(spl_image, info);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -335,4 +335,12 @@ void spl_perform_fixups(struct spl_image_info *spl_image);
|
||||||
*/
|
*/
|
||||||
int spl_board_prepare_for_jump(struct spl_image_info *spl_image);
|
int spl_board_prepare_for_jump(struct spl_image_info *spl_image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spl_kernel_partition() - arch/board-specific callback to get kernel partition
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_SPL_FIT_LOAD_KERNEL
|
||||||
|
const char *spl_kernel_partition(struct spl_image_info *spl,
|
||||||
|
struct spl_load_info *info);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue