Merge branch '2021-10-08-image-cleanups'
- A large number of image file and tooling related cleanups
This commit is contained in:
commit
94e922c76a
51 changed files with 2332 additions and 1509 deletions
|
@ -63,7 +63,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
||||||
"(fake run for tracing)" : "");
|
"(fake run for tracing)" : "");
|
||||||
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
|
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
|
||||||
|
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
r0 = 2;
|
r0 = 2;
|
||||||
r2 = (unsigned int)images->ft_addr;
|
r2 = (unsigned int)images->ft_addr;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -199,7 +199,7 @@ static void boot_prep_linux(bootm_headers_t *images)
|
||||||
{
|
{
|
||||||
char *commandline = env_get("bootargs");
|
char *commandline = env_get("bootargs");
|
||||||
|
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
#ifdef CONFIG_OF_LIBFDT
|
#ifdef CONFIG_OF_LIBFDT
|
||||||
debug("using: FDT\n");
|
debug("using: FDT\n");
|
||||||
if (image_setup_linux(images)) {
|
if (image_setup_linux(images)) {
|
||||||
|
@ -356,7 +356,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
||||||
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
|
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
|
||||||
announce_and_cleanup(fake);
|
announce_and_cleanup(fake);
|
||||||
|
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len)
|
||||||
r2 = (unsigned long)images->ft_addr;
|
r2 = (unsigned long)images->ft_addr;
|
||||||
else
|
else
|
||||||
r2 = gd->bd->bi_boot_params;
|
r2 = gd->bd->bi_boot_params;
|
||||||
|
|
|
@ -591,7 +591,7 @@ static ulong get_image_ivt_offset(ulong img_addr)
|
||||||
return (image_get_image_size((image_header_t *)img_addr)
|
return (image_get_image_size((image_header_t *)img_addr)
|
||||||
+ 0x1000 - 1) & ~(0x1000 - 1);
|
+ 0x1000 - 1) & ~(0x1000 - 1);
|
||||||
#endif
|
#endif
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
case IMAGE_FORMAT_FIT:
|
case IMAGE_FORMAT_FIT:
|
||||||
return (fit_get_size(buf) + 0x1000 - 1) & ~(0x1000 - 1);
|
return (fit_get_size(buf) + 0x1000 - 1) & ~(0x1000 - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,7 +75,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
||||||
|
|
||||||
static void boot_prep_linux(bootm_headers_t *images)
|
static void boot_prep_linux(bootm_headers_t *images)
|
||||||
{
|
{
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
debug("using: FDT\n");
|
debug("using: FDT\n");
|
||||||
if (image_setup_linux(images)) {
|
if (image_setup_linux(images)) {
|
||||||
printf("FDT creation failed! hanging...");
|
printf("FDT creation failed! hanging...");
|
||||||
|
|
|
@ -69,7 +69,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
|
||||||
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
||||||
(ulong)theKernel);
|
(ulong)theKernel);
|
||||||
|
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
#ifdef CONFIG_OF_LIBFDT
|
#ifdef CONFIG_OF_LIBFDT
|
||||||
debug("using: FDT\n");
|
debug("using: FDT\n");
|
||||||
if (image_setup_linux(images)) {
|
if (image_setup_linux(images)) {
|
||||||
|
@ -110,7 +110,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
cleanup_before_linux();
|
cleanup_before_linux();
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len)
|
||||||
theKernel(0, machid, (unsigned long)images->ft_addr);
|
theKernel(0, machid, (unsigned long)images->ft_addr);
|
||||||
else
|
else
|
||||||
theKernel(0, machid, bd->bi_boot_params);
|
theKernel(0, machid, bd->bi_boot_params);
|
||||||
|
|
|
@ -64,7 +64,7 @@ static void announce_and_cleanup(int fake)
|
||||||
|
|
||||||
static void boot_prep_linux(bootm_headers_t *images)
|
static void boot_prep_linux(bootm_headers_t *images)
|
||||||
{
|
{
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
#ifdef CONFIG_OF_LIBFDT
|
#ifdef CONFIG_OF_LIBFDT
|
||||||
debug("using: FDT\n");
|
debug("using: FDT\n");
|
||||||
if (image_setup_linux(images)) {
|
if (image_setup_linux(images)) {
|
||||||
|
@ -96,7 +96,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
||||||
announce_and_cleanup(fake);
|
announce_and_cleanup(fake);
|
||||||
|
|
||||||
if (!fake) {
|
if (!fake) {
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
ret = smp_call_function(images->ep,
|
ret = smp_call_function(images->ep,
|
||||||
(ulong)images->ft_addr, 0, 0);
|
(ulong)images->ft_addr, 0, 0);
|
||||||
|
|
|
@ -871,7 +871,7 @@ int board_prep_linux(bootm_headers_t *images)
|
||||||
if (env_common.core_mask.val == ALL_CPU_MASK)
|
if (env_common.core_mask.val == ALL_CPU_MASK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!IMAGE_ENABLE_OF_LIBFDT || !images->ft_len) {
|
if (!CONFIG_IS_ENABLED(OF_LIBFDT) || !images->ft_len) {
|
||||||
pr_err("WARN: core_mask setup will work properly only with external DTB!\n");
|
pr_err("WARN: core_mask setup will work properly only with external DTB!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,16 @@ config SPL_FIT_SIGNATURE
|
||||||
select SPL_IMAGE_SIGN_INFO
|
select SPL_IMAGE_SIGN_INFO
|
||||||
select SPL_FIT_FULL_CHECK
|
select SPL_FIT_FULL_CHECK
|
||||||
|
|
||||||
|
config SPL_FIT_SIGNATURE_MAX_SIZE
|
||||||
|
hex "Max size of signed FIT structures in SPL"
|
||||||
|
depends on SPL_FIT_SIGNATURE
|
||||||
|
default 0x10000000
|
||||||
|
help
|
||||||
|
This option sets a max size in bytes for verified FIT uImages.
|
||||||
|
A sane value of 256MB protects corrupted DTB structures from overlapping
|
||||||
|
device memory. Assure this size does not extend past expected storage
|
||||||
|
space.
|
||||||
|
|
||||||
config SPL_LOAD_FIT
|
config SPL_LOAD_FIT
|
||||||
bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
|
bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
|
||||||
select SPL_FIT
|
select SPL_FIT
|
||||||
|
|
|
@ -101,7 +101,7 @@ obj-y += malloc_simple.o
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-y += image.o
|
obj-y += image.o image-board.o
|
||||||
obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
|
obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
|
||||||
obj-$(CONFIG_ANDROID_AB) += android_ab.o
|
obj-$(CONFIG_ANDROID_AB) += android_ab.o
|
||||||
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
|
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
|
||||||
|
|
|
@ -115,7 +115,7 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
images.os.arch = image_get_arch(os_hdr);
|
images.os.arch = image_get_arch(os_hdr);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
case IMAGE_FORMAT_FIT:
|
case IMAGE_FORMAT_FIT:
|
||||||
if (fit_image_get_type(images.fit_hdr_os,
|
if (fit_image_get_type(images.fit_hdr_os,
|
||||||
images.fit_noffset_os,
|
images.fit_noffset_os,
|
||||||
|
@ -187,7 +187,7 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
/* Kernel entry point is the setup.bin */
|
/* Kernel entry point is the setup.bin */
|
||||||
} else if (images.legacy_hdr_valid) {
|
} else if (images.legacy_hdr_valid) {
|
||||||
images.ep = image_get_ep(&images.legacy_hdr_os_copy);
|
images.ep = image_get_ep(&images.legacy_hdr_os_copy);
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
} else if (images.fit_uname_os) {
|
} else if (images.fit_uname_os) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IMAGE_ENABLE_OF_LIBFDT
|
#if CONFIG_IS_ENABLED(OF_LIBFDT)
|
||||||
/* find flattened device tree */
|
/* find flattened device tree */
|
||||||
ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
|
ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
|
||||||
&images.ft_addr, &images.ft_len);
|
&images.ft_addr, &images.ft_len);
|
||||||
|
@ -295,16 +295,16 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
|
||||||
set_working_fdt_addr(map_to_sysmem(images.ft_addr));
|
set_working_fdt_addr(map_to_sysmem(images.ft_addr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
#if defined(CONFIG_FPGA)
|
if (IS_ENABLED(CONFIG_FPGA)) {
|
||||||
/* find bitstreams */
|
/* find bitstreams */
|
||||||
ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
|
ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("FPGA image is corrupted or invalid\n");
|
printf("FPGA image is corrupted or invalid\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* find all of the loadables */
|
/* find all of the loadables */
|
||||||
ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
|
ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
|
||||||
|
@ -706,7 +706,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
|
#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
|
||||||
if (!ret && (states & BOOTM_STATE_FDT)) {
|
if (!ret && (states & BOOTM_STATE_FDT)) {
|
||||||
boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
|
boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
|
||||||
ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
|
ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
|
||||||
|
@ -858,7 +858,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
const void *buf;
|
const void *buf;
|
||||||
const char *fit_uname_config = NULL;
|
const char *fit_uname_config = NULL;
|
||||||
const char *fit_uname_kernel = NULL;
|
const char *fit_uname_kernel = NULL;
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
int os_noffset;
|
int os_noffset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -916,7 +916,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
|
bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if IMAGE_ENABLE_FIT
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
case IMAGE_FORMAT_FIT:
|
case IMAGE_FORMAT_FIT:
|
||||||
os_noffset = fit_image_load(images, img_addr,
|
os_noffset = fit_image_load(images, img_addr,
|
||||||
&fit_uname_kernel, &fit_uname_config,
|
&fit_uname_kernel, &fit_uname_config,
|
||||||
|
|
|
@ -58,6 +58,14 @@ static void copy_args(char *dest, int argc, char *const argv[], char delim)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void __maybe_unused fit_unsupported_reset(const char *msg)
|
||||||
|
{
|
||||||
|
if (CONFIG_IS_ENABLED(FIT_VERBOSE)) {
|
||||||
|
printf("! FIT images not supported for '%s' - must reset board to recover!\n",
|
||||||
|
msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTM_NETBSD
|
#ifdef CONFIG_BOOTM_NETBSD
|
||||||
static int do_bootm_netbsd(int flag, int argc, char *const argv[],
|
static int do_bootm_netbsd(int flag, int argc, char *const argv[],
|
||||||
bootm_headers_t *images)
|
bootm_headers_t *images)
|
||||||
|
|
108
common/hash.c
108
common/hash.c
|
@ -24,7 +24,9 @@
|
||||||
#include <u-boot/crc.h>
|
#include <u-boot/crc.h>
|
||||||
#else
|
#else
|
||||||
#include "mkimage.h"
|
#include "mkimage.h"
|
||||||
|
#include <linux/compiler_attributes.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <linux/kconfig.h>
|
||||||
#endif /* !USE_HOSTCC*/
|
#endif /* !USE_HOSTCC*/
|
||||||
|
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
@ -41,8 +43,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
static void reloc_update(void);
|
static void reloc_update(void);
|
||||||
|
|
||||||
#if defined(CONFIG_SHA1) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
|
static int __maybe_unused hash_init_sha1(struct hash_algo *algo, void **ctxp)
|
||||||
static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
|
|
||||||
{
|
{
|
||||||
sha1_context *ctx = malloc(sizeof(sha1_context));
|
sha1_context *ctx = malloc(sizeof(sha1_context));
|
||||||
sha1_starts(ctx);
|
sha1_starts(ctx);
|
||||||
|
@ -50,15 +51,16 @@ static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
|
static int __maybe_unused hash_update_sha1(struct hash_algo *algo, void *ctx,
|
||||||
unsigned int size, int is_last)
|
const void *buf, unsigned int size,
|
||||||
|
int is_last)
|
||||||
{
|
{
|
||||||
sha1_update((sha1_context *)ctx, buf, size);
|
sha1_update((sha1_context *)ctx, buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
|
static int __maybe_unused hash_finish_sha1(struct hash_algo *algo, void *ctx,
|
||||||
int size)
|
void *dest_buf, int size)
|
||||||
{
|
{
|
||||||
if (size < algo->digest_size)
|
if (size < algo->digest_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -67,10 +69,8 @@ static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SHA256) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
|
static int __maybe_unused hash_init_sha256(struct hash_algo *algo, void **ctxp)
|
||||||
static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
|
|
||||||
{
|
{
|
||||||
sha256_context *ctx = malloc(sizeof(sha256_context));
|
sha256_context *ctx = malloc(sizeof(sha256_context));
|
||||||
sha256_starts(ctx);
|
sha256_starts(ctx);
|
||||||
|
@ -78,15 +78,16 @@ static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_update_sha256(struct hash_algo *algo, void *ctx,
|
static int __maybe_unused hash_update_sha256(struct hash_algo *algo, void *ctx,
|
||||||
const void *buf, unsigned int size, int is_last)
|
const void *buf, uint size,
|
||||||
|
int is_last)
|
||||||
{
|
{
|
||||||
sha256_update((sha256_context *)ctx, buf, size);
|
sha256_update((sha256_context *)ctx, buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
|
static int __maybe_unused hash_finish_sha256(struct hash_algo *algo, void *ctx,
|
||||||
*dest_buf, int size)
|
void *dest_buf, int size)
|
||||||
{
|
{
|
||||||
if (size < algo->digest_size)
|
if (size < algo->digest_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -95,10 +96,8 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SHA384) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
|
static int __maybe_unused hash_init_sha384(struct hash_algo *algo, void **ctxp)
|
||||||
static int hash_init_sha384(struct hash_algo *algo, void **ctxp)
|
|
||||||
{
|
{
|
||||||
sha512_context *ctx = malloc(sizeof(sha512_context));
|
sha512_context *ctx = malloc(sizeof(sha512_context));
|
||||||
sha384_starts(ctx);
|
sha384_starts(ctx);
|
||||||
|
@ -106,15 +105,16 @@ static int hash_init_sha384(struct hash_algo *algo, void **ctxp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_update_sha384(struct hash_algo *algo, void *ctx,
|
static int __maybe_unused hash_update_sha384(struct hash_algo *algo, void *ctx,
|
||||||
const void *buf, unsigned int size, int is_last)
|
const void *buf, uint size,
|
||||||
|
int is_last)
|
||||||
{
|
{
|
||||||
sha384_update((sha512_context *)ctx, buf, size);
|
sha384_update((sha512_context *)ctx, buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void
|
static int __maybe_unused hash_finish_sha384(struct hash_algo *algo, void *ctx,
|
||||||
*dest_buf, int size)
|
void *dest_buf, int size)
|
||||||
{
|
{
|
||||||
if (size < algo->digest_size)
|
if (size < algo->digest_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -123,10 +123,8 @@ static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SHA512) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
|
static int __maybe_unused hash_init_sha512(struct hash_algo *algo, void **ctxp)
|
||||||
static int hash_init_sha512(struct hash_algo *algo, void **ctxp)
|
|
||||||
{
|
{
|
||||||
sha512_context *ctx = malloc(sizeof(sha512_context));
|
sha512_context *ctx = malloc(sizeof(sha512_context));
|
||||||
sha512_starts(ctx);
|
sha512_starts(ctx);
|
||||||
|
@ -134,15 +132,16 @@ static int hash_init_sha512(struct hash_algo *algo, void **ctxp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_update_sha512(struct hash_algo *algo, void *ctx,
|
static int __maybe_unused hash_update_sha512(struct hash_algo *algo, void *ctx,
|
||||||
const void *buf, unsigned int size, int is_last)
|
const void *buf, uint size,
|
||||||
|
int is_last)
|
||||||
{
|
{
|
||||||
sha512_update((sha512_context *)ctx, buf, size);
|
sha512_update((sha512_context *)ctx, buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_finish_sha512(struct hash_algo *algo, void *ctx, void
|
static int __maybe_unused hash_finish_sha512(struct hash_algo *algo, void *ctx,
|
||||||
*dest_buf, int size)
|
void *dest_buf, int size)
|
||||||
{
|
{
|
||||||
if (size < algo->digest_size)
|
if (size < algo->digest_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -151,8 +150,6 @@ static int hash_finish_sha512(struct hash_algo *algo, void *ctx, void
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp)
|
static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +178,7 @@ static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
|
static int __maybe_unused hash_init_crc32(struct hash_algo *algo, void **ctxp)
|
||||||
{
|
{
|
||||||
uint32_t *ctx = malloc(sizeof(uint32_t));
|
uint32_t *ctx = malloc(sizeof(uint32_t));
|
||||||
*ctx = 0;
|
*ctx = 0;
|
||||||
|
@ -189,15 +186,16 @@ static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_update_crc32(struct hash_algo *algo, void *ctx,
|
static int __maybe_unused hash_update_crc32(struct hash_algo *algo, void *ctx,
|
||||||
const void *buf, unsigned int size, int is_last)
|
const void *buf, unsigned int size,
|
||||||
|
int is_last)
|
||||||
{
|
{
|
||||||
*((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
|
*((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
|
static int __maybe_unused hash_finish_crc32(struct hash_algo *algo, void *ctx,
|
||||||
int size)
|
void *dest_buf, int size)
|
||||||
{
|
{
|
||||||
if (size < algo->digest_size)
|
if (size < algo->digest_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -207,18 +205,13 @@ static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_HOSTCC
|
|
||||||
# define I_WANT_MD5 1
|
|
||||||
#else
|
|
||||||
# define I_WANT_MD5 CONFIG_IS_ENABLED(MD5)
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* These are the hash algorithms we support. If we have hardware acceleration
|
* These are the hash algorithms we support. If we have hardware acceleration
|
||||||
* is enable we will use that, otherwise a software version of the algorithm.
|
* is enable we will use that, otherwise a software version of the algorithm.
|
||||||
* Note that algorithm names must be in lower case.
|
* Note that algorithm names must be in lower case.
|
||||||
*/
|
*/
|
||||||
static struct hash_algo hash_algo[] = {
|
static struct hash_algo hash_algo[] = {
|
||||||
#if I_WANT_MD5
|
#if CONFIG_IS_ENABLED(MD5)
|
||||||
{
|
{
|
||||||
.name = "md5",
|
.name = "md5",
|
||||||
.digest_size = MD5_SUM_LEN,
|
.digest_size = MD5_SUM_LEN,
|
||||||
|
@ -226,17 +219,17 @@ static struct hash_algo hash_algo[] = {
|
||||||
.hash_func_ws = md5_wd,
|
.hash_func_ws = md5_wd,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA1
|
#if CONFIG_IS_ENABLED(SHA1)
|
||||||
{
|
{
|
||||||
.name = "sha1",
|
.name = "sha1",
|
||||||
.digest_size = SHA1_SUM_LEN,
|
.digest_size = SHA1_SUM_LEN,
|
||||||
.chunk_size = CHUNKSZ_SHA1,
|
.chunk_size = CHUNKSZ_SHA1,
|
||||||
#ifdef CONFIG_SHA_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA_HW_ACCEL)
|
||||||
.hash_func_ws = hw_sha1,
|
.hash_func_ws = hw_sha1,
|
||||||
#else
|
#else
|
||||||
.hash_func_ws = sha1_csum_wd,
|
.hash_func_ws = sha1_csum_wd,
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA_PROG_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL)
|
||||||
.hash_init = hw_sha_init,
|
.hash_init = hw_sha_init,
|
||||||
.hash_update = hw_sha_update,
|
.hash_update = hw_sha_update,
|
||||||
.hash_finish = hw_sha_finish,
|
.hash_finish = hw_sha_finish,
|
||||||
|
@ -247,17 +240,17 @@ static struct hash_algo hash_algo[] = {
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA256
|
#if CONFIG_IS_ENABLED(SHA256)
|
||||||
{
|
{
|
||||||
.name = "sha256",
|
.name = "sha256",
|
||||||
.digest_size = SHA256_SUM_LEN,
|
.digest_size = SHA256_SUM_LEN,
|
||||||
.chunk_size = CHUNKSZ_SHA256,
|
.chunk_size = CHUNKSZ_SHA256,
|
||||||
#ifdef CONFIG_SHA_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA_HW_ACCEL)
|
||||||
.hash_func_ws = hw_sha256,
|
.hash_func_ws = hw_sha256,
|
||||||
#else
|
#else
|
||||||
.hash_func_ws = sha256_csum_wd,
|
.hash_func_ws = sha256_csum_wd,
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA_PROG_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL)
|
||||||
.hash_init = hw_sha_init,
|
.hash_init = hw_sha_init,
|
||||||
.hash_update = hw_sha_update,
|
.hash_update = hw_sha_update,
|
||||||
.hash_finish = hw_sha_finish,
|
.hash_finish = hw_sha_finish,
|
||||||
|
@ -268,17 +261,17 @@ static struct hash_algo hash_algo[] = {
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA384
|
#if CONFIG_IS_ENABLED(SHA384)
|
||||||
{
|
{
|
||||||
.name = "sha384",
|
.name = "sha384",
|
||||||
.digest_size = SHA384_SUM_LEN,
|
.digest_size = SHA384_SUM_LEN,
|
||||||
.chunk_size = CHUNKSZ_SHA384,
|
.chunk_size = CHUNKSZ_SHA384,
|
||||||
#ifdef CONFIG_SHA512_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL)
|
||||||
.hash_func_ws = hw_sha384,
|
.hash_func_ws = hw_sha384,
|
||||||
#else
|
#else
|
||||||
.hash_func_ws = sha384_csum_wd,
|
.hash_func_ws = sha384_csum_wd,
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_SHA512_HW_ACCEL) && defined(CONFIG_SHA_PROG_HW_ACCEL)
|
#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) && CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL)
|
||||||
.hash_init = hw_sha_init,
|
.hash_init = hw_sha_init,
|
||||||
.hash_update = hw_sha_update,
|
.hash_update = hw_sha_update,
|
||||||
.hash_finish = hw_sha_finish,
|
.hash_finish = hw_sha_finish,
|
||||||
|
@ -289,17 +282,17 @@ static struct hash_algo hash_algo[] = {
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SHA512
|
#if CONFIG_IS_ENABLED(SHA512)
|
||||||
{
|
{
|
||||||
.name = "sha512",
|
.name = "sha512",
|
||||||
.digest_size = SHA512_SUM_LEN,
|
.digest_size = SHA512_SUM_LEN,
|
||||||
.chunk_size = CHUNKSZ_SHA512,
|
.chunk_size = CHUNKSZ_SHA512,
|
||||||
#ifdef CONFIG_SHA512_HW_ACCEL
|
#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL)
|
||||||
.hash_func_ws = hw_sha512,
|
.hash_func_ws = hw_sha512,
|
||||||
#else
|
#else
|
||||||
.hash_func_ws = sha512_csum_wd,
|
.hash_func_ws = sha512_csum_wd,
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_SHA512_HW_ACCEL) && defined(CONFIG_SHA_PROG_HW_ACCEL)
|
#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) && CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL)
|
||||||
.hash_init = hw_sha_init,
|
.hash_init = hw_sha_init,
|
||||||
.hash_update = hw_sha_update,
|
.hash_update = hw_sha_update,
|
||||||
.hash_finish = hw_sha_finish,
|
.hash_finish = hw_sha_finish,
|
||||||
|
@ -319,6 +312,7 @@ static struct hash_algo hash_algo[] = {
|
||||||
.hash_update = hash_update_crc16_ccitt,
|
.hash_update = hash_update_crc16_ccitt,
|
||||||
.hash_finish = hash_finish_crc16_ccitt,
|
.hash_finish = hash_finish_crc16_ccitt,
|
||||||
},
|
},
|
||||||
|
#if CONFIG_IS_ENABLED(CRC32)
|
||||||
{
|
{
|
||||||
.name = "crc32",
|
.name = "crc32",
|
||||||
.digest_size = 4,
|
.digest_size = 4,
|
||||||
|
@ -328,12 +322,13 @@ static struct hash_algo hash_algo[] = {
|
||||||
.hash_update = hash_update_crc32,
|
.hash_update = hash_update_crc32,
|
||||||
.hash_finish = hash_finish_crc32,
|
.hash_finish = hash_finish_crc32,
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Try to minimize code size for boards that don't want much hashing */
|
/* Try to minimize code size for boards that don't want much hashing */
|
||||||
#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) || \
|
#if CONFIG_IS_ENABLED(SHA256) || CONFIG_IS_ENABLED(CMD_SHA1SUM) || \
|
||||||
defined(CONFIG_CRC32_VERIFY) || defined(CONFIG_CMD_HASH) || \
|
CONFIG_IS_ENABLED(CRC32_VERIFY) || CONFIG_IS_ENABLED(CMD_HASH) || \
|
||||||
defined(CONFIG_SHA384) || defined(CONFIG_SHA512)
|
CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512)
|
||||||
#define multi_hash() 1
|
#define multi_hash() 1
|
||||||
#else
|
#else
|
||||||
#define multi_hash() 0
|
#define multi_hash() 0
|
||||||
|
@ -438,7 +433,8 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_HASH) || defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32)
|
#if !defined(CONFIG_SPL_BUILD) && (defined(CONFIG_CMD_HASH) || \
|
||||||
|
defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32))
|
||||||
/**
|
/**
|
||||||
* store_result: Store the resulting sum to an address or variable
|
* store_result: Store the resulting sum to an address or variable
|
||||||
*
|
*
|
||||||
|
|
956
common/image-board.c
Normal file
956
common/image-board.c
Normal file
|
@ -0,0 +1,956 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Image code used by boards (and not host tools)
|
||||||
|
*
|
||||||
|
* (C) Copyright 2008 Semihalf
|
||||||
|
*
|
||||||
|
* (C) Copyright 2000-2006
|
||||||
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <bootstage.h>
|
||||||
|
#include <cpu_func.h>
|
||||||
|
#include <env.h>
|
||||||
|
#include <fpga.h>
|
||||||
|
#include <image.h>
|
||||||
|
#include <mapmem.h>
|
||||||
|
#include <rtc.h>
|
||||||
|
#include <watchdog.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
|
#include <asm/global_data.h>
|
||||||
|
|
||||||
|
#ifndef CONFIG_SYS_BARGSIZE
|
||||||
|
#define CONFIG_SYS_BARGSIZE 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* image_get_ramdisk - get and verify ramdisk image
|
||||||
|
* @rd_addr: ramdisk image start address
|
||||||
|
* @arch: expected ramdisk architecture
|
||||||
|
* @verify: checksum verification flag
|
||||||
|
*
|
||||||
|
* image_get_ramdisk() returns a pointer to the verified ramdisk image
|
||||||
|
* header. Routine receives image start address and expected architecture
|
||||||
|
* flag. Verification done covers data and header integrity and os/type/arch
|
||||||
|
* fields checking.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* pointer to a ramdisk image header, if image was found and valid
|
||||||
|
* otherwise, return NULL
|
||||||
|
*/
|
||||||
|
static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch,
|
||||||
|
int verify)
|
||||||
|
{
|
||||||
|
const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
|
||||||
|
|
||||||
|
if (!image_check_magic(rd_hdr)) {
|
||||||
|
puts("Bad Magic Number\n");
|
||||||
|
bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image_check_hcrc(rd_hdr)) {
|
||||||
|
puts("Bad Header Checksum\n");
|
||||||
|
bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
|
||||||
|
image_print_contents(rd_hdr);
|
||||||
|
|
||||||
|
if (verify) {
|
||||||
|
puts(" Verifying Checksum ... ");
|
||||||
|
if (!image_check_dcrc(rd_hdr)) {
|
||||||
|
puts("Bad Data CRC\n");
|
||||||
|
bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
puts("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
|
||||||
|
|
||||||
|
if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
|
||||||
|
!image_check_arch(rd_hdr, arch) ||
|
||||||
|
!image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
|
||||||
|
printf("No Linux %s Ramdisk Image\n",
|
||||||
|
genimg_get_arch_name(arch));
|
||||||
|
bootstage_error(BOOTSTAGE_ID_RAMDISK);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rd_hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Shared dual-format routines */
|
||||||
|
/*****************************************************************************/
|
||||||
|
ulong image_load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
|
||||||
|
ulong image_save_addr; /* Default Save Address */
|
||||||
|
ulong image_save_size; /* Default Save Size (in bytes) */
|
||||||
|
|
||||||
|
static int on_loadaddr(const char *name, const char *value, enum env_op op,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case env_op_create:
|
||||||
|
case env_op_overwrite:
|
||||||
|
image_load_addr = hextoul(value, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
|
||||||
|
|
||||||
|
ulong env_get_bootm_low(void)
|
||||||
|
{
|
||||||
|
char *s = env_get("bootm_low");
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
ulong tmp = hextoul(s, NULL);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SYS_SDRAM_BASE)
|
||||||
|
return CONFIG_SYS_SDRAM_BASE;
|
||||||
|
#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_RISCV)
|
||||||
|
return gd->bd->bi_dram[0].start;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_size_t env_get_bootm_size(void)
|
||||||
|
{
|
||||||
|
phys_size_t tmp, size;
|
||||||
|
phys_addr_t start;
|
||||||
|
char *s = env_get("bootm_size");
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = gd->ram_base;
|
||||||
|
size = gd->ram_size;
|
||||||
|
|
||||||
|
if (start + size > gd->ram_top)
|
||||||
|
size = gd->ram_top - start;
|
||||||
|
|
||||||
|
s = env_get("bootm_low");
|
||||||
|
if (s)
|
||||||
|
tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
|
||||||
|
else
|
||||||
|
tmp = start;
|
||||||
|
|
||||||
|
return size - (tmp - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_size_t env_get_bootm_mapsize(void)
|
||||||
|
{
|
||||||
|
phys_size_t tmp;
|
||||||
|
char *s = env_get("bootm_mapsize");
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SYS_BOOTMAPSZ)
|
||||||
|
return CONFIG_SYS_BOOTMAPSZ;
|
||||||
|
#else
|
||||||
|
return env_get_bootm_size();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
|
||||||
|
{
|
||||||
|
if (to == from)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||||
|
if (to > from) {
|
||||||
|
from += len;
|
||||||
|
to += len;
|
||||||
|
}
|
||||||
|
while (len > 0) {
|
||||||
|
size_t tail = (len > chunksz) ? chunksz : len;
|
||||||
|
|
||||||
|
WATCHDOG_RESET();
|
||||||
|
if (to > from) {
|
||||||
|
to -= tail;
|
||||||
|
from -= tail;
|
||||||
|
}
|
||||||
|
memmove(to, from, tail);
|
||||||
|
if (to < from) {
|
||||||
|
to += tail;
|
||||||
|
from += tail;
|
||||||
|
}
|
||||||
|
len -= tail;
|
||||||
|
}
|
||||||
|
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
|
||||||
|
memmove(to, from, len);
|
||||||
|
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* genimg_get_kernel_addr_fit - get the real kernel address and return 2
|
||||||
|
* FIT strings
|
||||||
|
* @img_addr: a string might contain real image address
|
||||||
|
* @fit_uname_config: double pointer to a char, will hold pointer to a
|
||||||
|
* configuration unit name
|
||||||
|
* @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
|
||||||
|
* name
|
||||||
|
*
|
||||||
|
* genimg_get_kernel_addr_fit get the real kernel start address from a string
|
||||||
|
* which is normally the first argv of bootm/bootz
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* kernel start address
|
||||||
|
*/
|
||||||
|
ulong genimg_get_kernel_addr_fit(char * const img_addr,
|
||||||
|
const char **fit_uname_config,
|
||||||
|
const char **fit_uname_kernel)
|
||||||
|
{
|
||||||
|
ulong kernel_addr;
|
||||||
|
|
||||||
|
/* find out kernel image address */
|
||||||
|
if (!img_addr) {
|
||||||
|
kernel_addr = image_load_addr;
|
||||||
|
debug("* kernel: default image load address = 0x%08lx\n",
|
||||||
|
image_load_addr);
|
||||||
|
} else if (CONFIG_IS_ENABLED(FIT) &&
|
||||||
|
fit_parse_conf(img_addr, image_load_addr, &kernel_addr,
|
||||||
|
fit_uname_config)) {
|
||||||
|
debug("* kernel: config '%s' from image at 0x%08lx\n",
|
||||||
|
*fit_uname_config, kernel_addr);
|
||||||
|
} else if (CONFIG_IS_ENABLED(FIT) &&
|
||||||
|
fit_parse_subimage(img_addr, image_load_addr, &kernel_addr,
|
||||||
|
fit_uname_kernel)) {
|
||||||
|
debug("* kernel: subimage '%s' from image at 0x%08lx\n",
|
||||||
|
*fit_uname_kernel, kernel_addr);
|
||||||
|
} else {
|
||||||
|
kernel_addr = hextoul(img_addr, NULL);
|
||||||
|
debug("* kernel: cmdline image address = 0x%08lx\n",
|
||||||
|
kernel_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kernel_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* genimg_get_kernel_addr() is the simple version of
|
||||||
|
* genimg_get_kernel_addr_fit(). It ignores those return FIT strings
|
||||||
|
*/
|
||||||
|
ulong genimg_get_kernel_addr(char * const img_addr)
|
||||||
|
{
|
||||||
|
const char *fit_uname_config = NULL;
|
||||||
|
const char *fit_uname_kernel = NULL;
|
||||||
|
|
||||||
|
return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
|
||||||
|
&fit_uname_kernel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* genimg_get_format - get image format type
|
||||||
|
* @img_addr: image start address
|
||||||
|
*
|
||||||
|
* genimg_get_format() checks whether provided address points to a valid
|
||||||
|
* legacy or FIT image.
|
||||||
|
*
|
||||||
|
* New uImage format and FDT blob are based on a libfdt. FDT blob
|
||||||
|
* may be passed directly or embedded in a FIT image. In both situations
|
||||||
|
* genimg_get_format() must be able to dectect libfdt header.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* image format type or IMAGE_FORMAT_INVALID if no image is present
|
||||||
|
*/
|
||||||
|
int genimg_get_format(const void *img_addr)
|
||||||
|
{
|
||||||
|
if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
|
||||||
|
const image_header_t *hdr;
|
||||||
|
|
||||||
|
hdr = (const image_header_t *)img_addr;
|
||||||
|
if (image_check_magic(hdr))
|
||||||
|
return IMAGE_FORMAT_LEGACY;
|
||||||
|
}
|
||||||
|
if (CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)) {
|
||||||
|
if (!fdt_check_header(img_addr))
|
||||||
|
return IMAGE_FORMAT_FIT;
|
||||||
|
}
|
||||||
|
if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) &&
|
||||||
|
!android_image_check_header(img_addr))
|
||||||
|
return IMAGE_FORMAT_ANDROID;
|
||||||
|
|
||||||
|
return IMAGE_FORMAT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fit_has_config - check if there is a valid FIT configuration
|
||||||
|
* @images: pointer to the bootm command headers structure
|
||||||
|
*
|
||||||
|
* fit_has_config() checks if there is a FIT configuration in use
|
||||||
|
* (if FTI support is present).
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0, no FIT support or no configuration found
|
||||||
|
* 1, configuration found
|
||||||
|
*/
|
||||||
|
int genimg_has_config(bootm_headers_t *images)
|
||||||
|
{
|
||||||
|
if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* select_ramdisk() - Select and locate the ramdisk to use
|
||||||
|
*
|
||||||
|
* @images: pointer to the bootm images structure
|
||||||
|
* @select: name of ramdisk to select, or NULL for any
|
||||||
|
* @arch: expected ramdisk architecture
|
||||||
|
* @rd_datap: pointer to a ulong variable, will hold ramdisk pointer
|
||||||
|
* @rd_lenp: pointer to a ulong variable, will hold ramdisk length
|
||||||
|
* @return 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported),
|
||||||
|
* other -ve value on other error
|
||||||
|
*/
|
||||||
|
static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
|
||||||
|
ulong *rd_datap, ulong *rd_lenp)
|
||||||
|
{
|
||||||
|
ulong rd_addr = 0;
|
||||||
|
char *buf;
|
||||||
|
const char *fit_uname_config = images->fit_uname_cfg;
|
||||||
|
const char *fit_uname_ramdisk = NULL;
|
||||||
|
bool processed;
|
||||||
|
int rd_noffset;
|
||||||
|
|
||||||
|
if (select) {
|
||||||
|
ulong default_addr;
|
||||||
|
bool done = true;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(FIT)) {
|
||||||
|
/*
|
||||||
|
* If the init ramdisk comes from the FIT image and
|
||||||
|
* the FIT image address is omitted in the command
|
||||||
|
* line argument, try to use os FIT image address or
|
||||||
|
* default load address.
|
||||||
|
*/
|
||||||
|
if (images->fit_uname_os)
|
||||||
|
default_addr = (ulong)images->fit_hdr_os;
|
||||||
|
else
|
||||||
|
default_addr = image_load_addr;
|
||||||
|
|
||||||
|
if (fit_parse_conf(select, default_addr, &rd_addr,
|
||||||
|
&fit_uname_config)) {
|
||||||
|
debug("* ramdisk: config '%s' from image at 0x%08lx\n",
|
||||||
|
fit_uname_config, rd_addr);
|
||||||
|
} else if (fit_parse_subimage(select, default_addr,
|
||||||
|
&rd_addr,
|
||||||
|
&fit_uname_ramdisk)) {
|
||||||
|
debug("* ramdisk: subimage '%s' from image at 0x%08lx\n",
|
||||||
|
fit_uname_ramdisk, rd_addr);
|
||||||
|
} else {
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!done) {
|
||||||
|
rd_addr = hextoul(select, NULL);
|
||||||
|
debug("* ramdisk: cmdline image address = 0x%08lx\n",
|
||||||
|
rd_addr);
|
||||||
|
}
|
||||||
|
} else if (CONFIG_IS_ENABLED(FIT)) {
|
||||||
|
/* use FIT configuration provided in first bootm
|
||||||
|
* command argument. If the property is not defined,
|
||||||
|
* quit silently (with -ENOPKG )
|
||||||
|
*/
|
||||||
|
rd_addr = map_to_sysmem(images->fit_hdr_os);
|
||||||
|
rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
|
||||||
|
rd_addr);
|
||||||
|
if (rd_noffset == -ENOENT)
|
||||||
|
return -ENOPKG;
|
||||||
|
else if (rd_noffset < 0)
|
||||||
|
return rd_noffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there is an initrd image at the
|
||||||
|
* address provided in the second bootm argument
|
||||||
|
* check image type, for FIT images get FIT node.
|
||||||
|
*/
|
||||||
|
buf = map_sysmem(rd_addr, 0);
|
||||||
|
processed = false;
|
||||||
|
switch (genimg_get_format(buf)) {
|
||||||
|
case IMAGE_FORMAT_LEGACY:
|
||||||
|
if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
|
||||||
|
const image_header_t *rd_hdr;
|
||||||
|
|
||||||
|
printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
|
||||||
|
rd_addr);
|
||||||
|
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
|
||||||
|
rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify);
|
||||||
|
if (!rd_hdr)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
*rd_datap = image_get_data(rd_hdr);
|
||||||
|
*rd_lenp = image_get_data_size(rd_hdr);
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
if (CONFIG_IS_ENABLED(FIT)) {
|
||||||
|
rd_noffset = fit_image_load(images, rd_addr,
|
||||||
|
&fit_uname_ramdisk,
|
||||||
|
&fit_uname_config, arch,
|
||||||
|
IH_TYPE_RAMDISK,
|
||||||
|
BOOTSTAGE_ID_FIT_RD_START,
|
||||||
|
FIT_LOAD_OPTIONAL_NON_ZERO,
|
||||||
|
rd_datap, rd_lenp);
|
||||||
|
if (rd_noffset < 0)
|
||||||
|
return rd_noffset;
|
||||||
|
|
||||||
|
images->fit_hdr_rd = map_sysmem(rd_addr, 0);
|
||||||
|
images->fit_uname_rd = fit_uname_ramdisk;
|
||||||
|
images->fit_noffset_rd = rd_noffset;
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IMAGE_FORMAT_ANDROID:
|
||||||
|
if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
|
||||||
|
android_image_get_ramdisk((void *)images->os.start,
|
||||||
|
rd_datap, rd_lenp);
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processed) {
|
||||||
|
if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
|
||||||
|
char *end = NULL;
|
||||||
|
|
||||||
|
if (select)
|
||||||
|
end = strchr(select, ':');
|
||||||
|
if (end) {
|
||||||
|
*rd_lenp = hextoul(++end, NULL);
|
||||||
|
*rd_datap = rd_addr;
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processed) {
|
||||||
|
puts("Wrong Ramdisk Image Format\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boot_get_ramdisk - main ramdisk handling routine
|
||||||
|
* @argc: command argument count
|
||||||
|
* @argv: command argument list
|
||||||
|
* @images: pointer to the bootm images structure
|
||||||
|
* @arch: expected ramdisk architecture
|
||||||
|
* @rd_start: pointer to a ulong variable, will hold ramdisk start address
|
||||||
|
* @rd_end: pointer to a ulong variable, will hold ramdisk end
|
||||||
|
*
|
||||||
|
* boot_get_ramdisk() is responsible for finding a valid ramdisk image.
|
||||||
|
* Currently supported are the following ramdisk sources:
|
||||||
|
* - multicomponent kernel/ramdisk image,
|
||||||
|
* - commandline provided address of decicated ramdisk image.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0, if ramdisk image was found and valid, or skiped
|
||||||
|
* rd_start and rd_end are set to ramdisk start/end addresses if
|
||||||
|
* ramdisk image is found and valid
|
||||||
|
*
|
||||||
|
* 1, if ramdisk image is found but corrupted, or invalid
|
||||||
|
* rd_start and rd_end are set to 0 if no ramdisk exists
|
||||||
|
*/
|
||||||
|
int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images,
|
||||||
|
u8 arch, ulong *rd_start, ulong *rd_end)
|
||||||
|
{
|
||||||
|
ulong rd_data, rd_len;
|
||||||
|
const char *select = NULL;
|
||||||
|
|
||||||
|
*rd_start = 0;
|
||||||
|
*rd_end = 0;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
/* Look for an Android boot image */
|
||||||
|
buf = map_sysmem(images->os.start, 0);
|
||||||
|
if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
|
||||||
|
select = (argc == 0) ? env_get("loadaddr") : argv[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc >= 2)
|
||||||
|
select = argv[1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for a '-' which indicates to ignore the
|
||||||
|
* ramdisk argument
|
||||||
|
*/
|
||||||
|
if (select && strcmp(select, "-") == 0) {
|
||||||
|
debug("## Skipping init Ramdisk\n");
|
||||||
|
rd_len = 0;
|
||||||
|
rd_data = 0;
|
||||||
|
} else if (select || genimg_has_config(images)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = select_ramdisk(images, select, arch, &rd_data, &rd_len);
|
||||||
|
if (ret == -ENOPKG)
|
||||||
|
return 0;
|
||||||
|
else if (ret)
|
||||||
|
return ret;
|
||||||
|
} else if (images->legacy_hdr_valid &&
|
||||||
|
image_check_type(&images->legacy_hdr_os_copy,
|
||||||
|
IH_TYPE_MULTI)) {
|
||||||
|
/*
|
||||||
|
* Now check if we have a legacy mult-component image,
|
||||||
|
* get second entry data start address and len.
|
||||||
|
*/
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_RAMDISK);
|
||||||
|
printf("## Loading init Ramdisk from multi component Legacy Image at %08lx ...\n",
|
||||||
|
(ulong)images->legacy_hdr_os);
|
||||||
|
|
||||||
|
image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* no initrd image
|
||||||
|
*/
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
|
||||||
|
rd_len = 0;
|
||||||
|
rd_data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rd_data) {
|
||||||
|
debug("## No init Ramdisk\n");
|
||||||
|
} else {
|
||||||
|
*rd_start = rd_data;
|
||||||
|
*rd_end = rd_data + rd_len;
|
||||||
|
}
|
||||||
|
debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
|
||||||
|
*rd_start, *rd_end);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boot_ramdisk_high - relocate init ramdisk
|
||||||
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
|
* @rd_data: ramdisk data start address
|
||||||
|
* @rd_len: ramdisk data length
|
||||||
|
* @initrd_start: pointer to a ulong variable, will hold final init ramdisk
|
||||||
|
* start address (after possible relocation)
|
||||||
|
* @initrd_end: pointer to a ulong variable, will hold final init ramdisk
|
||||||
|
* end address (after possible relocation)
|
||||||
|
*
|
||||||
|
* boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
|
||||||
|
* variable and if requested ramdisk data is moved to a specified location.
|
||||||
|
*
|
||||||
|
* Initrd_start and initrd_end are set to final (after relocation) ramdisk
|
||||||
|
* start/end addresses if ramdisk image start and len were provided,
|
||||||
|
* otherwise set initrd_start and initrd_end set to zeros.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
|
*/
|
||||||
|
int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||||
|
ulong *initrd_start, ulong *initrd_end)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
ulong initrd_high;
|
||||||
|
int initrd_copy_to_ram = 1;
|
||||||
|
|
||||||
|
s = env_get("initrd_high");
|
||||||
|
if (s) {
|
||||||
|
/* a value of "no" or a similar string will act like 0,
|
||||||
|
* turning the "load high" feature off. This is intentional.
|
||||||
|
*/
|
||||||
|
initrd_high = hextoul(s, NULL);
|
||||||
|
if (initrd_high == ~0)
|
||||||
|
initrd_copy_to_ram = 0;
|
||||||
|
} else {
|
||||||
|
initrd_high = env_get_bootm_mapsize() + env_get_bootm_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
|
||||||
|
initrd_high, initrd_copy_to_ram);
|
||||||
|
|
||||||
|
if (rd_data) {
|
||||||
|
if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
|
||||||
|
debug(" in-place initrd\n");
|
||||||
|
*initrd_start = rd_data;
|
||||||
|
*initrd_end = rd_data + rd_len;
|
||||||
|
lmb_reserve(lmb, rd_data, rd_len);
|
||||||
|
} else {
|
||||||
|
if (initrd_high)
|
||||||
|
*initrd_start = (ulong)lmb_alloc_base(lmb,
|
||||||
|
rd_len, 0x1000, initrd_high);
|
||||||
|
else
|
||||||
|
*initrd_start = (ulong)lmb_alloc(lmb, rd_len,
|
||||||
|
0x1000);
|
||||||
|
|
||||||
|
if (*initrd_start == 0) {
|
||||||
|
puts("ramdisk - allocation error\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
|
||||||
|
|
||||||
|
*initrd_end = *initrd_start + rd_len;
|
||||||
|
printf(" Loading Ramdisk to %08lx, end %08lx ... ",
|
||||||
|
*initrd_start, *initrd_end);
|
||||||
|
|
||||||
|
memmove_wd((void *)*initrd_start,
|
||||||
|
(void *)rd_data, rd_len, CHUNKSZ);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure the image is flushed to memory to handle
|
||||||
|
* AMP boot scenarios in which we might not be
|
||||||
|
* HW cache coherent
|
||||||
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_MP)) {
|
||||||
|
flush_cache((unsigned long)*initrd_start,
|
||||||
|
ALIGN(rd_len, ARCH_DMA_MINALIGN));
|
||||||
|
}
|
||||||
|
puts("OK\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*initrd_start = 0;
|
||||||
|
*initrd_end = 0;
|
||||||
|
}
|
||||||
|
debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
|
||||||
|
*initrd_start, *initrd_end);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int boot_get_setup(bootm_headers_t *images, u8 arch,
|
||||||
|
ulong *setup_start, ulong *setup_len)
|
||||||
|
{
|
||||||
|
if (!CONFIG_IS_ENABLED(FIT))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
return boot_get_setup_fit(images, arch, setup_start, setup_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images,
|
||||||
|
u8 arch, const ulong *ld_start, ulong * const ld_len)
|
||||||
|
{
|
||||||
|
ulong tmp_img_addr, img_data, img_len;
|
||||||
|
void *buf;
|
||||||
|
int conf_noffset;
|
||||||
|
int fit_img_result;
|
||||||
|
const char *uname, *name;
|
||||||
|
int err;
|
||||||
|
int devnum = 0; /* TODO support multi fpga platforms */
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_FPGA))
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
/* Check to see if the images struct has a FIT configuration */
|
||||||
|
if (!genimg_has_config(images)) {
|
||||||
|
debug("## FIT configuration was not specified\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the os FIT header from the images struct
|
||||||
|
*/
|
||||||
|
tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
|
||||||
|
buf = map_sysmem(tmp_img_addr, 0);
|
||||||
|
/*
|
||||||
|
* Check image type. For FIT images get FIT node
|
||||||
|
* and attempt to locate a generic binary.
|
||||||
|
*/
|
||||||
|
switch (genimg_get_format(buf)) {
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
|
||||||
|
|
||||||
|
uname = fdt_stringlist_get(buf, conf_noffset, FIT_FPGA_PROP, 0,
|
||||||
|
NULL);
|
||||||
|
if (!uname) {
|
||||||
|
debug("## FPGA image is not specified\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fit_img_result = fit_image_load(images,
|
||||||
|
tmp_img_addr,
|
||||||
|
(const char **)&uname,
|
||||||
|
&images->fit_uname_cfg,
|
||||||
|
arch,
|
||||||
|
IH_TYPE_FPGA,
|
||||||
|
BOOTSTAGE_ID_FPGA_INIT,
|
||||||
|
FIT_LOAD_OPTIONAL_NON_ZERO,
|
||||||
|
&img_data, &img_len);
|
||||||
|
|
||||||
|
debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n",
|
||||||
|
uname, img_data, img_len);
|
||||||
|
|
||||||
|
if (fit_img_result < 0) {
|
||||||
|
/* Something went wrong! */
|
||||||
|
return fit_img_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fpga_is_partial_data(devnum, img_len)) {
|
||||||
|
name = "full";
|
||||||
|
err = fpga_loadbitstream(devnum, (char *)img_data,
|
||||||
|
img_len, BIT_FULL);
|
||||||
|
if (err)
|
||||||
|
err = fpga_load(devnum, (const void *)img_data,
|
||||||
|
img_len, BIT_FULL);
|
||||||
|
} else {
|
||||||
|
name = "partial";
|
||||||
|
err = fpga_loadbitstream(devnum, (char *)img_data,
|
||||||
|
img_len, BIT_PARTIAL);
|
||||||
|
if (err)
|
||||||
|
err = fpga_load(devnum, (const void *)img_data,
|
||||||
|
img_len, BIT_PARTIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
printf(" Programming %s bitstream... OK\n", name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("The given image format is not supported (corrupt?)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fit_loadable_process(u8 img_type,
|
||||||
|
ulong img_data,
|
||||||
|
ulong img_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const unsigned int count =
|
||||||
|
ll_entry_count(struct fit_loadable_tbl, fit_loadable);
|
||||||
|
struct fit_loadable_tbl *fit_loadable_handler =
|
||||||
|
ll_entry_start(struct fit_loadable_tbl, fit_loadable);
|
||||||
|
/* For each loadable handler */
|
||||||
|
for (i = 0; i < count; i++, fit_loadable_handler++)
|
||||||
|
/* matching this type */
|
||||||
|
if (fit_loadable_handler->type == img_type)
|
||||||
|
/* call that handler with this image data */
|
||||||
|
fit_loadable_handler->handler(img_data, img_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
|
||||||
|
u8 arch, const ulong *ld_start, ulong * const ld_len)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* These variables are used to hold the current image location
|
||||||
|
* in system memory.
|
||||||
|
*/
|
||||||
|
ulong tmp_img_addr;
|
||||||
|
/*
|
||||||
|
* These two variables are requirements for fit_image_load, but
|
||||||
|
* their values are not used
|
||||||
|
*/
|
||||||
|
ulong img_data, img_len;
|
||||||
|
void *buf;
|
||||||
|
int loadables_index;
|
||||||
|
int conf_noffset;
|
||||||
|
int fit_img_result;
|
||||||
|
const char *uname;
|
||||||
|
u8 img_type;
|
||||||
|
|
||||||
|
/* Check to see if the images struct has a FIT configuration */
|
||||||
|
if (!genimg_has_config(images)) {
|
||||||
|
debug("## FIT configuration was not specified\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the os FIT header from the images struct
|
||||||
|
*/
|
||||||
|
tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
|
||||||
|
buf = map_sysmem(tmp_img_addr, 0);
|
||||||
|
/*
|
||||||
|
* Check image type. For FIT images get FIT node
|
||||||
|
* and attempt to locate a generic binary.
|
||||||
|
*/
|
||||||
|
switch (genimg_get_format(buf)) {
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
|
||||||
|
|
||||||
|
for (loadables_index = 0;
|
||||||
|
uname = fdt_stringlist_get(buf, conf_noffset,
|
||||||
|
FIT_LOADABLE_PROP,
|
||||||
|
loadables_index, NULL), uname;
|
||||||
|
loadables_index++) {
|
||||||
|
fit_img_result = fit_image_load(images, tmp_img_addr,
|
||||||
|
&uname,
|
||||||
|
&images->fit_uname_cfg,
|
||||||
|
arch, IH_TYPE_LOADABLE,
|
||||||
|
BOOTSTAGE_ID_FIT_LOADABLE_START,
|
||||||
|
FIT_LOAD_OPTIONAL_NON_ZERO,
|
||||||
|
&img_data, &img_len);
|
||||||
|
if (fit_img_result < 0) {
|
||||||
|
/* Something went wrong! */
|
||||||
|
return fit_img_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fit_img_result = fit_image_get_node(buf, uname);
|
||||||
|
if (fit_img_result < 0) {
|
||||||
|
/* Something went wrong! */
|
||||||
|
return fit_img_result;
|
||||||
|
}
|
||||||
|
fit_img_result = fit_image_get_type(buf,
|
||||||
|
fit_img_result,
|
||||||
|
&img_type);
|
||||||
|
if (fit_img_result < 0) {
|
||||||
|
/* Something went wrong! */
|
||||||
|
return fit_img_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fit_loadable_process(img_type, img_data, img_len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("The given image format is not supported (corrupt?)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boot_get_cmdline - allocate and initialize kernel cmdline
|
||||||
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
|
* @cmd_start: pointer to a ulong variable, will hold cmdline start
|
||||||
|
* @cmd_end: pointer to a ulong variable, will hold cmdline end
|
||||||
|
*
|
||||||
|
* boot_get_cmdline() allocates space for kernel command line below
|
||||||
|
* BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment
|
||||||
|
* variable is present its contents is copied to allocated kernel
|
||||||
|
* command line.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
|
*/
|
||||||
|
int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
|
||||||
|
{
|
||||||
|
char *cmdline;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
|
||||||
|
env_get_bootm_mapsize() + env_get_bootm_low());
|
||||||
|
if (!cmdline)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
s = env_get("bootargs");
|
||||||
|
if (!s)
|
||||||
|
s = "";
|
||||||
|
|
||||||
|
strcpy(cmdline, s);
|
||||||
|
|
||||||
|
*cmd_start = (ulong)cmdline;
|
||||||
|
*cmd_end = *cmd_start + strlen(cmdline);
|
||||||
|
|
||||||
|
debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boot_get_kbd - allocate and initialize kernel copy of board info
|
||||||
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
|
* @kbd: double pointer to board info data
|
||||||
|
*
|
||||||
|
* boot_get_kbd() allocates space for kernel copy of board info data below
|
||||||
|
* BOOTMAPSZ + env_get_bootm_low() address and kernel board info is initialized
|
||||||
|
* with the current u-boot board info data.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
|
*/
|
||||||
|
int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd)
|
||||||
|
{
|
||||||
|
*kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb,
|
||||||
|
sizeof(struct bd_info),
|
||||||
|
0xf,
|
||||||
|
env_get_bootm_mapsize() +
|
||||||
|
env_get_bootm_low());
|
||||||
|
if (!*kbd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
**kbd = *gd->bd;
|
||||||
|
|
||||||
|
debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
if (IS_ENABLED(CONFIG_CMD_BDI)
|
||||||
|
do_bdinfo(NULL, 0, 0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_setup_linux(bootm_headers_t *images)
|
||||||
|
{
|
||||||
|
ulong of_size = images->ft_len;
|
||||||
|
char **of_flat_tree = &images->ft_addr;
|
||||||
|
struct lmb *lmb = &images->lmb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(OF_LIBFDT))
|
||||||
|
boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
|
||||||
|
ret = boot_get_cmdline(lmb, &images->cmdline_start,
|
||||||
|
&images->cmdline_end);
|
||||||
|
if (ret) {
|
||||||
|
puts("ERROR with allocation of cmdline\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(OF_LIBFDT)) {
|
||||||
|
ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) {
|
||||||
|
ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void genimg_print_size(uint32_t size)
|
||||||
|
{
|
||||||
|
printf("%d Bytes = ", size);
|
||||||
|
print_size(size, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void genimg_print_time(time_t timestamp)
|
||||||
|
{
|
||||||
|
struct rtc_time tm;
|
||||||
|
|
||||||
|
rtc_to_tm(timestamp, &tm);
|
||||||
|
printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n",
|
||||||
|
tm.tm_year, tm.tm_mon, tm.tm_mday,
|
||||||
|
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||||
|
}
|
|
@ -252,59 +252,29 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* boot_get_fdt - main fdt handling routine
|
* select_fdt() - Select and locate the FDT to use
|
||||||
* @argc: command argument count
|
*
|
||||||
* @argv: command argument list
|
|
||||||
* @arch: architecture (IH_ARCH_...)
|
|
||||||
* @images: pointer to the bootm images structure
|
* @images: pointer to the bootm images structure
|
||||||
* @of_flat_tree: pointer to a char* variable, will hold fdt start address
|
* @select: name of FDT to select, or NULL for any
|
||||||
* @of_size: pointer to a ulong variable, will hold fdt length
|
* @arch: expected FDT architecture
|
||||||
*
|
* @fdt_addrp: pointer to a ulong variable, will hold FDT pointer
|
||||||
* boot_get_fdt() is responsible for finding a valid flat device tree image.
|
* @return 0 if OK, -ENOPKG if no FDT (but an error should not be reported),
|
||||||
* Curently supported are the following ramdisk sources:
|
* other -ve value on other error
|
||||||
* - multicomponent kernel/ramdisk image,
|
|
||||||
* - commandline provided address of decicated ramdisk image.
|
|
||||||
*
|
|
||||||
* returns:
|
|
||||||
* 0, if fdt image was found and valid, or skipped
|
|
||||||
* of_flat_tree and of_size are set to fdt start address and length if
|
|
||||||
* fdt image is found and valid
|
|
||||||
*
|
|
||||||
* 1, if fdt image is found but corrupted
|
|
||||||
* of_flat_tree and of_size are set to 0 if no fdt exists
|
|
||||||
*/
|
*/
|
||||||
int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
|
||||||
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
|
static int select_fdt(bootm_headers_t *images, const char *select, u8 arch,
|
||||||
|
ulong *fdt_addrp)
|
||||||
{
|
{
|
||||||
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
|
const char *buf;
|
||||||
const image_header_t *fdt_hdr;
|
ulong fdt_addr;
|
||||||
ulong load, load_end;
|
|
||||||
ulong image_start, image_data, image_end;
|
|
||||||
#endif
|
|
||||||
ulong img_addr;
|
|
||||||
ulong fdt_addr;
|
|
||||||
char *fdt_blob = NULL;
|
|
||||||
void *buf;
|
|
||||||
#if CONFIG_IS_ENABLED(FIT)
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
const char *fit_uname_config = images->fit_uname_cfg;
|
const char *fit_uname_config = images->fit_uname_cfg;
|
||||||
const char *fit_uname_fdt = NULL;
|
const char *fit_uname_fdt = NULL;
|
||||||
ulong default_addr;
|
ulong default_addr;
|
||||||
int fdt_noffset;
|
int fdt_noffset;
|
||||||
#endif
|
|
||||||
const char *select = NULL;
|
|
||||||
|
|
||||||
*of_flat_tree = NULL;
|
if (select) {
|
||||||
*of_size = 0;
|
|
||||||
|
|
||||||
img_addr = (argc == 0) ? image_load_addr :
|
|
||||||
hextoul(argv[0], NULL);
|
|
||||||
buf = map_sysmem(img_addr, 0);
|
|
||||||
|
|
||||||
if (argc > 2)
|
|
||||||
select = argv[2];
|
|
||||||
if (select || genimg_has_config(images)) {
|
|
||||||
#if CONFIG_IS_ENABLED(FIT)
|
|
||||||
if (select) {
|
|
||||||
/*
|
/*
|
||||||
* If the FDT blob comes from the FIT image and the
|
* If the FDT blob comes from the FIT image and the
|
||||||
* FIT image address is omitted in the command line
|
* FIT image address is omitted in the command line
|
||||||
|
@ -318,54 +288,57 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
else
|
else
|
||||||
default_addr = image_load_addr;
|
default_addr = image_load_addr;
|
||||||
|
|
||||||
if (fit_parse_conf(select, default_addr,
|
if (fit_parse_conf(select, default_addr, &fdt_addr,
|
||||||
&fdt_addr, &fit_uname_config)) {
|
&fit_uname_config)) {
|
||||||
debug("* fdt: config '%s' from image at 0x%08lx\n",
|
debug("* fdt: config '%s' from image at 0x%08lx\n",
|
||||||
fit_uname_config, fdt_addr);
|
fit_uname_config, fdt_addr);
|
||||||
} else if (fit_parse_subimage(select, default_addr,
|
} else if (fit_parse_subimage(select, default_addr, &fdt_addr,
|
||||||
&fdt_addr, &fit_uname_fdt)) {
|
&fit_uname_fdt)) {
|
||||||
debug("* fdt: subimage '%s' from image at 0x%08lx\n",
|
debug("* fdt: subimage '%s' from image at 0x%08lx\n",
|
||||||
fit_uname_fdt, fdt_addr);
|
fit_uname_fdt, fdt_addr);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
fdt_addr = hextoul(select, NULL);
|
fdt_addr = hextoul(select, NULL);
|
||||||
debug("* fdt: cmdline image address = 0x%08lx\n",
|
debug("* fdt: cmdline image address = 0x%08lx\n",
|
||||||
fdt_addr);
|
fdt_addr);
|
||||||
}
|
|
||||||
#if CONFIG_IS_ENABLED(FIT)
|
|
||||||
} else {
|
|
||||||
/* use FIT configuration provided in first bootm
|
|
||||||
* command argument
|
|
||||||
*/
|
|
||||||
fdt_addr = map_to_sysmem(images->fit_hdr_os);
|
|
||||||
fdt_noffset = fit_get_node_from_config(images,
|
|
||||||
FIT_FDT_PROP,
|
|
||||||
fdt_addr);
|
|
||||||
if (fdt_noffset == -ENOENT)
|
|
||||||
return 0;
|
|
||||||
else if (fdt_noffset < 0)
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
|
} else {
|
||||||
fdt_addr);
|
/* use FIT configuration provided in first bootm
|
||||||
|
* command argument
|
||||||
/*
|
|
||||||
* Check if there is an FDT image at the
|
|
||||||
* address provided in the second bootm argument
|
|
||||||
* check image type, for FIT images get a FIT node.
|
|
||||||
*/
|
*/
|
||||||
buf = map_sysmem(fdt_addr, 0);
|
fdt_addr = map_to_sysmem(images->fit_hdr_os);
|
||||||
switch (genimg_get_format(buf)) {
|
fdt_noffset = fit_get_node_from_config(images, FIT_FDT_PROP,
|
||||||
|
fdt_addr);
|
||||||
|
if (fdt_noffset == -ENOENT)
|
||||||
|
return -ENOPKG;
|
||||||
|
else if (fdt_noffset < 0)
|
||||||
|
return fdt_noffset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
|
||||||
|
fdt_addr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there is an FDT image at the
|
||||||
|
* address provided in the second bootm argument
|
||||||
|
* check image type, for FIT images get a FIT node.
|
||||||
|
*/
|
||||||
|
buf = map_sysmem(fdt_addr, 0);
|
||||||
|
switch (genimg_get_format(buf)) {
|
||||||
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
|
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
|
||||||
case IMAGE_FORMAT_LEGACY:
|
case IMAGE_FORMAT_LEGACY: {
|
||||||
|
const image_header_t *fdt_hdr;
|
||||||
|
ulong load, load_end;
|
||||||
|
ulong image_start, image_data, image_end;
|
||||||
|
|
||||||
/* verify fdt_addr points to a valid image header */
|
/* verify fdt_addr points to a valid image header */
|
||||||
printf("## Flattened Device Tree from 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)
|
||||||
goto no_fdt;
|
return -ENOPKG;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* move image data to the load address,
|
* move image data to the load address,
|
||||||
|
@ -386,7 +359,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
|
|
||||||
if ((load < image_end) && (load_end > image_start)) {
|
if ((load < image_end) && (load_end > image_start)) {
|
||||||
fdt_error("fdt overwritten");
|
fdt_error("fdt overwritten");
|
||||||
goto error;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(" Loading FDT from 0x%08lx to 0x%08lx\n",
|
debug(" Loading FDT from 0x%08lx to 0x%08lx\n",
|
||||||
|
@ -398,25 +371,26 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
|
|
||||||
fdt_addr = load;
|
fdt_addr = load;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case IMAGE_FORMAT_FIT:
|
case IMAGE_FORMAT_FIT:
|
||||||
/*
|
/*
|
||||||
* This case will catch both: new uImage format
|
* This case will catch both: new uImage format
|
||||||
* (libfdt based) and raw FDT blob (also libfdt
|
* (libfdt based) and raw FDT blob (also libfdt
|
||||||
* based).
|
* based).
|
||||||
*/
|
*/
|
||||||
#if CONFIG_IS_ENABLED(FIT)
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
/* check FDT blob vs FIT blob */
|
/* check FDT blob vs FIT blob */
|
||||||
if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
|
if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
|
||||||
ulong load, len;
|
ulong load, len;
|
||||||
|
|
||||||
fdt_noffset = boot_get_fdt_fit(images,
|
fdt_noffset = boot_get_fdt_fit(images, fdt_addr,
|
||||||
fdt_addr, &fit_uname_fdt,
|
&fit_uname_fdt,
|
||||||
&fit_uname_config,
|
&fit_uname_config,
|
||||||
arch, &load, &len);
|
arch, &load, &len);
|
||||||
|
|
||||||
if (fdt_noffset < 0)
|
if (fdt_noffset < 0)
|
||||||
goto error;
|
return -ENOENT;
|
||||||
|
|
||||||
images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
|
images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
|
||||||
images->fit_uname_fdt = fit_uname_fdt;
|
images->fit_uname_fdt = fit_uname_fdt;
|
||||||
|
@ -424,22 +398,73 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
fdt_addr = load;
|
fdt_addr = load;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FDT blob
|
* FDT blob
|
||||||
*/
|
*/
|
||||||
debug("* fdt: raw FDT blob\n");
|
debug("* fdt: raw FDT blob\n");
|
||||||
printf("## Flattened Device Tree blob at %08lx\n",
|
printf("## Flattened Device Tree blob at %08lx\n",
|
||||||
(long)fdt_addr);
|
(long)fdt_addr);
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
*fdt_addrp = fdt_addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boot_get_fdt - main fdt handling routine
|
||||||
|
* @argc: command argument count
|
||||||
|
* @argv: command argument list
|
||||||
|
* @arch: architecture (IH_ARCH_...)
|
||||||
|
* @images: pointer to the bootm images structure
|
||||||
|
* @of_flat_tree: pointer to a char* variable, will hold fdt start address
|
||||||
|
* @of_size: pointer to a ulong variable, will hold fdt length
|
||||||
|
*
|
||||||
|
* boot_get_fdt() is responsible for finding a valid flat device tree image.
|
||||||
|
* Currently supported are the following ramdisk sources:
|
||||||
|
* - multicomponent kernel/ramdisk image,
|
||||||
|
* - commandline provided address of decicated ramdisk image.
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* 0, if fdt image was found and valid, or skipped
|
||||||
|
* of_flat_tree and of_size are set to fdt start address and length if
|
||||||
|
* fdt image is found and valid
|
||||||
|
*
|
||||||
|
* 1, if fdt image is found but corrupted
|
||||||
|
* of_flat_tree and of_size are set to 0 if no fdt exists
|
||||||
|
*/
|
||||||
|
int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
|
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
|
||||||
|
{
|
||||||
|
ulong img_addr;
|
||||||
|
ulong fdt_addr;
|
||||||
|
char *fdt_blob = NULL;
|
||||||
|
void *buf;
|
||||||
|
const char *select = NULL;
|
||||||
|
|
||||||
|
*of_flat_tree = NULL;
|
||||||
|
*of_size = 0;
|
||||||
|
|
||||||
|
img_addr = (argc == 0) ? image_load_addr : hextoul(argv[0], NULL);
|
||||||
|
buf = map_sysmem(img_addr, 0);
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
select = argv[2];
|
||||||
|
if (select || genimg_has_config(images)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = select_fdt(images, select, arch, &fdt_addr);
|
||||||
|
if (ret == -ENOPKG)
|
||||||
|
goto no_fdt;
|
||||||
|
else if (ret)
|
||||||
|
return 1;
|
||||||
printf(" Booting using the fdt blob at %#08lx\n", fdt_addr);
|
printf(" Booting using the fdt blob at %#08lx\n", fdt_addr);
|
||||||
fdt_blob = map_sysmem(fdt_addr, 0);
|
fdt_blob = map_sysmem(fdt_addr, 0);
|
||||||
} else if (images->legacy_hdr_valid &&
|
} else if (images->legacy_hdr_valid &&
|
||||||
|
@ -582,7 +607,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
|
||||||
/* Append PStore configuration */
|
/* Append PStore configuration */
|
||||||
fdt_fixup_pstore(blob);
|
fdt_fixup_pstore(blob);
|
||||||
#endif
|
#endif
|
||||||
if (IMAGE_OF_BOARD_SETUP) {
|
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {
|
||||||
const char *skip_board_fixup;
|
const char *skip_board_fixup;
|
||||||
|
|
||||||
skip_board_fixup = env_get("skip_board_fixup");
|
skip_board_fixup = env_get("skip_board_fixup");
|
||||||
|
@ -597,7 +622,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IMAGE_OF_SYSTEM_SETUP) {
|
if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {
|
||||||
fdt_ret = ft_system_setup(blob, gd->bd);
|
fdt_ret = ft_system_setup(blob, gd->bd);
|
||||||
if (fdt_ret) {
|
if (fdt_ret) {
|
||||||
printf("ERROR: system-specific fdt fixup failed: %s\n",
|
printf("ERROR: system-specific fdt fixup failed: %s\n",
|
||||||
|
@ -629,7 +654,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_KEYSTONE)
|
#if defined(CONFIG_ARCH_KEYSTONE)
|
||||||
if (IMAGE_OF_BOARD_SETUP)
|
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
|
||||||
ft_board_setup_ex(blob, gd->bd);
|
ft_board_setup_ex(blob, gd->bd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,8 @@ struct image_region *fit_region_make_list(const void *fit,
|
||||||
* Use malloc() except in SPL (to save code size). In SPL the caller
|
* Use malloc() except in SPL (to save code size). In SPL the caller
|
||||||
* must allocate the array.
|
* must allocate the array.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_SPL_BUILD
|
if (!IS_ENABLED(CONFIG_SPL_BUILD) && !region)
|
||||||
if (!region)
|
|
||||||
region = calloc(sizeof(*region), count);
|
region = calloc(sizeof(*region), count);
|
||||||
#endif
|
|
||||||
if (!region)
|
if (!region)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -72,11 +70,10 @@ static int fit_image_setup_verify(struct image_sign_info *info,
|
||||||
char *algo_name;
|
char *algo_name;
|
||||||
const char *padding_name;
|
const char *padding_name;
|
||||||
|
|
||||||
if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
|
if (fdt_totalsize(fit) > CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE)) {
|
||||||
*err_msgp = "Total size too large";
|
*err_msgp = "Total size too large";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
|
if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
|
||||||
*err_msgp = "Can't get hash algo property";
|
*err_msgp = "Can't get hash algo property";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -170,7 +170,6 @@ int fit_get_subimage_count(const void *fit, int images_noffset)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(FIT_PRINT) || CONFIG_IS_ENABLED(SPL_FIT_PRINT)
|
|
||||||
/**
|
/**
|
||||||
* fit_image_print_data() - prints out the hash node details
|
* fit_image_print_data() - prints out the hash node details
|
||||||
* @fit: pointer to the FIT format image header
|
* @fit: pointer to the FIT format image header
|
||||||
|
@ -380,6 +379,9 @@ void fit_print_contents(const void *fit)
|
||||||
const char *p;
|
const char *p;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(FIT_PRINT))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Indent string is defined in header image.h */
|
/* Indent string is defined in header image.h */
|
||||||
p = IMAGE_INDENT_STRING;
|
p = IMAGE_INDENT_STRING;
|
||||||
|
|
||||||
|
@ -482,6 +484,9 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
|
||||||
int ndepth;
|
int ndepth;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(FIT_PRINT))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Mandatory properties */
|
/* Mandatory properties */
|
||||||
ret = fit_get_desc(fit, image_noffset, &desc);
|
ret = fit_get_desc(fit, image_noffset, &desc);
|
||||||
printf("%s Description: ", p);
|
printf("%s Description: ", p);
|
||||||
|
@ -509,7 +514,7 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
|
||||||
|
|
||||||
ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
|
ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
|
||||||
|
|
||||||
if (!host_build()) {
|
if (!tools_build()) {
|
||||||
printf("%s Data Start: ", p);
|
printf("%s Data Start: ", p);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("unavailable\n");
|
printf("unavailable\n");
|
||||||
|
@ -575,10 +580,6 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void fit_print_contents(const void *fit) { }
|
|
||||||
void fit_image_print(const void *fit, int image_noffset, const char *p) { }
|
|
||||||
#endif /* CONFIG_IS_ENABLED(FIR_PRINT) || CONFIG_IS_ENABLED(SPL_FIT_PRINT) */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fit_get_desc - get node description property
|
* fit_get_desc - get node description property
|
||||||
|
@ -1277,7 +1278,7 @@ static int fit_image_check_hash(const void *fit, int noffset, const void *data,
|
||||||
}
|
}
|
||||||
printf("%s", algo);
|
printf("%s", algo);
|
||||||
|
|
||||||
if (IMAGE_ENABLE_IGNORE) {
|
if (!tools_build()) {
|
||||||
fit_image_hash_get_ignore(fit, noffset, &ignore);
|
fit_image_hash_get_ignore(fit, noffset, &ignore);
|
||||||
if (ignore) {
|
if (ignore) {
|
||||||
printf("-skipped ");
|
printf("-skipped ");
|
||||||
|
@ -1845,7 +1846,7 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
|
||||||
if (conf_uname == NULL) {
|
if (conf_uname == NULL) {
|
||||||
/* get configuration unit name from the default property */
|
/* get configuration unit name from the default property */
|
||||||
debug("No configuration specified, trying default...\n");
|
debug("No configuration specified, trying default...\n");
|
||||||
if (!host_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
|
if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
|
||||||
noffset = fit_find_config_node(fit);
|
noffset = fit_find_config_node(fit);
|
||||||
if (noffset < 0)
|
if (noffset < 0)
|
||||||
return noffset;
|
return noffset;
|
||||||
|
@ -2008,9 +2009,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
||||||
int type_ok, os_ok;
|
int type_ok, os_ok;
|
||||||
ulong load, load_end, data, len;
|
ulong load, load_end, data, len;
|
||||||
uint8_t os, comp;
|
uint8_t os, comp;
|
||||||
#ifndef USE_HOSTCC
|
|
||||||
uint8_t os_arch;
|
|
||||||
#endif
|
|
||||||
const char *prop_name;
|
const char *prop_name;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -2093,7 +2091,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
||||||
if (!host_build() && IS_ENABLED(CONFIG_SANDBOX)) {
|
if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
|
||||||
if (!fit_image_check_target_arch(fit, noffset)) {
|
if (!fit_image_check_target_arch(fit, noffset)) {
|
||||||
puts("Unsupported Architecture\n");
|
puts("Unsupported Architecture\n");
|
||||||
bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
||||||
|
@ -2102,8 +2100,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_HOSTCC
|
#ifndef USE_HOSTCC
|
||||||
|
{
|
||||||
|
uint8_t os_arch;
|
||||||
|
|
||||||
fit_image_get_arch(fit, noffset, &os_arch);
|
fit_image_get_arch(fit, noffset, &os_arch);
|
||||||
images->os.arch = os_arch;
|
images->os.arch = os_arch;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
|
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
|
||||||
|
@ -2158,7 +2160,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform any post-processing on the image data */
|
/* perform any post-processing on the image data */
|
||||||
if (!host_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
|
if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
|
||||||
board_fit_image_post_process(fit, noffset, &buf, &size);
|
board_fit_image_post_process(fit, noffset, &buf, &size);
|
||||||
|
|
||||||
len = (ulong)size;
|
len = (ulong)size;
|
||||||
|
|
27
common/image-host.c
Normal file
27
common/image-host.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Image code used by host tools (and not boards)
|
||||||
|
*
|
||||||
|
* (C) Copyright 2008 Semihalf
|
||||||
|
*
|
||||||
|
* (C) Copyright 2000-2006
|
||||||
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
|
||||||
|
{
|
||||||
|
memmove(to, from, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void genimg_print_size(uint32_t size)
|
||||||
|
{
|
||||||
|
printf("%d Bytes = %.2f KiB = %.2f MiB\n", size, (double)size / 1.024e3,
|
||||||
|
(double)size / 1.048576e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void genimg_print_time(time_t timestamp)
|
||||||
|
{
|
||||||
|
printf("%s", ctime(×tamp));
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <relocate.h>
|
||||||
#include <u-boot/ecdsa.h>
|
#include <u-boot/ecdsa.h>
|
||||||
#include <u-boot/rsa.h>
|
#include <u-boot/rsa.h>
|
||||||
#include <u-boot/hash-checksum.h>
|
#include <u-boot/hash-checksum.h>
|
||||||
|
@ -56,17 +57,19 @@ struct checksum_algo *image_get_checksum_algo(const char *full_name)
|
||||||
int i;
|
int i;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
|
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
|
||||||
static bool done;
|
static bool done;
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
done = true;
|
done = true;
|
||||||
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
|
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
|
||||||
checksum_algos[i].name += gd->reloc_off;
|
struct checksum_algo *algo = &checksum_algos[i];
|
||||||
checksum_algos[i].calculate += gd->reloc_off;
|
|
||||||
|
MANUAL_RELOC(algo->name);
|
||||||
|
MANUAL_RELOC(algo->calculate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
|
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
|
||||||
name = checksum_algos[i].name;
|
name = checksum_algos[i].name;
|
||||||
|
@ -84,18 +87,19 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name)
|
||||||
struct crypto_algo *crypto, *end;
|
struct crypto_algo *crypto, *end;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
|
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
|
||||||
static bool done;
|
static bool done;
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
crypto = ll_entry_start(struct crypto_algo, cryptos);
|
done = true;
|
||||||
end = ll_entry_end(struct crypto_algo, cryptos);
|
crypto = ll_entry_start(struct crypto_algo, cryptos);
|
||||||
for (; crypto < end; crypto++) {
|
end = ll_entry_end(struct crypto_algo, cryptos);
|
||||||
crypto->name += gd->reloc_off;
|
for (; crypto < end; crypto++) {
|
||||||
crypto->verify += gd->reloc_off;
|
MANUAL_RELOC(crypto->name);
|
||||||
|
MANUAL_RELOC(crypto->verify);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Move name to after the comma */
|
/* Move name to after the comma */
|
||||||
name = strchr(full_name, ',');
|
name = strchr(full_name, ',');
|
||||||
|
|
1181
common/image.c
1181
common/image.c
File diff suppressed because it is too large
Load diff
|
@ -419,7 +419,8 @@ config SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
|
||||||
|
|
||||||
config SPL_CRC32
|
config SPL_CRC32
|
||||||
bool "Support CRC32"
|
bool "Support CRC32"
|
||||||
default y if SPL_LEGACY_IMAGE_SUPPORT
|
default y if SPL_LEGACY_IMAGE_SUPPORT || SPL_EFI_PARTITION
|
||||||
|
default y if SPL_ENV_SUPPORT || TPL_BLOBLIST
|
||||||
help
|
help
|
||||||
Enable this to support CRC32 in uImages or FIT images within SPL.
|
Enable this to support CRC32 in uImages or FIT images within SPL.
|
||||||
This is a 32-bit checksum value that can be used to verify images.
|
This is a 32-bit checksum value that can be used to verify images.
|
||||||
|
@ -1419,6 +1420,16 @@ config TPL_BOOTROM_SUPPORT
|
||||||
BOOT_DEVICE_BOOTROM (or fall-through to the next boot device in the
|
BOOT_DEVICE_BOOTROM (or fall-through to the next boot device in the
|
||||||
boot device list, if not implemented for a given board)
|
boot device list, if not implemented for a given board)
|
||||||
|
|
||||||
|
config TPL_CRC32
|
||||||
|
bool "Support CRC32 in TPL"
|
||||||
|
default y if TPL_ENV_SUPPORT || TPL_BLOBLIST
|
||||||
|
help
|
||||||
|
Enable this to support CRC32 in uImages or FIT images within SPL.
|
||||||
|
This is a 32-bit checksum value that can be used to verify images.
|
||||||
|
For FIT images, this is the least secure type of checksum, suitable
|
||||||
|
for detected accidental image corruption. For secure applications you
|
||||||
|
should consider SHA1 or SHA256.
|
||||||
|
|
||||||
config TPL_DRIVERS_MISC
|
config TPL_DRIVERS_MISC
|
||||||
bool "Support misc drivers in TPL"
|
bool "Support misc drivers in TPL"
|
||||||
help
|
help
|
||||||
|
|
|
@ -56,6 +56,7 @@ CONFIG_CMD_MEMINFO=y
|
||||||
CONFIG_CMD_MEM_SEARCH=y
|
CONFIG_CMD_MEM_SEARCH=y
|
||||||
CONFIG_CMD_MX_CYCLIC=y
|
CONFIG_CMD_MX_CYCLIC=y
|
||||||
CONFIG_CMD_MEMTEST=y
|
CONFIG_CMD_MEMTEST=y
|
||||||
|
CONFIG_CMD_UNZIP=y
|
||||||
CONFIG_CMD_BIND=y
|
CONFIG_CMD_BIND=y
|
||||||
CONFIG_CMD_DEMO=y
|
CONFIG_CMD_DEMO=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "btrfs.h"
|
#include "btrfs.h"
|
||||||
|
#include <abuf.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <linux/lzo.h>
|
#include <linux/lzo.h>
|
||||||
|
@ -136,54 +137,12 @@ static u32 decompress_zlib(const u8 *_cbuf, u32 clen, u8 *dbuf, u32 dlen)
|
||||||
|
|
||||||
static u32 decompress_zstd(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
|
static u32 decompress_zstd(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
|
||||||
{
|
{
|
||||||
ZSTD_DStream *dstream;
|
struct abuf in, out;
|
||||||
ZSTD_inBuffer in_buf;
|
|
||||||
ZSTD_outBuffer out_buf;
|
|
||||||
void *workspace;
|
|
||||||
size_t wsize;
|
|
||||||
u32 res = -1;
|
|
||||||
|
|
||||||
wsize = ZSTD_DStreamWorkspaceBound(ZSTD_BTRFS_MAX_INPUT);
|
abuf_init_set(&in, (u8 *)cbuf, clen);
|
||||||
workspace = malloc(wsize);
|
abuf_init_set(&out, dbuf, dlen);
|
||||||
if (!workspace) {
|
|
||||||
debug("%s: cannot allocate workspace of size %zu\n", __func__,
|
|
||||||
wsize);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dstream = ZSTD_initDStream(ZSTD_BTRFS_MAX_INPUT, workspace, wsize);
|
return zstd_decompress(&in, &out);
|
||||||
if (!dstream) {
|
|
||||||
printf("%s: ZSTD_initDStream failed\n", __func__);
|
|
||||||
goto err_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_buf.src = cbuf;
|
|
||||||
in_buf.pos = 0;
|
|
||||||
in_buf.size = clen;
|
|
||||||
|
|
||||||
out_buf.dst = dbuf;
|
|
||||||
out_buf.pos = 0;
|
|
||||||
out_buf.size = dlen;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
size_t ret;
|
|
||||||
|
|
||||||
ret = ZSTD_decompressStream(dstream, &out_buf, &in_buf);
|
|
||||||
if (ZSTD_isError(ret)) {
|
|
||||||
printf("%s: ZSTD_decompressStream error %d\n", __func__,
|
|
||||||
ZSTD_getErrorCode(ret));
|
|
||||||
goto err_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_buf.pos >= clen || !ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = out_buf.pos;
|
|
||||||
|
|
||||||
err_free:
|
|
||||||
free(workspace);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 btrfs_decompress(u8 type, const char *c, u32 clen, char *d, u32 dlen)
|
u32 btrfs_decompress(u8 type, const char *c, u32 clen, char *d, u32 dlen)
|
||||||
|
|
159
include/abuf.h
Normal file
159
include/abuf.h
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* Handles a buffer that can be allocated and freed
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ABUF_H
|
||||||
|
#define __ABUF_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct abuf - buffer that can be allocated and freed
|
||||||
|
*
|
||||||
|
* This is useful for a block of data which may be allocated with malloc(), or
|
||||||
|
* not, so that it needs to be freed correctly when finished with.
|
||||||
|
*
|
||||||
|
* For now it has a very simple purpose.
|
||||||
|
*
|
||||||
|
* Using memset() to zero all fields is guaranteed to be equivalent to
|
||||||
|
* abuf_init().
|
||||||
|
*
|
||||||
|
* @data: Pointer to data
|
||||||
|
* @size: Size of data in bytes
|
||||||
|
* @alloced: true if allocated with malloc(), so must be freed after use
|
||||||
|
*/
|
||||||
|
struct abuf {
|
||||||
|
void *data;
|
||||||
|
size_t size;
|
||||||
|
bool alloced;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void *abuf_data(const struct abuf *abuf)
|
||||||
|
{
|
||||||
|
return abuf->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t abuf_size(const struct abuf *abuf)
|
||||||
|
{
|
||||||
|
return abuf->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_set() - set the (unallocated) data in a buffer
|
||||||
|
*
|
||||||
|
* This simply makes the abuf point to the supplied data, which must be live
|
||||||
|
* for the lifetime of the abuf. It is not alloced.
|
||||||
|
*
|
||||||
|
* Any existing data in the abuf is freed and the alloced member is set to
|
||||||
|
* false.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to adjust
|
||||||
|
* @data: New contents of abuf
|
||||||
|
* @size: New size of abuf
|
||||||
|
*/
|
||||||
|
void abuf_set(struct abuf *abuf, void *data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_map_sysmem() - calls map_sysmem() to set up an abuf
|
||||||
|
*
|
||||||
|
* This is equivalent to abuf_set(abuf, map_sysmem(addr, size), size)
|
||||||
|
*
|
||||||
|
* Any existing data in the abuf is freed and the alloced member is set to
|
||||||
|
* false.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to adjust
|
||||||
|
* @addr: Address to set the abuf to
|
||||||
|
* @size: New size of abuf
|
||||||
|
*/
|
||||||
|
void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_realloc() - Change the size of a buffer
|
||||||
|
*
|
||||||
|
* This uses realloc() to change the size of the buffer, with the same semantics
|
||||||
|
* as that function. If the abuf is not currently alloced, then it will alloc
|
||||||
|
* it if the size needs to increase (i.e. set the alloced member to true)
|
||||||
|
*
|
||||||
|
* @abuf: abuf to adjust
|
||||||
|
* @new_size: new size in bytes.
|
||||||
|
* if 0, the abuf is freed
|
||||||
|
* if greater than the current size, the abuf is extended and the new
|
||||||
|
* space is not inited. The alloced member is set to true
|
||||||
|
* if less than the current size, the abuf is contracted and the data at
|
||||||
|
* the end is lost. If @new_size is 0, this sets the alloced member to
|
||||||
|
* false
|
||||||
|
* @return true if OK, false if out of memory
|
||||||
|
*/
|
||||||
|
bool abuf_realloc(struct abuf *abuf, size_t new_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_uninit_move() - Return the allocated contents and uninit the abuf
|
||||||
|
*
|
||||||
|
* This returns the abuf data to the caller, allocating it if necessary, so that
|
||||||
|
* the caller receives data that it can be sure will hang around. The caller is
|
||||||
|
* responsible for freeing the data.
|
||||||
|
*
|
||||||
|
* If the abuf has allocated data, it is returned. If the abuf has data but it
|
||||||
|
* is not allocated, then it is first allocated, then returned.
|
||||||
|
*
|
||||||
|
* If the abuf size is 0, this returns NULL
|
||||||
|
*
|
||||||
|
* The abuf is uninited as part of this, except if the allocation fails, in
|
||||||
|
* which NULL is returned and the abuf remains untouched.
|
||||||
|
*
|
||||||
|
* The abuf must be inited before this can be called.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to uninit
|
||||||
|
* @sizep: if non-NULL, returns the size of the returned data
|
||||||
|
* @return data contents, allocated with malloc(), or NULL if the data could not
|
||||||
|
* be allocated, or the data size is 0
|
||||||
|
*/
|
||||||
|
void *abuf_uninit_move(struct abuf *abuf, size_t *sizep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_init_move() - Make abuf take over the management of an allocated region
|
||||||
|
*
|
||||||
|
* After this, @data must not be used. All access must be via the abuf.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to init
|
||||||
|
* @data: Existing allocated buffer to place in the abuf
|
||||||
|
* @size: Size of allocated buffer
|
||||||
|
*/
|
||||||
|
void abuf_init_move(struct abuf *abuf, void *data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_init_set() - Set up a new abuf
|
||||||
|
*
|
||||||
|
* Inits a new abuf and sets up its (unallocated) data
|
||||||
|
*
|
||||||
|
* @abuf: abuf to set up
|
||||||
|
* @data: New contents of abuf
|
||||||
|
* @size: New size of abuf
|
||||||
|
*/
|
||||||
|
void abuf_init_set(struct abuf *abuf, void *data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_uninit() - Free any memory used by an abuf
|
||||||
|
*
|
||||||
|
* The buffer must be inited before this can be called.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to uninit
|
||||||
|
*/
|
||||||
|
void abuf_uninit(struct abuf *abuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_init() - Set up a new abuf
|
||||||
|
*
|
||||||
|
* This initially has no data and alloced is set to false. This is equivalent to
|
||||||
|
* setting all fields to 0, e.g. with memset(), so callers can do that instead
|
||||||
|
* if desired.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to set up
|
||||||
|
*/
|
||||||
|
void abuf_init(struct abuf *abuf);
|
||||||
|
|
||||||
|
#endif
|
|
@ -68,6 +68,9 @@ typedef uint32_t __u32;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef unsigned long ulong;
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
|
/* Define these on the host so we can build some target code */
|
||||||
|
typedef __u32 u32;
|
||||||
|
|
||||||
#define uswap_16(x) \
|
#define uswap_16(x) \
|
||||||
((((x) & 0xff00) >> 8) | \
|
((((x) & 0xff00) >> 8) | \
|
||||||
(((x) & 0x00ff) << 8))
|
(((x) & 0x00ff) << 8))
|
||||||
|
@ -151,7 +154,13 @@ typedef unsigned long int uintptr_t;
|
||||||
#define MEM_SUPPORT_64BIT_DATA 0
|
#define MEM_SUPPORT_64BIT_DATA 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline bool host_build(void) {
|
/**
|
||||||
|
* tools_build() - check if we are building host tools
|
||||||
|
*
|
||||||
|
* @return true if building for the host, false if for a target
|
||||||
|
*/
|
||||||
|
static inline bool tools_build(void)
|
||||||
|
{
|
||||||
#ifdef USE_HOSTCC
|
#ifdef USE_HOSTCC
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef __FDT_SUPPORT_H
|
#ifndef __FDT_SUPPORT_H
|
||||||
#define __FDT_SUPPORT_H
|
#define __FDT_SUPPORT_H
|
||||||
|
|
||||||
#ifdef CONFIG_OF_LIBFDT
|
#if defined(CONFIG_OF_LIBFDT) && !defined(USE_HOSTCC)
|
||||||
|
|
||||||
#include <asm/u-boot.h>
|
#include <asm/u-boot.h>
|
||||||
#include <linux/libfdt.h>
|
#include <linux/libfdt.h>
|
||||||
|
|
|
@ -54,11 +54,11 @@ int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
|
||||||
* gzwrite_progress_finish called at end of loop to
|
* gzwrite_progress_finish called at end of loop to
|
||||||
* indicate success (retcode=0) or failure
|
* indicate success (retcode=0) or failure
|
||||||
*/
|
*/
|
||||||
void gzwrite_progress_init(u64 expected_size);
|
void gzwrite_progress_init(ulong expected_size);
|
||||||
|
|
||||||
void gzwrite_progress(int iteration, u64 bytes_written, u64 total_bytes);
|
void gzwrite_progress(int iteration, ulong bytes_written, ulong total_bytes);
|
||||||
|
|
||||||
void gzwrite_progress_finish(int retcode, u64 totalwritten, u64 totalsize,
|
void gzwrite_progress_finish(int retcode, ulong totalwritten, ulong totalsize,
|
||||||
u32 expected_crc, u32 calculated_crc);
|
u32 expected_crc, u32 calculated_crc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +74,7 @@ void gzwrite_progress_finish(int retcode, u64 totalwritten, u64 totalsize,
|
||||||
* @return 0 if OK, -1 on error
|
* @return 0 if OK, -1 on error
|
||||||
*/
|
*/
|
||||||
int gzwrite(unsigned char *src, int len, struct blk_desc *dev, ulong szwritebuf,
|
int gzwrite(unsigned char *src, int len, struct blk_desc *dev, ulong szwritebuf,
|
||||||
u64 startoffs, u64 szexpected);
|
ulong startoffs, ulong szexpected);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gzip()- Compress data into a buffer using the gzip algorithm
|
* gzip()- Compress data into a buffer using the gzip algorithm
|
||||||
|
|
|
@ -6,13 +6,17 @@
|
||||||
#ifndef _HASH_H
|
#ifndef _HASH_H
|
||||||
#define _HASH_H
|
#define _HASH_H
|
||||||
|
|
||||||
|
#ifdef USE_HOSTCC
|
||||||
|
#include <linux/kconfig.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct cmd_tbl;
|
struct cmd_tbl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum digest size for all algorithms we support. Having this value
|
* Maximum digest size for all algorithms we support. Having this value
|
||||||
* avoids a malloc() or C99 local declaration in common/cmd_hash.c.
|
* avoids a malloc() or C99 local declaration in common/cmd_hash.c.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_SHA384) || defined(CONFIG_SHA512)
|
#if CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512)
|
||||||
#define HASH_MAX_DIGEST_SIZE 64
|
#define HASH_MAX_DIGEST_SIZE 64
|
||||||
#else
|
#else
|
||||||
#define HASH_MAX_DIGEST_SIZE 32
|
#define HASH_MAX_DIGEST_SIZE 32
|
||||||
|
|
|
@ -25,19 +25,8 @@ struct fdt_region;
|
||||||
|
|
||||||
#ifdef USE_HOSTCC
|
#ifdef USE_HOSTCC
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <linux/kconfig.h>
|
||||||
|
|
||||||
/* new uImage format support enabled on host */
|
|
||||||
#define IMAGE_ENABLE_FIT 1
|
|
||||||
#define IMAGE_ENABLE_OF_LIBFDT 1
|
|
||||||
#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */
|
|
||||||
#define CONFIG_FIT_RSASSA_PSS 1
|
|
||||||
#define CONFIG_MD5
|
|
||||||
#define CONFIG_SHA1
|
|
||||||
#define CONFIG_SHA256
|
|
||||||
#define CONFIG_SHA384
|
|
||||||
#define CONFIG_SHA512
|
|
||||||
|
|
||||||
#define IMAGE_ENABLE_IGNORE 0
|
|
||||||
#define IMAGE_INDENT_STRING ""
|
#define IMAGE_INDENT_STRING ""
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -47,38 +36,14 @@ struct fdt_region;
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <linker_lists.h>
|
#include <linker_lists.h>
|
||||||
|
|
||||||
/* Take notice of the 'ignore' property for hashes */
|
|
||||||
#define IMAGE_ENABLE_IGNORE 1
|
|
||||||
#define IMAGE_INDENT_STRING " "
|
#define IMAGE_INDENT_STRING " "
|
||||||
|
|
||||||
#define IMAGE_ENABLE_FIT CONFIG_IS_ENABLED(FIT)
|
|
||||||
#define IMAGE_ENABLE_OF_LIBFDT CONFIG_IS_ENABLED(OF_LIBFDT)
|
|
||||||
|
|
||||||
#endif /* USE_HOSTCC */
|
#endif /* USE_HOSTCC */
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <linux/libfdt.h>
|
#include <linux/libfdt.h>
|
||||||
#include <fdt_support.h>
|
#include <fdt_support.h>
|
||||||
#endif /* IMAGE_ENABLE_FIT */
|
#include <u-boot/hash-checksum.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
|
|
||||||
# define IMAGE_BOOT_GET_CMDLINE 1
|
|
||||||
#else
|
|
||||||
# define IMAGE_BOOT_GET_CMDLINE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_OF_BOARD_SETUP
|
|
||||||
# define IMAGE_OF_BOARD_SETUP 1
|
|
||||||
#else
|
|
||||||
# define IMAGE_OF_BOARD_SETUP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_OF_SYSTEM_SETUP
|
|
||||||
# define IMAGE_OF_SYSTEM_SETUP 1
|
|
||||||
#else
|
|
||||||
# define IMAGE_OF_SYSTEM_SETUP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern ulong image_load_addr; /* Default Load Address */
|
extern ulong image_load_addr; /* Default Load Address */
|
||||||
extern ulong image_save_addr; /* Default Save Address */
|
extern ulong image_save_addr; /* Default Save Address */
|
||||||
|
@ -333,7 +298,11 @@ typedef struct bootm_headers {
|
||||||
image_header_t legacy_hdr_os_copy; /* header copy */
|
image_header_t legacy_hdr_os_copy; /* header copy */
|
||||||
ulong legacy_hdr_valid;
|
ulong legacy_hdr_valid;
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
/*
|
||||||
|
* The fit_ members are only used with FIT, but it involves a lot of
|
||||||
|
* #ifdefs to avoid compiling that code. Since FIT is the standard
|
||||||
|
* format, even for SPL, this extra data size seems worth it.
|
||||||
|
*/
|
||||||
const char *fit_uname_cfg; /* configuration node unit name */
|
const char *fit_uname_cfg; /* configuration node unit name */
|
||||||
|
|
||||||
void *fit_hdr_os; /* os FIT image header */
|
void *fit_hdr_os; /* os FIT image header */
|
||||||
|
@ -351,7 +320,6 @@ typedef struct bootm_headers {
|
||||||
void *fit_hdr_setup; /* x86 setup FIT image header */
|
void *fit_hdr_setup; /* x86 setup FIT image header */
|
||||||
const char *fit_uname_setup; /* x86 setup subimage node name */
|
const char *fit_uname_setup; /* x86 setup subimage node name */
|
||||||
int fit_noffset_setup;/* x86 setup subimage node offset */
|
int fit_noffset_setup;/* x86 setup subimage node offset */
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_HOSTCC
|
#ifndef USE_HOSTCC
|
||||||
image_info_t os; /* os image info */
|
image_info_t os; /* os image info */
|
||||||
|
@ -538,8 +506,7 @@ int genimg_get_type_id(const char *name);
|
||||||
int genimg_get_comp_id(const char *name);
|
int genimg_get_comp_id(const char *name);
|
||||||
void genimg_print_size(uint32_t size);
|
void genimg_print_size(uint32_t size);
|
||||||
|
|
||||||
#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || \
|
#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
|
||||||
defined(USE_HOSTCC)
|
|
||||||
#define IMAGE_ENABLE_TIMESTAMP 1
|
#define IMAGE_ENABLE_TIMESTAMP 1
|
||||||
#else
|
#else
|
||||||
#define IMAGE_ENABLE_TIMESTAMP 0
|
#define IMAGE_ENABLE_TIMESTAMP 0
|
||||||
|
@ -557,12 +524,9 @@ enum fit_load_op {
|
||||||
int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start,
|
int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start,
|
||||||
ulong *setup_len);
|
ulong *setup_len);
|
||||||
|
|
||||||
#ifndef USE_HOSTCC
|
|
||||||
/* Image format types, returned by _get_format() routine */
|
/* Image format types, returned by _get_format() routine */
|
||||||
#define IMAGE_FORMAT_INVALID 0x00
|
#define IMAGE_FORMAT_INVALID 0x00
|
||||||
#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
|
|
||||||
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
|
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
|
||||||
#endif
|
|
||||||
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
|
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
|
||||||
#define IMAGE_FORMAT_ANDROID 0x03 /* Android boot image */
|
#define IMAGE_FORMAT_ANDROID 0x03 /* Android boot image */
|
||||||
|
|
||||||
|
@ -601,7 +565,6 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images,
|
||||||
*/
|
*/
|
||||||
int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
|
int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
|
||||||
uint8_t arch, const ulong *ld_start, ulong *const ld_len);
|
uint8_t arch, const ulong *ld_start, ulong *const ld_len);
|
||||||
#endif /* !USE_HOSTCC */
|
|
||||||
|
|
||||||
int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
|
int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
|
||||||
ulong *setup_start, ulong *setup_len);
|
ulong *setup_start, ulong *setup_len);
|
||||||
|
@ -678,7 +641,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
||||||
*/
|
*/
|
||||||
int image_source_script(ulong addr, const char *fit_uname);
|
int image_source_script(ulong addr, const char *fit_uname);
|
||||||
|
|
||||||
#ifndef USE_HOSTCC
|
|
||||||
/**
|
/**
|
||||||
* fit_get_node_from_config() - Look up an image a FIT by type
|
* fit_get_node_from_config() - Look up an image a FIT by type
|
||||||
*
|
*
|
||||||
|
@ -718,10 +680,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size);
|
||||||
int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
|
int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||||
ulong *initrd_start, ulong *initrd_end);
|
ulong *initrd_start, ulong *initrd_end);
|
||||||
int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end);
|
int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end);
|
||||||
#ifdef CONFIG_SYS_BOOT_GET_KBD
|
|
||||||
int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd);
|
int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd);
|
||||||
#endif /* CONFIG_SYS_BOOT_GET_KBD */
|
|
||||||
#endif /* !USE_HOSTCC */
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* Legacy format specific code (prefixed with image_) */
|
/* Legacy format specific code (prefixed with image_) */
|
||||||
|
@ -836,11 +795,9 @@ static inline int image_check_type(const image_header_t *hdr, uint8_t type)
|
||||||
}
|
}
|
||||||
static inline int image_check_arch(const image_header_t *hdr, uint8_t arch)
|
static inline int image_check_arch(const image_header_t *hdr, uint8_t arch)
|
||||||
{
|
{
|
||||||
#ifndef USE_HOSTCC
|
|
||||||
/* Let's assume that sandbox can load any architecture */
|
/* Let's assume that sandbox can load any architecture */
|
||||||
if (IS_ENABLED(CONFIG_SANDBOX))
|
if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
return (image_get_arch(hdr) == arch) ||
|
return (image_get_arch(hdr) == arch) ||
|
||||||
(image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64);
|
(image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64);
|
||||||
}
|
}
|
||||||
|
@ -988,7 +945,6 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size,
|
||||||
|
|
||||||
#define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE
|
#define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
|
||||||
/* cmdline argument format parsing */
|
/* cmdline argument format parsing */
|
||||||
int fit_parse_conf(const char *spec, ulong addr_curr,
|
int fit_parse_conf(const char *spec, ulong addr_curr,
|
||||||
ulong *addr, const char **conf_name);
|
ulong *addr, const char **conf_name);
|
||||||
|
@ -1162,7 +1118,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset,
|
||||||
|
|
||||||
int fit_check_ramdisk(const void *fit, int os_noffset,
|
int fit_check_ramdisk(const void *fit, int os_noffset,
|
||||||
uint8_t arch, int verify);
|
uint8_t arch, int verify);
|
||||||
#endif /* IMAGE_ENABLE_FIT */
|
|
||||||
|
|
||||||
int calculate_hash(const void *data, int data_len, const char *algo,
|
int calculate_hash(const void *data, int data_len, const char *algo,
|
||||||
uint8_t *value, int *value_len);
|
uint8_t *value, int *value_len);
|
||||||
|
@ -1185,7 +1140,6 @@ int calculate_hash(const void *data, int data_len, const char *algo,
|
||||||
# define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
# define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
|
||||||
#ifdef USE_HOSTCC
|
#ifdef USE_HOSTCC
|
||||||
void *image_get_host_blob(void);
|
void *image_get_host_blob(void);
|
||||||
void image_set_host_blob(void *host_blob);
|
void image_set_host_blob(void *host_blob);
|
||||||
|
@ -1194,8 +1148,6 @@ void image_set_host_blob(void *host_blob);
|
||||||
# define gd_fdt_blob() (gd->fdt_blob)
|
# define gd_fdt_blob() (gd->fdt_blob)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* IMAGE_ENABLE_FIT */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Information passed to the signing routines
|
* Information passed to the signing routines
|
||||||
*
|
*
|
||||||
|
@ -1232,9 +1184,6 @@ struct image_region {
|
||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if FIT_IMAGE_ENABLE_VERIFY
|
|
||||||
# include <u-boot/hash-checksum.h>
|
|
||||||
#endif
|
|
||||||
struct checksum_algo {
|
struct checksum_algo {
|
||||||
const char *name;
|
const char *name;
|
||||||
const int checksum_len;
|
const int checksum_len;
|
||||||
|
@ -1244,7 +1193,7 @@ struct checksum_algo {
|
||||||
const EVP_MD *(*calculate_sign)(void);
|
const EVP_MD *(*calculate_sign)(void);
|
||||||
#endif
|
#endif
|
||||||
int (*calculate)(const char *name,
|
int (*calculate)(const char *name,
|
||||||
const struct image_region region[],
|
const struct image_region *region,
|
||||||
int region_count, uint8_t *checksum);
|
int region_count, uint8_t *checksum);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1340,8 +1289,6 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name);
|
||||||
*/
|
*/
|
||||||
struct padding_algo *image_get_padding_algo(const char *name);
|
struct padding_algo *image_get_padding_algo(const char *name);
|
||||||
|
|
||||||
#if IMAGE_ENABLE_FIT
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fit_image_verify_required_sigs() - Verify signatures marked as 'required'
|
* fit_image_verify_required_sigs() - Verify signatures marked as 'required'
|
||||||
*
|
*
|
||||||
|
@ -1467,23 +1414,6 @@ int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo);
|
||||||
|
|
||||||
struct cipher_algo *image_get_cipher_algo(const char *full_name);
|
struct cipher_algo *image_get_cipher_algo(const char *full_name);
|
||||||
|
|
||||||
#ifdef CONFIG_FIT_VERBOSE
|
|
||||||
#define fit_unsupported(msg) printf("! %s:%d " \
|
|
||||||
"FIT images not supported for '%s'\n", \
|
|
||||||
__FILE__, __LINE__, (msg))
|
|
||||||
|
|
||||||
#define fit_unsupported_reset(msg) printf("! %s:%d " \
|
|
||||||
"FIT images not supported for '%s' " \
|
|
||||||
"- must reset board to recover!\n", \
|
|
||||||
__FILE__, __LINE__, (msg))
|
|
||||||
#else
|
|
||||||
#define fit_unsupported(msg)
|
|
||||||
#define fit_unsupported_reset(msg)
|
|
||||||
#endif /* CONFIG_FIT_VERBOSE */
|
|
||||||
#endif /* CONFIG_FIT */
|
|
||||||
|
|
||||||
#if !defined(USE_HOSTCC)
|
|
||||||
#if defined(CONFIG_ANDROID_BOOT_IMAGE)
|
|
||||||
struct andr_img_hdr;
|
struct andr_img_hdr;
|
||||||
int android_image_check_header(const struct andr_img_hdr *hdr);
|
int android_image_check_header(const struct andr_img_hdr *hdr);
|
||||||
int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
|
int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
|
||||||
|
@ -1499,12 +1429,7 @@ ulong android_image_get_end(const struct andr_img_hdr *hdr);
|
||||||
ulong android_image_get_kload(const struct andr_img_hdr *hdr);
|
ulong android_image_get_kload(const struct andr_img_hdr *hdr);
|
||||||
ulong android_image_get_kcomp(const struct andr_img_hdr *hdr);
|
ulong android_image_get_kcomp(const struct andr_img_hdr *hdr);
|
||||||
void android_print_contents(const struct andr_img_hdr *hdr);
|
void android_print_contents(const struct andr_img_hdr *hdr);
|
||||||
#if !defined(CONFIG_SPL_BUILD)
|
|
||||||
bool android_image_print_dtb_contents(ulong hdr_addr);
|
bool android_image_print_dtb_contents(ulong hdr_addr);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CONFIG_ANDROID_BOOT_IMAGE */
|
|
||||||
#endif /* !USE_HOSTCC */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* board_fit_config_name_match() - Check for a matching board name
|
* board_fit_config_name_match() - Check for a matching board name
|
||||||
|
|
|
@ -31,11 +31,14 @@
|
||||||
(config_enabled(option))
|
(config_enabled(option))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* U-Boot add-on: Helper macros to reference to different macros
|
* U-Boot add-on: Helper macros to reference to different macros (prefixed by
|
||||||
* (CONFIG_ or CONFIG_SPL_ prefixed), depending on the build context.
|
* CONFIG_, CONFIG_SPL_, CONFIG_TPL_ or CONFIG_TOOLS_), depending on the build
|
||||||
|
* context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_TPL_BUILD)
|
#ifdef USE_HOSTCC
|
||||||
|
#define _CONFIG_PREFIX TOOLS_
|
||||||
|
#elif defined(CONFIG_TPL_BUILD)
|
||||||
#define _CONFIG_PREFIX TPL_
|
#define _CONFIG_PREFIX TPL_
|
||||||
#elif defined(CONFIG_SPL_BUILD)
|
#elif defined(CONFIG_SPL_BUILD)
|
||||||
#define _CONFIG_PREFIX SPL_
|
#define _CONFIG_PREFIX SPL_
|
||||||
|
@ -49,6 +52,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CONFIG_VAL(FOO) evaluates to the value of
|
* CONFIG_VAL(FOO) evaluates to the value of
|
||||||
|
* CONFIG_TOOLS_FOO if USE_HOSTCC is defined,
|
||||||
* CONFIG_FOO if CONFIG_SPL_BUILD is undefined,
|
* CONFIG_FOO if CONFIG_SPL_BUILD is undefined,
|
||||||
* CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined.
|
* CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined.
|
||||||
* CONFIG_TPL_FOO if CONFIG_TPL_BUILD is defined.
|
* CONFIG_TPL_FOO if CONFIG_TPL_BUILD is defined.
|
||||||
|
@ -76,18 +80,21 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CONFIG_IS_ENABLED(FOO) expands to
|
* CONFIG_IS_ENABLED(FOO) expands to
|
||||||
|
* 1 if USE_HOSTCC is defined and CONFIG_TOOLS_FOO is set to 'y',
|
||||||
* 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
* 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||||
* 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
* 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||||
* 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
* 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||||
* 0 otherwise.
|
* 0 otherwise.
|
||||||
*
|
*
|
||||||
* CONFIG_IS_ENABLED(FOO, (abc)) expands to
|
* CONFIG_IS_ENABLED(FOO, (abc)) expands to
|
||||||
|
* abc if USE_HOSTCC is defined and CONFIG_TOOLS_FOO is set to 'y',
|
||||||
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||||
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||||
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||||
* nothing otherwise.
|
* nothing otherwise.
|
||||||
*
|
*
|
||||||
* CONFIG_IS_ENABLED(FOO, (abc), (def)) expands to
|
* CONFIG_IS_ENABLED(FOO, (abc), (def)) expands to
|
||||||
|
* abc if USE_HOSTCC is defined and CONFIG_TOOLS_FOO is set to 'y',
|
||||||
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||||
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||||
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||||
|
|
|
@ -129,6 +129,19 @@ extern void * memchr(const void *,int,__kernel_size_t);
|
||||||
void *memchr_inv(const void *, int, size_t);
|
void *memchr_inv(const void *, int, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memdup() - allocate a buffer and copy in the contents
|
||||||
|
*
|
||||||
|
* Note that this returns a valid pointer even if @len is 0
|
||||||
|
*
|
||||||
|
* @src: data to copy in
|
||||||
|
* @len: number of bytes to copy
|
||||||
|
* @return allocated buffer with the copied contents, or NULL if not enough
|
||||||
|
* memory is available
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
char *memdup(const void *src, size_t len);
|
||||||
|
|
||||||
unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
|
unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
|
||||||
unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
|
unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
|
||||||
|
|
||||||
|
|
|
@ -1144,4 +1144,15 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity,
|
||||||
size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart,
|
size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart,
|
||||||
size_t blockSize);
|
size_t blockSize);
|
||||||
|
|
||||||
|
struct abuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zstd_decompress() - Decompress Zstandard data
|
||||||
|
*
|
||||||
|
* @in: Input buffer to decompress
|
||||||
|
* @out: Output buffer to hold the results (must be large enough)
|
||||||
|
* @return size of the decompressed data, or -ve on error
|
||||||
|
*/
|
||||||
|
int zstd_decompress(struct abuf *in, struct abuf *out);
|
||||||
|
|
||||||
#endif /* ZSTD_H */
|
#endif /* ZSTD_H */
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
#ifndef _RELOCATE_H_
|
#ifndef _RELOCATE_H_
|
||||||
#define _RELOCATE_H_
|
#define _RELOCATE_H_
|
||||||
|
|
||||||
#include <common.h>
|
#ifndef USE_HOSTCC
|
||||||
|
#include <asm/global_data.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* copy_uboot_to_ram() - Copy U-Boot to its new relocated position
|
* copy_uboot_to_ram() - Copy U-Boot to its new relocated position
|
||||||
|
@ -35,4 +39,28 @@ int clear_bss(void);
|
||||||
*/
|
*/
|
||||||
int do_elf_reloc_fixups(void);
|
int do_elf_reloc_fixups(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* manual_reloc() - Manually relocate a pointer if needed
|
||||||
|
*
|
||||||
|
* This is a nop in almost all cases, except for the systems with a broken gcc
|
||||||
|
* which need to manually relocate some things.
|
||||||
|
*
|
||||||
|
* @ptr: Pointer to relocate
|
||||||
|
* @return new pointer value
|
||||||
|
*/
|
||||||
|
static inline void *manual_reloc(void *ptr)
|
||||||
|
{
|
||||||
|
#ifndef USE_HOSTCC
|
||||||
|
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC))
|
||||||
|
return ptr + gd->reloc_off;
|
||||||
|
#endif
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC)
|
||||||
|
#define MANUAL_RELOC(ptr) (ptr) = manual_reloc(ptr)
|
||||||
|
#else
|
||||||
|
#define MANUAL_RELOC(ptr) (void)(ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _RELOCATE_H_ */
|
#endif /* _RELOCATE_H_ */
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
#define _RSA_CHECKSUM_H
|
#define _RSA_CHECKSUM_H
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <image.h>
|
|
||||||
#include <u-boot/sha1.h>
|
#include <u-boot/sha1.h>
|
||||||
#include <u-boot/sha256.h>
|
#include <u-boot/sha256.h>
|
||||||
#include <u-boot/sha512.h>
|
#include <u-boot/sha512.h>
|
||||||
|
|
||||||
|
struct image_region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hash_calculate() - Calculate hash over the data
|
* hash_calculate() - Calculate hash over the data
|
||||||
*
|
*
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
* @return 0 if OK, < 0 if error
|
* @return 0 if OK, < 0 if error
|
||||||
*/
|
*/
|
||||||
int hash_calculate(const char *name,
|
int hash_calculate(const char *name,
|
||||||
const struct image_region region[], int region_count,
|
const struct image_region *region, int region_count,
|
||||||
uint8_t *checksum);
|
uint8_t *checksum);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,11 +103,9 @@ int padding_pkcs_15_verify(struct image_sign_info *info,
|
||||||
uint8_t *msg, int msg_len,
|
uint8_t *msg, int msg_len,
|
||||||
const uint8_t *hash, int hash_len);
|
const uint8_t *hash, int hash_len);
|
||||||
|
|
||||||
#ifdef CONFIG_FIT_RSASSA_PSS
|
|
||||||
int padding_pss_verify(struct image_sign_info *info,
|
int padding_pss_verify(struct image_sign_info *info,
|
||||||
uint8_t *msg, int msg_len,
|
uint8_t *msg, int msg_len,
|
||||||
const uint8_t *hash, int hash_len);
|
const uint8_t *hash, int hash_len);
|
||||||
#endif /* CONFIG_FIT_RSASSA_PSS */
|
|
||||||
|
|
||||||
#define RSA_DEFAULT_PADDING_NAME "pkcs-1.5"
|
#define RSA_DEFAULT_PADDING_NAME "pkcs-1.5"
|
||||||
|
|
||||||
|
|
66
lib/Kconfig
66
lib/Kconfig
|
@ -373,7 +373,6 @@ config SHA256
|
||||||
The SHA256 algorithm produces a 256-bit (32-byte) hash value
|
The SHA256 algorithm produces a 256-bit (32-byte) hash value
|
||||||
(digest).
|
(digest).
|
||||||
|
|
||||||
|
|
||||||
config SHA512
|
config SHA512
|
||||||
bool "Enable SHA512 support"
|
bool "Enable SHA512 support"
|
||||||
help
|
help
|
||||||
|
@ -399,6 +398,66 @@ config SHA_HW_ACCEL
|
||||||
hashing algorithms. This affects the 'hash' command and also the
|
hashing algorithms. This affects the 'hash' command and also the
|
||||||
hash_lookup_algo() function.
|
hash_lookup_algo() function.
|
||||||
|
|
||||||
|
if SPL
|
||||||
|
|
||||||
|
config SPL_SHA1
|
||||||
|
bool "Enable SHA1 support in SPL"
|
||||||
|
default y if SHA1
|
||||||
|
help
|
||||||
|
This option enables support of hashing using SHA1 algorithm.
|
||||||
|
The hash is calculated in software.
|
||||||
|
The SHA1 algorithm produces a 160-bit (20-byte) hash value
|
||||||
|
(digest).
|
||||||
|
|
||||||
|
config SPL_SHA256
|
||||||
|
bool "Enable SHA256 support in SPL"
|
||||||
|
default y if SHA256
|
||||||
|
help
|
||||||
|
This option enables support of hashing using SHA256 algorithm.
|
||||||
|
The hash is calculated in software.
|
||||||
|
The SHA256 algorithm produces a 256-bit (32-byte) hash value
|
||||||
|
(digest).
|
||||||
|
|
||||||
|
config SPL_SHA512
|
||||||
|
bool "Enable SHA512 support in SPL"
|
||||||
|
default y if SHA512
|
||||||
|
help
|
||||||
|
This option enables support of hashing using SHA512 algorithm.
|
||||||
|
The hash is calculated in software.
|
||||||
|
The SHA512 algorithm produces a 512-bit (64-byte) hash value
|
||||||
|
(digest).
|
||||||
|
|
||||||
|
config SPL_SHA384
|
||||||
|
bool "Enable SHA384 support in SPL"
|
||||||
|
default y if SHA384
|
||||||
|
select SPL_SHA512
|
||||||
|
help
|
||||||
|
This option enables support of hashing using SHA384 algorithm.
|
||||||
|
The hash is calculated in software. This is also selects SHA512,
|
||||||
|
because these implementations share the bulk of the code..
|
||||||
|
The SHA384 algorithm produces a 384-bit (48-byte) hash value
|
||||||
|
(digest).
|
||||||
|
|
||||||
|
config SPL_SHA_HW_ACCEL
|
||||||
|
bool "Enable hardware acceleration for SHA hash functions"
|
||||||
|
default y if SHA_HW_ACCEL
|
||||||
|
help
|
||||||
|
This option enables hardware acceleration for the SHA1 and SHA256
|
||||||
|
hashing algorithms. This affects the 'hash' command and also the
|
||||||
|
hash_lookup_algo() function.
|
||||||
|
|
||||||
|
config SPL_SHA_PROG_HW_ACCEL
|
||||||
|
bool "Enable Progressive hashing support using hardware in SPL"
|
||||||
|
depends on SHA_PROG_HW_ACCEL
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
This option enables hardware-acceleration for SHA progressive
|
||||||
|
hashing.
|
||||||
|
Data can be streamed in a block at a time and the hashing is
|
||||||
|
performed in hardware.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
if SHA_HW_ACCEL
|
if SHA_HW_ACCEL
|
||||||
|
|
||||||
config SHA512_HW_ACCEL
|
config SHA512_HW_ACCEL
|
||||||
|
@ -437,6 +496,11 @@ config SPL_MD5
|
||||||
security applications, but it can be useful for providing a quick
|
security applications, but it can be useful for providing a quick
|
||||||
checksum of a block of data.
|
checksum of a block of data.
|
||||||
|
|
||||||
|
config CRC32
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enables CRC32 support in U-Boot. This is normally required.
|
||||||
|
|
||||||
config CRC32C
|
config CRC32C
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
|
|
@ -96,9 +96,7 @@ obj-y += display_options.o
|
||||||
CFLAGS_display_options.o := $(if $(BUILD_TAG),-DBUILD_TAG='"$(BUILD_TAG)"')
|
CFLAGS_display_options.o := $(if $(BUILD_TAG),-DBUILD_TAG='"$(BUILD_TAG)"')
|
||||||
obj-$(CONFIG_BCH) += bch.o
|
obj-$(CONFIG_BCH) += bch.o
|
||||||
obj-$(CONFIG_MMC_SPI) += crc7.o
|
obj-$(CONFIG_MMC_SPI) += crc7.o
|
||||||
#ifndef CONFIG_TPL_BUILD
|
obj-$(CONFIG_$(SPL_TPL_)CRC32) += crc32.o
|
||||||
obj-y += crc32.o
|
|
||||||
#endif
|
|
||||||
obj-$(CONFIG_CRC32C) += crc32c.o
|
obj-$(CONFIG_CRC32C) += crc32c.o
|
||||||
obj-y += ctype.o
|
obj-y += ctype.o
|
||||||
obj-y += div64.o
|
obj-y += div64.o
|
||||||
|
@ -134,6 +132,7 @@ obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
|
||||||
obj-$(CONFIG_SSCANF) += sscanf.o
|
obj-$(CONFIG_SSCANF) += sscanf.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
obj-y += abuf.o
|
||||||
obj-y += date.o
|
obj-y += date.o
|
||||||
obj-y += rtc-lib.o
|
obj-y += rtc-lib.o
|
||||||
obj-$(CONFIG_LIB_ELF) += elf.o
|
obj-$(CONFIG_LIB_ELF) += elf.o
|
||||||
|
|
109
lib/abuf.c
Normal file
109
lib/abuf.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Handles a buffer that can be allocated and freed
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <abuf.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <mapmem.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void abuf_set(struct abuf *abuf, void *data, size_t size)
|
||||||
|
{
|
||||||
|
abuf_uninit(abuf);
|
||||||
|
abuf->data = data;
|
||||||
|
abuf->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size)
|
||||||
|
{
|
||||||
|
abuf_set(abuf, map_sysmem(addr, size), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool abuf_realloc(struct abuf *abuf, size_t new_size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (!new_size) {
|
||||||
|
/* easy case, just need to uninit, freeing any allocation */
|
||||||
|
abuf_uninit(abuf);
|
||||||
|
return true;
|
||||||
|
} else if (abuf->alloced) {
|
||||||
|
/* currently allocated, so need to reallocate */
|
||||||
|
ptr = realloc(abuf->data, new_size);
|
||||||
|
if (!ptr)
|
||||||
|
return false;
|
||||||
|
abuf->data = ptr;
|
||||||
|
abuf->size = new_size;
|
||||||
|
return true;
|
||||||
|
} else if (new_size <= abuf->size) {
|
||||||
|
/*
|
||||||
|
* not currently alloced and new size is no larger. Just update
|
||||||
|
* it. Data is lost off the end if new_size < abuf->size
|
||||||
|
*/
|
||||||
|
abuf->size = new_size;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
/* not currently allocated and new size is larger. Alloc and
|
||||||
|
* copy in data. The new space is not inited.
|
||||||
|
*/
|
||||||
|
ptr = memdup(abuf->data, new_size);
|
||||||
|
if (!ptr)
|
||||||
|
return false;
|
||||||
|
abuf->data = ptr;
|
||||||
|
abuf->size = new_size;
|
||||||
|
abuf->alloced = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *abuf_uninit_move(struct abuf *abuf, size_t *sizep)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (sizep)
|
||||||
|
*sizep = abuf->size;
|
||||||
|
if (!abuf->size)
|
||||||
|
return NULL;
|
||||||
|
if (abuf->alloced) {
|
||||||
|
ptr = abuf->data;
|
||||||
|
} else {
|
||||||
|
ptr = memdup(abuf->data, abuf->size);
|
||||||
|
if (!ptr)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Clear everything out so there is no record of the data */
|
||||||
|
abuf_init(abuf);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abuf_init_set(struct abuf *abuf, void *data, size_t size)
|
||||||
|
{
|
||||||
|
abuf_init(abuf);
|
||||||
|
abuf_set(abuf, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void abuf_init_move(struct abuf *abuf, void *data, size_t size)
|
||||||
|
{
|
||||||
|
abuf_init_set(abuf, data, size);
|
||||||
|
abuf->alloced = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abuf_uninit(struct abuf *abuf)
|
||||||
|
{
|
||||||
|
if (abuf->alloced)
|
||||||
|
free(abuf->data);
|
||||||
|
abuf_init(abuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void abuf_init(struct abuf *abuf)
|
||||||
|
{
|
||||||
|
abuf->data = NULL;
|
||||||
|
abuf->size = 0;
|
||||||
|
abuf->alloced = false;
|
||||||
|
}
|
|
@ -336,7 +336,7 @@ config EFI_LOAD_FILE2_INITRD
|
||||||
|
|
||||||
config EFI_SECURE_BOOT
|
config EFI_SECURE_BOOT
|
||||||
bool "Enable EFI secure boot support"
|
bool "Enable EFI secure boot support"
|
||||||
depends on EFI_LOADER
|
depends on EFI_LOADER && FIT_SIGNATURE
|
||||||
select HASH
|
select HASH
|
||||||
select SHA256
|
select SHA256
|
||||||
select RSA
|
select RSA
|
||||||
|
|
28
lib/gunzip.c
28
lib/gunzip.c
|
@ -84,32 +84,32 @@ int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
|
||||||
|
|
||||||
#ifdef CONFIG_CMD_UNZIP
|
#ifdef CONFIG_CMD_UNZIP
|
||||||
__weak
|
__weak
|
||||||
void gzwrite_progress_init(u64 expectedsize)
|
void gzwrite_progress_init(ulong expectedsize)
|
||||||
{
|
{
|
||||||
putc('\n');
|
putc('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
__weak
|
__weak
|
||||||
void gzwrite_progress(int iteration,
|
void gzwrite_progress(int iteration,
|
||||||
u64 bytes_written,
|
ulong bytes_written,
|
||||||
u64 total_bytes)
|
ulong total_bytes)
|
||||||
{
|
{
|
||||||
if (0 == (iteration & 3))
|
if (0 == (iteration & 3))
|
||||||
printf("%llu/%llu\r", bytes_written, total_bytes);
|
printf("%lu/%lu\r", bytes_written, total_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
__weak
|
__weak
|
||||||
void gzwrite_progress_finish(int returnval,
|
void gzwrite_progress_finish(int returnval,
|
||||||
u64 bytes_written,
|
ulong bytes_written,
|
||||||
u64 total_bytes,
|
ulong total_bytes,
|
||||||
u32 expected_crc,
|
u32 expected_crc,
|
||||||
u32 calculated_crc)
|
u32 calculated_crc)
|
||||||
{
|
{
|
||||||
if (0 == returnval) {
|
if (0 == returnval) {
|
||||||
printf("\n\t%llu bytes, crc 0x%08x\n",
|
printf("\n\t%lu bytes, crc 0x%08x\n",
|
||||||
total_bytes, calculated_crc);
|
total_bytes, calculated_crc);
|
||||||
} else {
|
} else {
|
||||||
printf("\n\tuncompressed %llu of %llu\n"
|
printf("\n\tuncompressed %lu of %lu\n"
|
||||||
"\tcrcs == 0x%08x/0x%08x\n",
|
"\tcrcs == 0x%08x/0x%08x\n",
|
||||||
bytes_written, total_bytes,
|
bytes_written, total_bytes,
|
||||||
expected_crc, calculated_crc);
|
expected_crc, calculated_crc);
|
||||||
|
@ -119,15 +119,15 @@ void gzwrite_progress_finish(int returnval,
|
||||||
int gzwrite(unsigned char *src, int len,
|
int gzwrite(unsigned char *src, int len,
|
||||||
struct blk_desc *dev,
|
struct blk_desc *dev,
|
||||||
unsigned long szwritebuf,
|
unsigned long szwritebuf,
|
||||||
u64 startoffs,
|
ulong startoffs,
|
||||||
u64 szexpected)
|
ulong szexpected)
|
||||||
{
|
{
|
||||||
int i, flags;
|
int i, flags;
|
||||||
z_stream s;
|
z_stream s;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
unsigned char *writebuf;
|
unsigned char *writebuf;
|
||||||
unsigned crc = 0;
|
unsigned crc = 0;
|
||||||
u64 totalfilled = 0;
|
ulong totalfilled = 0;
|
||||||
lbaint_t blksperbuf, outblock;
|
lbaint_t blksperbuf, outblock;
|
||||||
u32 expected_crc;
|
u32 expected_crc;
|
||||||
u32 payload_size;
|
u32 payload_size;
|
||||||
|
@ -142,7 +142,7 @@ int gzwrite(unsigned char *src, int len,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startoffs & (dev->blksz-1)) {
|
if (startoffs & (dev->blksz-1)) {
|
||||||
printf("%s: start offset %llu not a multiple of %lu\n",
|
printf("%s: start offset %lu not a multiple of %lu\n",
|
||||||
__func__, startoffs, dev->blksz);
|
__func__, startoffs, dev->blksz);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -182,12 +182,12 @@ int gzwrite(unsigned char *src, int len,
|
||||||
if (szexpected == 0) {
|
if (szexpected == 0) {
|
||||||
szexpected = le32_to_cpu(szuncompressed);
|
szexpected = le32_to_cpu(szuncompressed);
|
||||||
} else if (szuncompressed != (u32)szexpected) {
|
} else if (szuncompressed != (u32)szexpected) {
|
||||||
printf("size of %llx doesn't match trailer low bits %x\n",
|
printf("size of %lx doesn't match trailer low bits %x\n",
|
||||||
szexpected, szuncompressed);
|
szexpected, szuncompressed);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (lldiv(szexpected, dev->blksz) > (dev->lba - outblock)) {
|
if (lldiv(szexpected, dev->blksz) > (dev->lba - outblock)) {
|
||||||
printf("%s: uncompressed size %llu exceeds device size\n",
|
printf("%s: uncompressed size %lu exceeds device size\n",
|
||||||
__func__, szexpected);
|
__func__, szexpected);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
|
||||||
int hash_calculate(const char *name,
|
int hash_calculate(const char *name,
|
||||||
const struct image_region region[],
|
const struct image_region *region,
|
||||||
int region_count, uint8_t *checksum)
|
int region_count, uint8_t *checksum)
|
||||||
{
|
{
|
||||||
struct hash_algo *algo;
|
struct hash_algo *algo;
|
||||||
|
|
|
@ -153,7 +153,7 @@ static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob)
|
||||||
arch_lmb_reserve(lmb);
|
arch_lmb_reserve(lmb);
|
||||||
board_lmb_reserve(lmb);
|
board_lmb_reserve(lmb);
|
||||||
|
|
||||||
if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob)
|
if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob)
|
||||||
boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
|
boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,15 +401,14 @@ static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo,
|
||||||
goto err_sign;
|
goto err_sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FIT_RSASSA_PSS
|
if (CONFIG_IS_ENABLED(FIT_RSASSA_PSS) && padding_algo &&
|
||||||
if (padding_algo && !strcmp(padding_algo->name, "pss")) {
|
!strcmp(padding_algo->name, "pss")) {
|
||||||
if (EVP_PKEY_CTX_set_rsa_padding(ckey,
|
if (EVP_PKEY_CTX_set_rsa_padding(ckey,
|
||||||
RSA_PKCS1_PSS_PADDING) <= 0) {
|
RSA_PKCS1_PSS_PADDING) <= 0) {
|
||||||
ret = rsa_err("Signer padding setup failed");
|
ret = rsa_err("Signer padding setup failed");
|
||||||
goto err_sign;
|
goto err_sign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FIT_RSASSA_PSS */
|
|
||||||
|
|
||||||
for (i = 0; i < region_count; i++) {
|
for (i = 0; i < region_count; i++) {
|
||||||
if (!EVP_DigestSignUpdate(context, region[i].data,
|
if (!EVP_DigestSignUpdate(context, region[i].data,
|
||||||
|
|
|
@ -102,7 +102,7 @@ U_BOOT_PADDING_ALGO(pkcs_15) = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FIT_RSASSA_PSS
|
#if CONFIG_IS_ENABLED(FIT_RSASSA_PSS)
|
||||||
static void u32_i2osp(uint32_t val, uint8_t *buf)
|
static void u32_i2osp(uint32_t val, uint8_t *buf)
|
||||||
{
|
{
|
||||||
buf[0] = (uint8_t)((val >> 24) & 0xff);
|
buf[0] = (uint8_t)((val >> 24) & 0xff);
|
||||||
|
@ -313,7 +313,6 @@ U_BOOT_PADDING_ALGO(pss) = {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
|
|
||||||
/**
|
/**
|
||||||
* rsa_verify_key() - Verify a signature against some data using RSA Key
|
* rsa_verify_key() - Verify a signature against some data using RSA Key
|
||||||
*
|
*
|
||||||
|
@ -385,9 +384,7 @@ static int rsa_verify_key(struct image_sign_info *info,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
|
|
||||||
/**
|
/**
|
||||||
* rsa_verify_with_pkey() - Verify a signature against some data using
|
* rsa_verify_with_pkey() - Verify a signature against some data using
|
||||||
* only modulus and exponent as RSA key properties.
|
* only modulus and exponent as RSA key properties.
|
||||||
|
@ -408,6 +405,9 @@ int rsa_verify_with_pkey(struct image_sign_info *info,
|
||||||
struct key_prop *prop;
|
struct key_prop *prop;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
/* Public key is self-described to fill key_prop */
|
/* Public key is self-described to fill key_prop */
|
||||||
ret = rsa_gen_key_prop(info->key, info->keylen, &prop);
|
ret = rsa_gen_key_prop(info->key, info->keylen, &prop);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -422,13 +422,6 @@ int rsa_verify_with_pkey(struct image_sign_info *info,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
int rsa_verify_with_pkey(struct image_sign_info *info,
|
|
||||||
const void *hash, uint8_t *sig, uint sig_len)
|
|
||||||
{
|
|
||||||
return -EACCES;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
||||||
/**
|
/**
|
||||||
|
|
13
lib/string.c
13
lib/string.c
|
@ -659,6 +659,19 @@ void * memscan(void * addr, int c, size_t size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *memdup(const void *src, size_t len)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = malloc(len);
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(p, src, len);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __HAVE_ARCH_STRSTR
|
#ifndef __HAVE_ARCH_STRSTR
|
||||||
/**
|
/**
|
||||||
* strstr - Find the first substring in a %NUL terminated string
|
* strstr - Find the first substring in a %NUL terminated string
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
obj-y += zstd_decompress.o
|
obj-y += zstd_decompress.o
|
||||||
|
|
||||||
zstd_decompress-y := huf_decompress.o decompress.o \
|
zstd_decompress-y := huf_decompress.o decompress.o \
|
||||||
entropy_common.o fse_decompress.o zstd_common.o
|
entropy_common.o fse_decompress.o zstd_common.o zstd.o
|
||||||
|
|
64
lib/zstd/zstd.c
Normal file
64
lib/zstd/zstd.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY LOGC_BOOT
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <abuf.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <linux/zstd.h>
|
||||||
|
|
||||||
|
int zstd_decompress(struct abuf *in, struct abuf *out)
|
||||||
|
{
|
||||||
|
ZSTD_DStream *dstream;
|
||||||
|
ZSTD_inBuffer in_buf;
|
||||||
|
ZSTD_outBuffer out_buf;
|
||||||
|
void *workspace;
|
||||||
|
size_t wsize;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wsize = ZSTD_DStreamWorkspaceBound(abuf_size(in));
|
||||||
|
workspace = malloc(wsize);
|
||||||
|
if (!workspace) {
|
||||||
|
debug("%s: cannot allocate workspace of size %zu\n", __func__,
|
||||||
|
wsize);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstream = ZSTD_initDStream(abuf_size(in), workspace, wsize);
|
||||||
|
if (!dstream) {
|
||||||
|
log_err("%s: ZSTD_initDStream failed\n", __func__);
|
||||||
|
ret = -EPERM;
|
||||||
|
goto do_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_buf.src = abuf_data(in);
|
||||||
|
in_buf.pos = 0;
|
||||||
|
in_buf.size = abuf_size(in);
|
||||||
|
|
||||||
|
out_buf.dst = abuf_data(out);
|
||||||
|
out_buf.pos = 0;
|
||||||
|
out_buf.size = abuf_size(out);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
size_t res;
|
||||||
|
|
||||||
|
res = ZSTD_decompressStream(dstream, &out_buf, &in_buf);
|
||||||
|
if (ZSTD_isError(res)) {
|
||||||
|
ret = ZSTD_getErrorCode(res);
|
||||||
|
log_err("ZSTD_decompressStream error %d\n", ret);
|
||||||
|
goto do_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_buf.pos >= abuf_size(in) || !res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = out_buf.pos;
|
||||||
|
do_free:
|
||||||
|
free(workspace);
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
# (C) Copyright 2018
|
# (C) Copyright 2018
|
||||||
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
obj-y += cmd_ut_lib.o
|
obj-y += cmd_ut_lib.o
|
||||||
|
obj-y += abuf.o
|
||||||
obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
|
obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
|
||||||
obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
|
obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
|
||||||
obj-y += hexdump.o
|
obj-y += hexdump.o
|
||||||
|
|
344
test/lib/abuf.c
Normal file
344
test/lib/abuf.c
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <abuf.h>
|
||||||
|
#include <mapmem.h>
|
||||||
|
#include <test/lib.h>
|
||||||
|
#include <test/test.h>
|
||||||
|
#include <test/ut.h>
|
||||||
|
|
||||||
|
static char test_data[] = "1234";
|
||||||
|
#define TEST_DATA_LEN sizeof(test_data)
|
||||||
|
|
||||||
|
/* Test abuf_set() */
|
||||||
|
static int lib_test_abuf_set(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
ulong start;
|
||||||
|
|
||||||
|
start = ut_check_free();
|
||||||
|
|
||||||
|
abuf_init(&buf);
|
||||||
|
abuf_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
ut_asserteq_ptr(test_data, buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Force it to allocate */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN + 1));
|
||||||
|
ut_assertnonnull(buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN + 1, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
|
||||||
|
/* Now set it again, to force it to free */
|
||||||
|
abuf_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
ut_asserteq_ptr(test_data, buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Check for memory leaks */
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_set, 0);
|
||||||
|
|
||||||
|
/* Test abuf_map_sysmem() */
|
||||||
|
static int lib_test_abuf_map_sysmem(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
ulong addr;
|
||||||
|
|
||||||
|
abuf_init(&buf);
|
||||||
|
addr = 0x100;
|
||||||
|
abuf_map_sysmem(&buf, addr, TEST_DATA_LEN);
|
||||||
|
|
||||||
|
ut_asserteq_ptr(map_sysmem(0x100, 0), buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_map_sysmem, 0);
|
||||||
|
|
||||||
|
/* Test abuf_realloc() */
|
||||||
|
static int lib_test_abuf_realloc(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
ulong start;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: crashes on sandbox sometimes due to an apparent bug in
|
||||||
|
* realloc().
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
start = ut_check_free();
|
||||||
|
|
||||||
|
abuf_init(&buf);
|
||||||
|
|
||||||
|
/* Allocate an empty buffer */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, 0));
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Allocate a non-empty abuf */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
|
||||||
|
ut_assertnonnull(buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
ptr = buf.data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make it smaller; the pointer should remain the same. Note this relies
|
||||||
|
* on knowledge of how U-Boot's realloc() works
|
||||||
|
*/
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN - 1));
|
||||||
|
ut_asserteq(TEST_DATA_LEN - 1, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
ut_asserteq_ptr(ptr, buf.data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make it larger, forcing reallocation. Note this relies on knowledge
|
||||||
|
* of how U-Boot's realloc() works
|
||||||
|
*/
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, 0x1000));
|
||||||
|
ut_assert(buf.data != ptr);
|
||||||
|
ut_asserteq(0x1000, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
|
||||||
|
/* Free it */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, 0));
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Check for memory leaks */
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_realloc, 0);
|
||||||
|
|
||||||
|
/* Test handling of buffers that are too large */
|
||||||
|
static int lib_test_abuf_large(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
ulong start;
|
||||||
|
size_t size;
|
||||||
|
int delta;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This crashes at present due to trying to allocate more memory than
|
||||||
|
* available, which breaks something on sandbox.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
start = ut_check_free();
|
||||||
|
|
||||||
|
/* Try an impossible size */
|
||||||
|
abuf_init(&buf);
|
||||||
|
ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
abuf_uninit(&buf);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Start with a normal size then try to increase it, to check realloc */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
|
||||||
|
ut_assertnonnull(buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
ptr = buf.data;
|
||||||
|
delta = ut_check_delta(start);
|
||||||
|
ut_assert(delta > 0);
|
||||||
|
|
||||||
|
/* try to increase it */
|
||||||
|
ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
|
||||||
|
ut_asserteq_ptr(ptr, buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
ut_asserteq(delta, ut_check_delta(start));
|
||||||
|
|
||||||
|
/* Check for memory leaks */
|
||||||
|
abuf_uninit(&buf);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
/* Start with a huge unallocated buf and try to move it */
|
||||||
|
abuf_init(&buf);
|
||||||
|
abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
|
||||||
|
ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
ut_assertnull(abuf_uninit_move(&buf, &size));
|
||||||
|
|
||||||
|
/* Check for memory leaks */
|
||||||
|
abuf_uninit(&buf);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_large, 0);
|
||||||
|
|
||||||
|
/* Test abuf_uninit_move() */
|
||||||
|
static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
void *ptr, *orig_ptr;
|
||||||
|
struct abuf buf;
|
||||||
|
size_t size;
|
||||||
|
ulong start;
|
||||||
|
int delta;
|
||||||
|
|
||||||
|
start = ut_check_free();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: crashes on sandbox sometimes due to an apparent bug in
|
||||||
|
* realloc().
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Move an empty buffer */
|
||||||
|
abuf_init(&buf);
|
||||||
|
ut_assertnull(abuf_uninit_move(&buf, &size));
|
||||||
|
ut_asserteq(0, size);
|
||||||
|
ut_assertnull(abuf_uninit_move(&buf, NULL));
|
||||||
|
|
||||||
|
/* Move an unallocated buffer */
|
||||||
|
abuf_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
ptr = abuf_uninit_move(&buf, &size);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, size);
|
||||||
|
ut_asserteq_str(ptr, test_data);
|
||||||
|
ut_assertnonnull(ptr);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Check that freeing it frees the only allocation */
|
||||||
|
delta = ut_check_delta(start);
|
||||||
|
ut_assert(delta > 0);
|
||||||
|
free(ptr);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
/* Move an allocated buffer */
|
||||||
|
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
|
||||||
|
orig_ptr = buf.data;
|
||||||
|
strcpy(orig_ptr, test_data);
|
||||||
|
|
||||||
|
delta = ut_check_delta(start);
|
||||||
|
ut_assert(delta > 0);
|
||||||
|
ptr = abuf_uninit_move(&buf, &size);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, size);
|
||||||
|
ut_assertnonnull(ptr);
|
||||||
|
ut_asserteq_ptr(ptr, orig_ptr);
|
||||||
|
ut_asserteq_str(ptr, test_data);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Check there was no new allocation */
|
||||||
|
ut_asserteq(delta, ut_check_delta(start));
|
||||||
|
|
||||||
|
/* Check that freeing it frees the only allocation */
|
||||||
|
free(ptr);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
/* Move an unallocated buffer, without the size */
|
||||||
|
abuf_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
ptr = abuf_uninit_move(&buf, NULL);
|
||||||
|
ut_asserteq_str(ptr, test_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_uninit_move, 0);
|
||||||
|
|
||||||
|
/* Test abuf_uninit() */
|
||||||
|
static int lib_test_abuf_uninit(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
|
||||||
|
/* Nothing in the buffer */
|
||||||
|
abuf_init(&buf);
|
||||||
|
abuf_uninit(&buf);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
/* Not allocated */
|
||||||
|
abuf_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
abuf_uninit(&buf);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_uninit, 0);
|
||||||
|
|
||||||
|
/* Test abuf_init_set() */
|
||||||
|
static int lib_test_abuf_init_set(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
|
||||||
|
abuf_init_set(&buf, test_data, TEST_DATA_LEN);
|
||||||
|
ut_asserteq_ptr(test_data, buf.data);
|
||||||
|
ut_asserteq(TEST_DATA_LEN, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_init_set, 0);
|
||||||
|
|
||||||
|
/* Test abuf_init_move() */
|
||||||
|
static int lib_test_abuf_init_move(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: crashes on sandbox sometimes due to an apparent bug in
|
||||||
|
* realloc().
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ptr = strdup(test_data);
|
||||||
|
ut_assertnonnull(ptr);
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
|
||||||
|
abuf_init_move(&buf, ptr, TEST_DATA_LEN);
|
||||||
|
ut_asserteq_ptr(ptr, abuf_data(&buf));
|
||||||
|
ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
|
||||||
|
ut_asserteq(true, buf.alloced);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_init_move, 0);
|
||||||
|
|
||||||
|
/* Test abuf_init() */
|
||||||
|
static int lib_test_abuf_init(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
|
||||||
|
buf.data = &buf;
|
||||||
|
buf.size = 123;
|
||||||
|
buf.alloced = true;
|
||||||
|
abuf_init(&buf);
|
||||||
|
ut_assertnull(buf.data);
|
||||||
|
ut_asserteq(0, buf.size);
|
||||||
|
ut_asserteq(false, buf.alloced);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_init, 0);
|
|
@ -23,6 +23,8 @@
|
||||||
/* Allow for copying up to 32 bytes */
|
/* Allow for copying up to 32 bytes */
|
||||||
#define BUFLEN (SWEEP + 33)
|
#define BUFLEN (SWEEP + 33)
|
||||||
|
|
||||||
|
#define TEST_STR "hello"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_buffer() - initialize buffer
|
* init_buffer() - initialize buffer
|
||||||
*
|
*
|
||||||
|
@ -193,3 +195,33 @@ static int lib_memmove(struct unit_test_state *uts)
|
||||||
}
|
}
|
||||||
|
|
||||||
LIB_TEST(lib_memmove, 0);
|
LIB_TEST(lib_memmove, 0);
|
||||||
|
|
||||||
|
/** lib_memdup() - unit test for memdup() */
|
||||||
|
static int lib_memdup(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
char buf[BUFLEN];
|
||||||
|
size_t len;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
/* Zero size should do nothing */
|
||||||
|
p = memdup(NULL, 0);
|
||||||
|
ut_assertnonnull(p);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
p = memdup(buf, 0);
|
||||||
|
ut_assertnonnull(p);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
strcpy(buf, TEST_STR);
|
||||||
|
len = sizeof(TEST_STR);
|
||||||
|
p = memdup(buf, len);
|
||||||
|
ut_asserteq_mem(p, buf, len);
|
||||||
|
|
||||||
|
q = memdup(p, len);
|
||||||
|
ut_asserteq_mem(q, buf, len);
|
||||||
|
free(q);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_memdup, 0);
|
||||||
|
|
|
@ -9,6 +9,11 @@ config MKIMAGE_DTC_PATH
|
||||||
some cases the system dtc may not support all required features
|
some cases the system dtc may not support all required features
|
||||||
and the path to a different version should be given here.
|
and the path to a different version should be given here.
|
||||||
|
|
||||||
|
config TOOLS_CRC32
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable CRC32 support in the tools builds
|
||||||
|
|
||||||
config TOOLS_LIBCRYPTO
|
config TOOLS_LIBCRYPTO
|
||||||
bool "Use OpenSSL's libcrypto library for host tools"
|
bool "Use OpenSSL's libcrypto library for host tools"
|
||||||
default y
|
default y
|
||||||
|
@ -20,4 +25,69 @@ config TOOLS_LIBCRYPTO
|
||||||
This selection does not affect target features, such as runtime FIT
|
This selection does not affect target features, such as runtime FIT
|
||||||
signature verification.
|
signature verification.
|
||||||
|
|
||||||
|
config TOOLS_FIT
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable FIT support in the tools builds.
|
||||||
|
|
||||||
|
config TOOLS_FIT_FULL_CHECK
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Do a full check of the FIT before using it in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_FIT_PRINT
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Print the content of the FIT verbosely in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_FIT_RSASSA_PSS
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Support the rsassa-pss signature scheme in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_FIT_SIGNATURE
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable signature verification of FIT uImages in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_FIT_SIGNATURE_MAX_SIZE
|
||||||
|
hex
|
||||||
|
depends on TOOLS_FIT_SIGNATURE
|
||||||
|
default 0x10000000
|
||||||
|
|
||||||
|
config TOOLS_FIT_VERBOSE
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Support verbose FIT output in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_MD5
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable MD5 support in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_OF_LIBFDT
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable libfdt support in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_SHA1
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable SHA1 support in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_SHA256
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable SHA256 support in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_SHA384
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable SHA384 support in the tools builds
|
||||||
|
|
||||||
|
config TOOLS_SHA512
|
||||||
|
def_bool y
|
||||||
|
help
|
||||||
|
Enable SHA512 support in the tools builds
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -113,6 +113,7 @@ dumpimage-mkimage-objs := aisimage.o \
|
||||||
lib/fdtdec_common.o \
|
lib/fdtdec_common.o \
|
||||||
lib/fdtdec.o \
|
lib/fdtdec.o \
|
||||||
common/image.o \
|
common/image.o \
|
||||||
|
common/image-host.o \
|
||||||
imagetool.o \
|
imagetool.o \
|
||||||
imximage.o \
|
imximage.o \
|
||||||
imx8image.o \
|
imx8image.o \
|
||||||
|
|
Loading…
Reference in a new issue