133 lines
2.6 KiB
C
133 lines
2.6 KiB
C
|
/*
|
||
|
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-2.0+
|
||
|
*/
|
||
|
|
||
|
#include <common.h>
|
||
|
#include <android_ab.h>
|
||
|
#include <bootm.h>
|
||
|
#include <boot_rkimg.h>
|
||
|
#include <image.h>
|
||
|
#include <malloc.h>
|
||
|
#include <sysmem.h>
|
||
|
#include <asm/arch/fit.h>
|
||
|
|
||
|
DECLARE_GLOBAL_DATA_PTR;
|
||
|
|
||
|
static void *do_boot_fit_storage(ulong *size)
|
||
|
{
|
||
|
return fit_image_load_bootables(size);
|
||
|
}
|
||
|
|
||
|
static void *do_boot_fit_ram(char *const argv[], ulong *data_size)
|
||
|
{
|
||
|
void *fit;
|
||
|
int size;
|
||
|
|
||
|
fit = (void *)simple_strtoul(argv[1], NULL, 16);
|
||
|
if (!fit || fdt_check_header(fit)) {
|
||
|
FIT_I("Invalid header\n");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
size = fit_image_get_bootables_size(fit);
|
||
|
if (!size) {
|
||
|
FIT_I("Failed to get bootable image size\n");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/* reserve this full FIT image */
|
||
|
if (!sysmem_alloc_base(MEM_FIT_USER,
|
||
|
(phys_addr_t)fit, ALIGN(size, 512)))
|
||
|
return NULL;
|
||
|
|
||
|
*data_size = size;
|
||
|
|
||
|
return fit;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* argc == 1:
|
||
|
* FIT image is loaded from storage(eg. CONFIG_BOOTCOMMAND).
|
||
|
*
|
||
|
* argc == 2:
|
||
|
* FIT image is already in ram, the booflow is:
|
||
|
* CLI cmd "bootm <fit_addr>" => do_bootm() =>
|
||
|
* board_do_bootm() => boot_fit <fit_addr>
|
||
|
*/
|
||
|
static int do_boot_fit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||
|
{
|
||
|
char *bootm_args[1];
|
||
|
char fit_addr[12];
|
||
|
ulong size;
|
||
|
void *fit;
|
||
|
int ret;
|
||
|
|
||
|
if (argc > 2)
|
||
|
return CMD_RET_USAGE;
|
||
|
|
||
|
printf("## Booting FIT Image ");
|
||
|
|
||
|
if (argc == 1)
|
||
|
fit = do_boot_fit_storage(&size);
|
||
|
else
|
||
|
fit = do_boot_fit_ram(argv, &size);
|
||
|
|
||
|
if (!fit) {
|
||
|
FIT_I("No FIT image\n");
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
if (fdt_check_header(fit)) {
|
||
|
FIT_I("Invalid FIT format\n");
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
/* fixup entry/load and alloc sysmem */
|
||
|
if (fit_image_pre_process(fit))
|
||
|
goto out;
|
||
|
|
||
|
env_set("bootm-no-reloc", "y");
|
||
|
snprintf(fit_addr, sizeof(fit_addr), "0x%lx", (ulong)fit);
|
||
|
bootm_args[0] = fit_addr;
|
||
|
|
||
|
printf("at %s with size 0x%08lx\n", fit_addr, size);
|
||
|
|
||
|
#ifdef CONFIG_ANDROID_AB
|
||
|
char slot_suffix[3] = {0};
|
||
|
char slot_info[21] = "android_slotsufix=";
|
||
|
|
||
|
if (ab_get_slot_suffix(slot_suffix))
|
||
|
goto out;
|
||
|
|
||
|
strcat(slot_info, slot_suffix);
|
||
|
env_update("bootargs", slot_info);
|
||
|
#endif
|
||
|
|
||
|
ret = do_bootm_states(NULL, 0, ARRAY_SIZE(bootm_args), bootm_args,
|
||
|
BOOTM_STATE_START |
|
||
|
BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
|
||
|
BOOTM_STATE_LOADOS |
|
||
|
#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
|
||
|
BOOTM_STATE_RAMDISK |
|
||
|
#endif
|
||
|
BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
|
||
|
BOOTM_STATE_OS_GO, &images, 1);
|
||
|
|
||
|
if (ret && argc != 1) {
|
||
|
fit_image_fail_process(fit);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
return CMD_RET_SUCCESS;
|
||
|
out:
|
||
|
return CMD_RET_FAILURE;
|
||
|
}
|
||
|
|
||
|
U_BOOT_CMD_ALWAYS(
|
||
|
boot_fit, 2, 1, do_boot_fit,
|
||
|
"Boot FIT Image from memory or boot/recovery partition",
|
||
|
"boot_fit [addr]"
|
||
|
);
|