From 930c887e0fb88dcf1907f268960330c17999b5a3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:06 -0600 Subject: lib: Add memdup() Add a function to duplicate a memory region, a little like strdup(). Signed-off-by: Simon Glass --- include/linux/string.h | 13 +++++++++++++ lib/string.c | 13 +++++++++++++ test/lib/string.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index dd255f2..3169c93 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -129,6 +129,19 @@ extern void * memchr(const void *,int,__kernel_size_t); void *memchr_inv(const void *, int, size_t); #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 long ustrtoull(const char *cp, char **endp, unsigned int base); diff --git a/lib/string.c b/lib/string.c index ba176fb..78bd65c 100644 --- a/lib/string.c +++ b/lib/string.c @@ -659,6 +659,19 @@ void * memscan(void * addr, int c, size_t size) } #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 /** * strstr - Find the first substring in a %NUL terminated string diff --git a/test/lib/string.c b/test/lib/string.c index 64234be..5dcf4d6 100644 --- a/test/lib/string.c +++ b/test/lib/string.c @@ -23,6 +23,8 @@ /* Allow for copying up to 32 bytes */ #define BUFLEN (SWEEP + 33) +#define TEST_STR "hello" + /** * init_buffer() - initialize buffer * @@ -193,3 +195,33 @@ static int lib_memmove(struct unit_test_state *uts) } 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); -- cgit v1.1 From 67bc59df05331eaac56cd0a00219d1386130aee2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:07 -0600 Subject: Add support for an owned buffer When passing a data buffer back from a function, it is not always clear who owns the buffer, i.e. who is responsible for freeing the memory used. An example of this is where multiple files are decompressed from the firmware image, using a temporary buffer for reading (since the compressed data has to live somewhere) and producing a temporary or permanent buffer with the resuilts. Where the firmware image can be memory-mapped, as on x86, the compressed data does not need to be buffered, but the complexity of having a buffer which is either allocated or not, makes the code hard to understand. Introduce a new 'abuf' which supports simple buffer operations: - encapsulating a buffer and its size - either allocated with malloc() or not - able to be reliably freed if necessary - able to be converted to an allocated buffer if needed This simple API makes it easier to deal with allocated and memory-mapped buffers. Signed-off-by: Simon Glass --- include/abuf.h | 159 +++++++++++++++++++++++++ lib/Makefile | 1 + lib/abuf.c | 109 +++++++++++++++++ test/lib/Makefile | 1 + test/lib/abuf.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 614 insertions(+) create mode 100644 include/abuf.h create mode 100644 lib/abuf.c create mode 100644 test/lib/abuf.c diff --git a/include/abuf.h b/include/abuf.h new file mode 100644 index 0000000..d230f72 --- /dev/null +++ b/include/abuf.h @@ -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 + */ + +#ifndef __ABUF_H +#define __ABUF_H + +#include + +/** + * 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 diff --git a/lib/Makefile b/lib/Makefile index 962470f..454396f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -134,6 +134,7 @@ obj-$(CONFIG_OID_REGISTRY) += oid_registry.o obj-$(CONFIG_SSCANF) += sscanf.o endif +obj-y += abuf.o obj-y += date.o obj-y += rtc-lib.o obj-$(CONFIG_LIB_ELF) += elf.o diff --git a/lib/abuf.c b/lib/abuf.c new file mode 100644 index 0000000..4b17e0b --- /dev/null +++ b/lib/abuf.c @@ -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 + */ + +#include +#include +#include +#include +#include + +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; +} diff --git a/test/lib/Makefile b/test/lib/Makefile index 6fd0514..d244bb4 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -3,6 +3,7 @@ # (C) Copyright 2018 # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc obj-y += cmd_ut_lib.o +obj-y += abuf.o obj-$(CONFIG_EFI_LOADER) += efi_device_path.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o diff --git a/test/lib/abuf.c b/test/lib/abuf.c new file mode 100644 index 0000000..086c9b2 --- /dev/null +++ b/test/lib/abuf.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include + +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); -- cgit v1.1 From c45b7920db21c8e0be89b15ea034ff3e9edb8e1d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:08 -0600 Subject: compiler: Add a comment to host_build() This function should have a comment explaining what it does. Add one. Signed-off-by: Simon Glass --- include/compiler.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/compiler.h b/include/compiler.h index 27b9843..67e5205 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -151,6 +151,11 @@ typedef unsigned long int uintptr_t; #define MEM_SUPPORT_64BIT_DATA 0 #endif +/** + * host_build() - check if we are building for the host + * + * @return true if building for the host, false if for a target + */ static inline bool host_build(void) { #ifdef USE_HOSTCC return true; -- cgit v1.1 From 94d0a2efc0315e2c5e3b62a7420292f0ce058079 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:09 -0600 Subject: zstd: Create a function for use from U-Boot The existing zstd API requires the same sequence of calls to perform its task. Create a helper for U-Boot, to avoid code duplication, as is done with other compression algorithms. Make use of of this from the image code. Note that the zstd code lacks a test in test/compression.c and this should be added by the maintainer. Signed-off-by: Simon Glass --- common/image.c | 50 ++++++++-------------------------------- include/linux/zstd.h | 11 +++++++++ lib/zstd/Makefile | 2 +- lib/zstd/zstd.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 42 deletions(-) create mode 100644 lib/zstd/zstd.c diff --git a/common/image.c b/common/image.c index 8ac5708..2437223 100644 --- a/common/image.c +++ b/common/image.c @@ -22,6 +22,7 @@ #include #endif +#include #include #include @@ -527,50 +528,17 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, #ifndef USE_HOSTCC #if CONFIG_IS_ENABLED(ZSTD) case IH_COMP_ZSTD: { - size_t size = unc_len; - ZSTD_DStream *dstream; - ZSTD_inBuffer in_buf; - ZSTD_outBuffer out_buf; - void *workspace; - size_t wsize; - - wsize = ZSTD_DStreamWorkspaceBound(image_len); - workspace = malloc(wsize); - if (!workspace) { - debug("%s: cannot allocate workspace of size %zu\n", __func__, - wsize); - return -1; - } - - dstream = ZSTD_initDStream(image_len, workspace, wsize); - if (!dstream) { - printf("%s: ZSTD_initDStream failed\n", __func__); - return ZSTD_getErrorCode(ret); - } - - in_buf.src = image_buf; - in_buf.pos = 0; - in_buf.size = image_len; + struct abuf in, out; - out_buf.dst = load_buf; - out_buf.pos = 0; - out_buf.size = size; - - 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)); - return ZSTD_getErrorCode(ret); - } - - if (in_buf.pos >= image_len || !ret) - break; + abuf_init_set(&in, image_buf, image_len); + abuf_init_set(&in, load_buf, unc_len); + ret = zstd_decompress(&in, &out); + if (ret < 0) { + printf("ZSTD decompression failed\n"); + return ret; } - image_len = out_buf.pos; + image_len = ret; break; } diff --git a/include/linux/zstd.h b/include/linux/zstd.h index 724f693..35ba4c9 100644 --- a/include/linux/zstd.h +++ b/include/linux/zstd.h @@ -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 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 */ diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile index 33c1df4..1217089 100644 --- a/lib/zstd/Makefile +++ b/lib/zstd/Makefile @@ -1,4 +1,4 @@ obj-y += zstd_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 diff --git a/lib/zstd/zstd.c b/lib/zstd/zstd.c new file mode 100644 index 0000000..bf9cd19 --- /dev/null +++ b/lib/zstd/zstd.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY LOGC_BOOT + +#include +#include +#include +#include +#include + +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; +} -- cgit v1.1 From 918adf8e07337719750c57be0939824247973b1e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:10 -0600 Subject: btrfs: Use U-Boot API for decompression Use the common function to avoid code duplication. Acked-by: Qu Wenruo Signed-off-by: Simon Glass --- fs/btrfs/compression.c | 51 +++++--------------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 23efefa..7adfbb0 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -6,6 +6,7 @@ */ #include "btrfs.h" +#include #include #include #include @@ -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) { - ZSTD_DStream *dstream; - ZSTD_inBuffer in_buf; - ZSTD_outBuffer out_buf; - void *workspace; - size_t wsize; - u32 res = -1; - - wsize = ZSTD_DStreamWorkspaceBound(ZSTD_BTRFS_MAX_INPUT); - workspace = malloc(wsize); - if (!workspace) { - debug("%s: cannot allocate workspace of size %zu\n", __func__, - wsize); - return -1; - } - - dstream = ZSTD_initDStream(ZSTD_BTRFS_MAX_INPUT, workspace, wsize); - if (!dstream) { - printf("%s: ZSTD_initDStream failed\n", __func__); - goto err_free; - } + struct abuf in, out; - in_buf.src = cbuf; - in_buf.pos = 0; - in_buf.size = clen; + abuf_init_set(&in, (u8 *)cbuf, clen); + abuf_init_set(&out, dbuf, dlen); - 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; + return zstd_decompress(&in, &out); } u32 btrfs_decompress(u8 type, const char *c, u32 clen, char *d, u32 dlen) -- cgit v1.1 From b876eb87e91d6705ef946090af16175dfb5ce1f9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:11 -0600 Subject: image: Avoid switch default in image_decomp() At present this function is full of preprocessor macros. Adjust it to check for an unsupported algorithm after the switch(). This will allow us to drop the macros. Fix up the return-value path and an extra blank line while we are here. Signed-off-by: Simon Glass --- common/image.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/common/image.c b/common/image.c index 2437223..1102483 100644 --- a/common/image.c +++ b/common/image.c @@ -446,7 +446,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, void *load_buf, void *image_buf, ulong image_len, uint unc_len, ulong *load_end) { - int ret = 0; + int ret = -ENOSYS; *load_end = load; print_decomp_msg(comp, type, load == image_start); @@ -458,6 +458,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, */ switch (comp) { case IH_COMP_NONE: + ret = 0; if (load == image_start) break; if (image_len <= unc_len) @@ -539,22 +540,23 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, } image_len = ret; - break; } #endif /* CONFIG_ZSTD */ #endif - default: + } + if (ret == -ENOSYS) { printf("Unimplemented compression type %d\n", comp); - return -ENOSYS; + return ret; } + if (ret) + return ret; *load_end = load + image_len; - return ret; + return 0; } - #ifndef USE_HOSTCC #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** -- cgit v1.1 From 02ace2cd4942da507414b23645cd7bec99f23174 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:12 -0600 Subject: image: Update zstd to avoid reporting error twice The zstd implementation prints the error in image_decomp() which is incorrect and does not match other algorithms. Drop this and let the caller report the error. Signed-off-by: Simon Glass --- common/image.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/common/image.c b/common/image.c index 1102483..62314a9 100644 --- a/common/image.c +++ b/common/image.c @@ -534,12 +534,10 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, abuf_init_set(&in, image_buf, image_len); abuf_init_set(&in, load_buf, unc_len); ret = zstd_decompress(&in, &out); - if (ret < 0) { - printf("ZSTD decompression failed\n"); - return ret; + if (ret >= 0) { + image_len = ret; + ret = 0; } - - image_len = ret; break; } #endif /* CONFIG_ZSTD */ -- cgit v1.1 From 5a4f10d71bfe2b7a5646cf1f96b298805b36df7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:13 -0600 Subject: gzip: Avoid use of u64 The gzip API uses the u64 type in it, which is not available in the host build. This makes it impossible to include the header file. We could make this type available, but it seems unnecessary. Limiting the compression size to that of the 'unsigned long' type seems good enough. On 32-bit machines the limit then becomes 4GB, which likely exceeds available RAM anyway, therefore it should be sufficient. On 64-bit machines this is effectively u64 anyway. Update the header file and implementation to use 'ulong' instead of 'u64'. Add a definition of u32 for the cases that seem to need exactly that length. This should be safe enough. Signed-off-by: Simon Glass --- include/compiler.h | 3 +++ include/gzip.h | 8 ++++---- lib/gunzip.c | 28 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/include/compiler.h b/include/compiler.h index 67e5205..6b0d3bf 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -68,6 +68,9 @@ typedef uint32_t __u32; typedef unsigned int uint; typedef unsigned long ulong; +/* Define these on the host so we can build some target code */ +typedef __u32 u32; + #define uswap_16(x) \ ((((x) & 0xff00) >> 8) | \ (((x) & 0x00ff) << 8)) diff --git a/include/gzip.h b/include/gzip.h index 783acbb..cb4db3d 100644 --- a/include/gzip.h +++ b/include/gzip.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 * 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); /** @@ -74,7 +74,7 @@ void gzwrite_progress_finish(int retcode, u64 totalwritten, u64 totalsize, * @return 0 if OK, -1 on error */ 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 diff --git a/lib/gunzip.c b/lib/gunzip.c index bee3b92..a8e498d 100644 --- a/lib/gunzip.c +++ b/lib/gunzip.c @@ -84,32 +84,32 @@ int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) #ifdef CONFIG_CMD_UNZIP __weak -void gzwrite_progress_init(u64 expectedsize) +void gzwrite_progress_init(ulong expectedsize) { putc('\n'); } __weak void gzwrite_progress(int iteration, - u64 bytes_written, - u64 total_bytes) + ulong bytes_written, + ulong total_bytes) { if (0 == (iteration & 3)) - printf("%llu/%llu\r", bytes_written, total_bytes); + printf("%lu/%lu\r", bytes_written, total_bytes); } __weak void gzwrite_progress_finish(int returnval, - u64 bytes_written, - u64 total_bytes, + ulong bytes_written, + ulong total_bytes, u32 expected_crc, u32 calculated_crc) { 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); } else { - printf("\n\tuncompressed %llu of %llu\n" + printf("\n\tuncompressed %lu of %lu\n" "\tcrcs == 0x%08x/0x%08x\n", bytes_written, total_bytes, expected_crc, calculated_crc); @@ -119,15 +119,15 @@ void gzwrite_progress_finish(int returnval, int gzwrite(unsigned char *src, int len, struct blk_desc *dev, unsigned long szwritebuf, - u64 startoffs, - u64 szexpected) + ulong startoffs, + ulong szexpected) { int i, flags; z_stream s; int r = 0; unsigned char *writebuf; unsigned crc = 0; - u64 totalfilled = 0; + ulong totalfilled = 0; lbaint_t blksperbuf, outblock; u32 expected_crc; u32 payload_size; @@ -142,7 +142,7 @@ int gzwrite(unsigned char *src, int len, } 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); return -1; } @@ -182,12 +182,12 @@ int gzwrite(unsigned char *src, int len, if (szexpected == 0) { szexpected = le32_to_cpu(szuncompressed); } 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); return -1; } 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); return -1; } -- cgit v1.1 From 458b30af66cd41ca8e6f8a52ea4c09cb50d3413d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:14 -0600 Subject: image: Update image_decomp() to avoid ifdefs Adjust this function so that preprocessor macros are not needed. With this, the host build uses more of the same header files as the target build. Rather than definining CONFIG_SYS_MALLOC_LEN, add a CONSERVE_MEMORY define, since that is the purpose of the value. This appears to have no impact on code size from a spot check of a few boards (snow, firefly-rk3288, boston32r2el, m53menlo). Signed-off-by: Simon Glass --- common/image.c | 145 ++++++++++++++++++++++------------------------ configs/sandbox_defconfig | 1 + 2 files changed, 69 insertions(+), 77 deletions(-) diff --git a/common/image.c b/common/image.c index 62314a9..e16d433 100644 --- a/common/image.c +++ b/common/image.c @@ -22,12 +22,9 @@ #include #endif -#include #include -#include #include -#include #include #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT @@ -43,13 +40,6 @@ #include #include -#include -#include -#include -#include -#include -#include - #ifdef CONFIG_CMD_BDI extern int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); @@ -61,7 +51,15 @@ DECLARE_GLOBAL_DATA_PTR; static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, int verify); #endif + +/* Set this if we have less than 4 MB of malloc() space */ +#if CONFIG_SYS_MALLOC_LEN < (4096 * 1024) +#define CONSERVE_MEMORY true #else +#define CONSERVE_MEMORY false +#endif + +#else /* USE_HOSTCC */ #include "mkimage.h" #include #include @@ -70,10 +68,23 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #ifndef __maybe_unused # define __maybe_unused /* unimplemented */ #endif + +#define CONSERVE_MEMORY false + #endif /* !USE_HOSTCC*/ -#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #ifndef CONFIG_SYS_BARGSIZE #define CONFIG_SYS_BARGSIZE 512 @@ -466,83 +477,63 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, else ret = -ENOSPC; break; -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(GZIP) - case IH_COMP_GZIP: { - ret = gunzip(load_buf, unc_len, image_buf, &image_len); + case IH_COMP_GZIP: + if (!host_build() && CONFIG_IS_ENABLED(GZIP)) + ret = gunzip(load_buf, unc_len, image_buf, &image_len); break; - } -#endif /* CONFIG_GZIP */ -#endif -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(BZIP2) - case IH_COMP_BZIP2: { - uint size = unc_len; + case IH_COMP_BZIP2: + if (!host_build() && CONFIG_IS_ENABLED(BZIP2)) { + uint size = unc_len; - /* - * If we've got less than 4 MB of malloc() space, - * use slower decompression algorithm which requires - * at most 2300 KB of memory. - */ - ret = BZ2_bzBuffToBuffDecompress(load_buf, &size, - image_buf, image_len, - CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); - image_len = size; + /* + * If we've got less than 4 MB of malloc() space, + * use slower decompression algorithm which requires + * at most 2300 KB of memory. + */ + ret = BZ2_bzBuffToBuffDecompress(load_buf, &size, + image_buf, image_len, CONSERVE_MEMORY, 0); + image_len = size; + } break; - } -#endif /* CONFIG_BZIP2 */ -#endif -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(LZMA) - case IH_COMP_LZMA: { - SizeT lzma_len = unc_len; + case IH_COMP_LZMA: + if (!host_build() && CONFIG_IS_ENABLED(LZMA)) { + SizeT lzma_len = unc_len; - ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, - image_buf, image_len); - image_len = lzma_len; + ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, + image_buf, image_len); + image_len = lzma_len; + } break; - } -#endif /* CONFIG_LZMA */ -#endif -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(LZO) - case IH_COMP_LZO: { - size_t size = unc_len; + case IH_COMP_LZO: + if (!host_build() && CONFIG_IS_ENABLED(LZO)) { + size_t size = unc_len; - ret = lzop_decompress(image_buf, image_len, load_buf, &size); - image_len = size; + ret = lzop_decompress(image_buf, image_len, load_buf, &size); + image_len = size; + } break; - } -#endif /* CONFIG_LZO */ -#endif -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(LZ4) - case IH_COMP_LZ4: { - size_t size = unc_len; + case IH_COMP_LZ4: + if (!host_build() && CONFIG_IS_ENABLED(LZ4)) { + size_t size = unc_len; - ret = ulz4fn(image_buf, image_len, load_buf, &size); - image_len = size; + ret = ulz4fn(image_buf, image_len, load_buf, &size); + image_len = size; + } break; - } -#endif /* CONFIG_LZ4 */ -#endif -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(ZSTD) - case IH_COMP_ZSTD: { - struct abuf in, out; - - abuf_init_set(&in, image_buf, image_len); - abuf_init_set(&in, load_buf, unc_len); - ret = zstd_decompress(&in, &out); - if (ret >= 0) { - image_len = ret; - ret = 0; + case IH_COMP_ZSTD: + if (!host_build() && CONFIG_IS_ENABLED(ZSTD)) { + struct abuf in, out; + + abuf_init_set(&in, image_buf, image_len); + abuf_init_set(&in, load_buf, unc_len); + ret = zstd_decompress(&in, &out); + if (ret >= 0) { + image_len = ret; + ret = 0; + } } break; } -#endif /* CONFIG_ZSTD */ -#endif - } if (ret == -ENOSYS) { printf("Unimplemented compression type %d\n", comp); return ret; @@ -960,7 +951,7 @@ int get_table_entry_id(const table_entry_t *table, const table_entry_t *t; for (t = table; t->id >= 0; ++t) { -#ifdef CONFIG_NEEDS_MANUAL_RELOC +#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC) if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0) #else if (t->sname && strcasecmp(t->sname, name) == 0) diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index f1067b9..d601677 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -56,6 +56,7 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_MEM_SEARCH=y CONFIG_CMD_MX_CYCLIC=y CONFIG_CMD_MEMTEST=y +CONFIG_CMD_UNZIP=y CONFIG_CMD_BIND=y CONFIG_CMD_DEMO=y CONFIG_CMD_GPIO=y -- cgit v1.1 From 41506ff5a51fb95896683bc8def8dbf53ef93de1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:15 -0600 Subject: image: Split board code out into its own file To avoid a large #ifdef in the image.c file, move the affected code into a separate file. Avoid any style fix-ups for easier review. Those are in the next patch. Signed-off-by: Simon Glass --- common/Makefile | 2 +- common/image-board.c | 925 +++++++++++++++++++++++++++++++++++++++++++++++++++ common/image.c | 925 +-------------------------------------------------- 3 files changed, 928 insertions(+), 924 deletions(-) create mode 100644 common/image-board.c diff --git a/common/Makefile b/common/Makefile index fb8173a..e783902 100644 --- a/common/Makefile +++ b/common/Makefile @@ -101,7 +101,7 @@ obj-y += malloc_simple.o endif endif -obj-y += image.o +obj-y += image.o image-board.o obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o obj-$(CONFIG_ANDROID_AB) += android_ab.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o diff --git a/common/image-board.c b/common/image-board.c new file mode 100644 index 0000000..63cbf5f --- /dev/null +++ b/common/image-board.c @@ -0,0 +1,925 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_BARGSIZE +#define CONFIG_SYS_BARGSIZE 512 +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) +/** + * 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, uint8_t 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; +} +#endif + +/*****************************************************************************/ +/* 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); +#if CONFIG_IS_ENABLED(FIT) + } else if (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 (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); +#endif + } 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; +#endif +#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT + if (fdt_check_header(img_addr) == 0) + return IMAGE_FORMAT_FIT; +#endif +#ifdef CONFIG_ANDROID_BOOT_IMAGE + if (android_image_check_header(img_addr) == 0) + return IMAGE_FORMAT_ANDROID; +#endif + + 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 IMAGE_ENABLE_FIT + if (images->fit_uname_cfg) + return 1; +#endif + 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. + * Curently 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, + uint8_t arch, ulong *rd_start, ulong *rd_end) +{ + ulong rd_addr, rd_load; + ulong rd_data, rd_len; +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + const image_header_t *rd_hdr; +#endif + void *buf; +#ifdef CONFIG_SUPPORT_RAW_INITRD + char *end; +#endif +#if IMAGE_ENABLE_FIT + const char *fit_uname_config = images->fit_uname_cfg; + const char *fit_uname_ramdisk = NULL; + ulong default_addr; + int rd_noffset; +#endif + const char *select = NULL; + + *rd_start = 0; + *rd_end = 0; + +#ifdef CONFIG_ANDROID_BOOT_IMAGE + /* + * 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]; +#endif + + 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 = rd_data = 0; + } else if (select || genimg_has_config(images)) { +#if IMAGE_ENABLE_FIT + if (select) { + /* + * 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 +#endif + { + rd_addr = hextoul(select, NULL); + debug("* ramdisk: cmdline image address = " + "0x%08lx\n", + rd_addr); + } +#if IMAGE_ENABLE_FIT + } else { + /* use FIT configuration provided in first bootm + * command argument. If the property is not defined, + * quit silently. + */ + 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 0; + else if (rd_noffset < 0) + return 1; + } +#endif + + /* + * 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); + switch (genimg_get_format(buf)) { +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + case IMAGE_FORMAT_LEGACY: + 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 == NULL) + return 1; + + rd_data = image_get_data(rd_hdr); + rd_len = image_get_data_size(rd_hdr); + rd_load = image_get_load(rd_hdr); + break; +#endif +#if IMAGE_ENABLE_FIT + case IMAGE_FORMAT_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_data, &rd_len); + if (rd_noffset < 0) + return 1; + + images->fit_hdr_rd = map_sysmem(rd_addr, 0); + images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; + break; +#endif +#ifdef CONFIG_ANDROID_BOOT_IMAGE + case IMAGE_FORMAT_ANDROID: + android_image_get_ramdisk((void *)images->os.start, + &rd_data, &rd_len); + break; +#endif + default: +#ifdef CONFIG_SUPPORT_RAW_INITRD + end = NULL; + if (select) + end = strchr(select, ':'); + if (end) { + rd_len = hextoul(++end, NULL); + rd_data = rd_addr; + } else +#endif + { + puts("Wrong Ramdisk Image Format\n"); + rd_data = rd_len = rd_load = 0; + return 1; + } + } + } 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 = 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; +} + +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH +/** + * 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); + +#ifdef CONFIG_MP + /* + * Ensure the image is flushed to memory to handle + * AMP boot scenarios in which we might not be + * HW cache coherent + */ + flush_cache((unsigned long)*initrd_start, + ALIGN(rd_len, ARCH_DMA_MINALIGN)); +#endif + 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; +} +#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ + +int boot_get_setup(bootm_headers_t *images, uint8_t arch, + ulong *setup_start, ulong *setup_len) +{ +#if IMAGE_ENABLE_FIT + return boot_get_setup_fit(images, arch, setup_start, setup_len); +#else + return -ENOENT; +#endif +} + +#if IMAGE_ENABLE_FIT +#if defined(CONFIG_FPGA) +int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, + uint8_t 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 */ + + /* 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; +} +#endif + +static void fit_loadable_process(uint8_t 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, + uint8_t 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; + uint8_t 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; +} +#endif + +#ifdef CONFIG_SYS_BOOT_GET_CMDLINE +/** + * 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 == NULL) + return -1; + + s = env_get("bootargs"); + if (!s) + s = ""; + + strcpy(cmdline, s); + + *cmd_start = (ulong) & cmdline[0]; + *cmd_end = *cmd_start + strlen(cmdline); + + debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); + + return 0; +} +#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ + +#ifdef CONFIG_SYS_BOOT_GET_KBD +/** + * 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 == NULL) + return -1; + + **kbd = *(gd->bd); + + debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); + +#if defined(DEBUG) && defined(CONFIG_CMD_BDI) + do_bdinfo(NULL, 0, 0, NULL); +#endif + + return 0; +} +#endif /* CONFIG_SYS_BOOT_GET_KBD */ + +#ifdef CONFIG_LMB +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 (IMAGE_ENABLE_OF_LIBFDT) + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + + if (IMAGE_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 (IMAGE_ENABLE_OF_LIBFDT) { + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret; + } + + if (IMAGE_ENABLE_OF_LIBFDT && of_size) { + ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); + if (ret) + return ret; + } + + return 0; +} +#endif /* CONFIG_LMB */ diff --git a/common/image.c b/common/image.c index e16d433..ed7f188 100644 --- a/common/image.c +++ b/common/image.c @@ -8,15 +8,11 @@ #ifndef USE_HOSTCC #include -#include -#include #include #include #include #include -#include #include -#include #ifdef CONFIG_SHOW_BOOT_PROGRESS #include @@ -24,14 +20,9 @@ #include -#include -#include - #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT #include #include -#include -#include #endif #include @@ -47,11 +38,6 @@ extern int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, - int verify); -#endif - /* Set this if we have less than 4 MB of malloc() space */ #if CONFIG_SYS_MALLOC_LEN < (4096 * 1024) #define CONSERVE_MEMORY true @@ -63,7 +49,6 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #include "mkimage.h" #include #include -#include #ifndef __maybe_unused # define __maybe_unused /* unimplemented */ @@ -76,6 +61,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #include #include #include +#include #include #include #include @@ -86,10 +72,6 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #include #include -#ifndef CONFIG_SYS_BARGSIZE -#define CONFIG_SYS_BARGSIZE 512 -#endif - static const table_entry_t uimage_arch[] = { { IH_ARCH_INVALID, "invalid", "Invalid ARCH", }, { IH_ARCH_ALPHA, "alpha", "Alpha", }, @@ -546,180 +528,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, return 0; } -#ifndef USE_HOSTCC -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -/** - * 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, uint8_t 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; -} -#endif -#endif /* !USE_HOSTCC */ - -/*****************************************************************************/ -/* Shared dual-format routines */ -/*****************************************************************************/ -#ifndef USE_HOSTCC -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 */ -} -#else /* USE_HOSTCC */ +#ifdef USE_HOSTCC void memmove_wd(void *to, void *from, size_t len, ulong chunksz) { memmove(to, from, len); @@ -982,733 +791,3 @@ int genimg_get_comp_id(const char *name) { return (get_table_entry_id(uimage_comp, "Compression", name)); } - -#ifndef USE_HOSTCC -/** - * 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); -#if CONFIG_IS_ENABLED(FIT) - } else if (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 (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); -#endif - } 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; -#endif -#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT - if (fdt_check_header(img_addr) == 0) - return IMAGE_FORMAT_FIT; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - if (android_image_check_header(img_addr) == 0) - return IMAGE_FORMAT_ANDROID; -#endif - - 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 IMAGE_ENABLE_FIT - if (images->fit_uname_cfg) - return 1; -#endif - 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. - * Curently 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, - uint8_t arch, ulong *rd_start, ulong *rd_end) -{ - ulong rd_addr, rd_load; - ulong rd_data, rd_len; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - const image_header_t *rd_hdr; -#endif - void *buf; -#ifdef CONFIG_SUPPORT_RAW_INITRD - char *end; -#endif -#if IMAGE_ENABLE_FIT - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_ramdisk = NULL; - ulong default_addr; - int rd_noffset; -#endif - const char *select = NULL; - - *rd_start = 0; - *rd_end = 0; - -#ifdef CONFIG_ANDROID_BOOT_IMAGE - /* - * 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]; -#endif - - 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 = rd_data = 0; - } else if (select || genimg_has_config(images)) { -#if IMAGE_ENABLE_FIT - if (select) { - /* - * 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 -#endif - { - rd_addr = hextoul(select, NULL); - debug("* ramdisk: cmdline image address = " - "0x%08lx\n", - rd_addr); - } -#if IMAGE_ENABLE_FIT - } else { - /* use FIT configuration provided in first bootm - * command argument. If the property is not defined, - * quit silently. - */ - 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 0; - else if (rd_noffset < 0) - return 1; - } -#endif - - /* - * 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); - switch (genimg_get_format(buf)) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: - 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 == NULL) - return 1; - - rd_data = image_get_data(rd_hdr); - rd_len = image_get_data_size(rd_hdr); - rd_load = image_get_load(rd_hdr); - break; -#endif -#if IMAGE_ENABLE_FIT - case IMAGE_FORMAT_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_data, &rd_len); - if (rd_noffset < 0) - return 1; - - images->fit_hdr_rd = map_sysmem(rd_addr, 0); - images->fit_uname_rd = fit_uname_ramdisk; - images->fit_noffset_rd = rd_noffset; - break; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - case IMAGE_FORMAT_ANDROID: - android_image_get_ramdisk((void *)images->os.start, - &rd_data, &rd_len); - break; -#endif - default: -#ifdef CONFIG_SUPPORT_RAW_INITRD - end = NULL; - if (select) - end = strchr(select, ':'); - if (end) { - rd_len = hextoul(++end, NULL); - rd_data = rd_addr; - } else -#endif - { - puts("Wrong Ramdisk Image Format\n"); - rd_data = rd_len = rd_load = 0; - return 1; - } - } - } 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 = 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; -} - -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH -/** - * 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); - -#ifdef CONFIG_MP - /* - * Ensure the image is flushed to memory to handle - * AMP boot scenarios in which we might not be - * HW cache coherent - */ - flush_cache((unsigned long)*initrd_start, - ALIGN(rd_len, ARCH_DMA_MINALIGN)); -#endif - 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; -} -#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ - -int boot_get_setup(bootm_headers_t *images, uint8_t arch, - ulong *setup_start, ulong *setup_len) -{ -#if IMAGE_ENABLE_FIT - return boot_get_setup_fit(images, arch, setup_start, setup_len); -#else - return -ENOENT; -#endif -} - -#if IMAGE_ENABLE_FIT -#if defined(CONFIG_FPGA) -int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, - uint8_t 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 */ - - /* 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; -} -#endif - -static void fit_loadable_process(uint8_t 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, - uint8_t 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; - uint8_t 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; -} -#endif - -#ifdef CONFIG_SYS_BOOT_GET_CMDLINE -/** - * 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 == NULL) - return -1; - - s = env_get("bootargs"); - if (!s) - s = ""; - - strcpy(cmdline, s); - - *cmd_start = (ulong) & cmdline[0]; - *cmd_end = *cmd_start + strlen(cmdline); - - debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); - - return 0; -} -#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ - -#ifdef CONFIG_SYS_BOOT_GET_KBD -/** - * 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 == NULL) - return -1; - - **kbd = *(gd->bd); - - debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); - -#if defined(DEBUG) && defined(CONFIG_CMD_BDI) - do_bdinfo(NULL, 0, 0, NULL); -#endif - - return 0; -} -#endif /* CONFIG_SYS_BOOT_GET_KBD */ - -#ifdef CONFIG_LMB -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 (IMAGE_ENABLE_OF_LIBFDT) - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); - - if (IMAGE_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 (IMAGE_ENABLE_OF_LIBFDT) { - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; - } - - if (IMAGE_ENABLE_OF_LIBFDT && of_size) { - ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); - if (ret) - return ret; - } - - return 0; -} -#endif /* CONFIG_LMB */ -#endif /* !USE_HOSTCC */ -- cgit v1.1 From 3d2a47f11c1e77e79aa4f04dc787b25054822267 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:16 -0600 Subject: image: Fix up checkpatch warnings in image-board.c Tidy up the warnings. Signed-off-by: Simon Glass --- common/image-board.c | 142 ++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index 63cbf5f..835751e 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -41,8 +41,8 @@ DECLARE_GLOBAL_DATA_PTR; * 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, uint8_t arch, - int verify) +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; @@ -77,7 +77,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, !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)); + genimg_get_arch_name(arch)); bootstage_error(BOOTSTAGE_ID_RAMDISK); return NULL; } @@ -94,7 +94,7 @@ 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) + int flags) { switch (op) { case env_op_create: @@ -112,6 +112,7 @@ 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; @@ -131,6 +132,7 @@ 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; @@ -155,6 +157,7 @@ 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; @@ -179,6 +182,7 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) } while (len > 0) { size_t tail = (len > chunksz) ? chunksz : len; + WATCHDOG_RESET(); if (to > from) { to -= tail; @@ -212,8 +216,8 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) * kernel start address */ ulong genimg_get_kernel_addr_fit(char * const img_addr, - const char **fit_uname_config, - const char **fit_uname_kernel) + const char **fit_uname_config, + const char **fit_uname_kernel) { ulong kernel_addr; @@ -319,7 +323,7 @@ int genimg_has_config(bootm_headers_t *images) * @rd_end: pointer to a ulong variable, will hold ramdisk end * * boot_get_ramdisk() is responsible for finding a valid ramdisk image. - * Curently supported are the following ramdisk sources: + * Currently supported are the following ramdisk sources: * - multicomponent kernel/ramdisk image, * - commandline provided address of decicated ramdisk image. * @@ -332,7 +336,7 @@ int genimg_has_config(bootm_headers_t *images) * 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, - uint8_t arch, ulong *rd_start, ulong *rd_end) + u8 arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; ulong rd_data, rd_len; @@ -372,7 +376,8 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, */ if (select && strcmp(select, "-") == 0) { debug("## Skipping init Ramdisk\n"); - rd_len = rd_data = 0; + rd_len = 0; + rd_data = 0; } else if (select || genimg_has_config(images)) { #if IMAGE_ENABLE_FIT if (select) { @@ -389,21 +394,19 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, 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); + 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); + &rd_addr, + &fit_uname_ramdisk)) { + debug("* ramdisk: subimage '%s' from image at 0x%08lx\n", + fit_uname_ramdisk, rd_addr); } else #endif { rd_addr = hextoul(select, NULL); - debug("* ramdisk: cmdline image address = " - "0x%08lx\n", - rd_addr); + debug("* ramdisk: cmdline image address = 0x%08lx\n", + rd_addr); } #if IMAGE_ENABLE_FIT } else { @@ -413,7 +416,8 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, */ rd_addr = map_to_sysmem(images->fit_hdr_os); rd_noffset = fit_get_node_from_config(images, - FIT_RAMDISK_PROP, rd_addr); + FIT_RAMDISK_PROP, + rd_addr); if (rd_noffset == -ENOENT) return 0; else if (rd_noffset < 0) @@ -430,14 +434,14 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - printf("## Loading init Ramdisk from Legacy " - "Image at %08lx ...\n", rd_addr); + 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); + images->verify); - if (rd_hdr == NULL) + if (!rd_hdr) return 1; rd_data = image_get_data(rd_hdr); @@ -448,12 +452,12 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, #if IMAGE_ENABLE_FIT case IMAGE_FORMAT_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_data, &rd_len); + rd_addr, &fit_uname_ramdisk, + &fit_uname_config, arch, + IH_TYPE_RAMDISK, + BOOTSTAGE_ID_FIT_RD_START, + FIT_LOAD_OPTIONAL_NON_ZERO, + &rd_data, &rd_len); if (rd_noffset < 0) return 1; @@ -465,7 +469,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: android_image_get_ramdisk((void *)images->os.start, - &rd_data, &rd_len); + &rd_data, &rd_len); break; #endif default: @@ -480,22 +484,22 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, #endif { puts("Wrong Ramdisk Image Format\n"); - rd_data = rd_len = rd_load = 0; + rd_data = 0; + rd_len = 0; + rd_load = 0; return 1; } } } else if (images->legacy_hdr_valid && image_check_type(&images->legacy_hdr_os_copy, - IH_TYPE_MULTI)) { - + 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); + 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 { @@ -503,7 +507,8 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, * no initrd image */ bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK); - rd_len = rd_data = 0; + rd_len = 0; + rd_data = 0; } if (!rd_data) { @@ -513,7 +518,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, *rd_end = rd_data + rd_len; } debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", - *rd_start, *rd_end); + *rd_start, *rd_end); return 0; } @@ -541,7 +546,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, * -1 - failure */ 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) { char *s; ulong initrd_high; @@ -559,9 +564,8 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, 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); + initrd_high, initrd_copy_to_ram); if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ @@ -585,10 +589,10 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, *initrd_end = *initrd_start + rd_len; printf(" Loading Ramdisk to %08lx, end %08lx ... ", - *initrd_start, *initrd_end); + *initrd_start, *initrd_end); memmove_wd((void *)*initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); + (void *)rd_data, rd_len, CHUNKSZ); #ifdef CONFIG_MP /* @@ -606,7 +610,7 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, *initrd_end = 0; } debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", - *initrd_start, *initrd_end); + *initrd_start, *initrd_end); return 0; @@ -615,7 +619,7 @@ error: } #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ -int boot_get_setup(bootm_headers_t *images, uint8_t arch, +int boot_get_setup(bootm_headers_t *images, u8 arch, ulong *setup_start, ulong *setup_len) { #if IMAGE_ENABLE_FIT @@ -628,7 +632,7 @@ int boot_get_setup(bootm_headers_t *images, uint8_t arch, #if IMAGE_ENABLE_FIT #if defined(CONFIG_FPGA) int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, - uint8_t arch, const ulong *ld_start, ulong * const ld_len) + u8 arch, const ulong *ld_start, ulong * const ld_len) { ulong tmp_img_addr, img_data, img_len; void *buf; @@ -666,7 +670,7 @@ int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, fit_img_result = fit_image_load(images, tmp_img_addr, (const char **)&uname, - &(images->fit_uname_cfg), + &images->fit_uname_cfg, arch, IH_TYPE_FPGA, BOOTSTAGE_ID_FPGA_INIT, @@ -711,7 +715,7 @@ int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, } #endif -static void fit_loadable_process(uint8_t img_type, +static void fit_loadable_process(u8 img_type, ulong img_data, ulong img_len) { @@ -729,7 +733,7 @@ static void fit_loadable_process(uint8_t img_type, } int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, - uint8_t arch, const ulong *ld_start, ulong * const ld_len) + u8 arch, const ulong *ld_start, ulong * const ld_len) { /* * These variables are used to hold the current image location @@ -746,7 +750,7 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, int conf_noffset; int fit_img_result; const char *uname; - uint8_t img_type; + u8 img_type; /* Check to see if the images struct has a FIT configuration */ if (!genimg_has_config(images)) { @@ -769,18 +773,16 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, 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); + 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; @@ -834,8 +836,7 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, env_get_bootm_mapsize() + env_get_bootm_low()); - - if (cmdline == NULL) + if (!cmdline) return -1; s = env_get("bootargs"); @@ -844,7 +845,7 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) strcpy(cmdline, s); - *cmd_start = (ulong) & cmdline[0]; + *cmd_start = (ulong)cmdline; *cmd_end = *cmd_start + strlen(cmdline); debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); @@ -872,11 +873,12 @@ 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 == NULL) + env_get_bootm_mapsize() + + env_get_bootm_low()); + if (!*kbd) return -1; - **kbd = *(gd->bd); + **kbd = *gd->bd; debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); @@ -901,7 +903,7 @@ int image_setup_linux(bootm_headers_t *images) if (IMAGE_BOOT_GET_CMDLINE) { ret = boot_get_cmdline(lmb, &images->cmdline_start, - &images->cmdline_end); + &images->cmdline_end); if (ret) { puts("ERROR with allocation of cmdline\n"); return ret; -- cgit v1.1 From 5d3248a688c2368be54aaa9407be30adfa994abc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:17 -0600 Subject: image: Split host code out into its own file To avoid having #ifdefs in a few functions which are completely different in the board and host code, create a new image-host.c file. Signed-off-by: Simon Glass --- common/image-board.c | 17 +++++++++++++++++ common/image-host.c | 27 +++++++++++++++++++++++++++ common/image.c | 38 +------------------------------------- tools/Makefile | 1 + 4 files changed, 46 insertions(+), 37 deletions(-) create mode 100644 common/image-host.c diff --git a/common/image-board.c b/common/image-board.c index 835751e..898f0a2 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -925,3 +926,19 @@ int image_setup_linux(bootm_headers_t *images) return 0; } #endif /* CONFIG_LMB */ + +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); +} diff --git a/common/image-host.c b/common/image-host.c new file mode 100644 index 0000000..20a9521 --- /dev/null +++ b/common/image-host.c @@ -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 + +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)); +} diff --git a/common/image.c b/common/image.c index ed7f188..3eb6a7f 100644 --- a/common/image.c +++ b/common/image.c @@ -18,8 +18,6 @@ #include #endif -#include - #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT #include #include @@ -60,6 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #include +#include #include #include #include @@ -528,41 +527,6 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, return 0; } -#ifdef USE_HOSTCC -void memmove_wd(void *to, void *from, size_t len, ulong chunksz) -{ - memmove(to, from, len); -} -#endif /* !USE_HOSTCC */ - -void genimg_print_size(uint32_t size) -{ -#ifndef USE_HOSTCC - printf("%d Bytes = ", size); - print_size(size, "\n"); -#else - printf("%d Bytes = %.2f KiB = %.2f MiB\n", - size, (double)size / 1.024e3, - (double)size / 1.048576e6); -#endif -} - -#if IMAGE_ENABLE_TIMESTAMP -void genimg_print_time(time_t timestamp) -{ -#ifndef USE_HOSTCC - 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); -#else - printf("%s", ctime(×tamp)); -#endif -} -#endif - const table_entry_t *get_table_entry(const table_entry_t *table, int id) { for (; table->id >= 0; ++table) { diff --git a/tools/Makefile b/tools/Makefile index 4a86321..999fd46 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -113,6 +113,7 @@ dumpimage-mkimage-objs := aisimage.o \ lib/fdtdec_common.o \ lib/fdtdec.o \ common/image.o \ + common/image-host.o \ imagetool.o \ imximage.o \ imx8image.o \ -- cgit v1.1 From 2ac00c050582389e667374bccc5cc19b4fce80f5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:18 -0600 Subject: image: Create a function to do manual relocation Rather than adding an #ifdef and open-coding this calculation, add a helper function to handle it. Use this in the image code. Signed-off-by: Simon Glass --- common/image.c | 33 +++++++-------------------------- include/relocate.h | 24 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/common/image.c b/common/image.c index 3eb6a7f..2f2fd05 100644 --- a/common/image.c +++ b/common/image.c @@ -63,6 +63,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #include #include +#include #include #include #include @@ -565,11 +566,7 @@ const char *genimg_get_cat_name(enum ih_category category, uint id) entry = get_table_entry(table_info[category].table, id); if (!entry) return unknown_msg(category); -#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) - return entry->lname; -#else - return entry->lname + gd->reloc_off; -#endif + return manual_reloc(entry->lname); } /** @@ -589,11 +586,7 @@ const char *genimg_get_cat_short_name(enum ih_category category, uint id) entry = get_table_entry(table_info[category].table, id); if (!entry) return unknown_msg(category); -#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) - return entry->sname; -#else - return entry->sname + gd->reloc_off; -#endif + return manual_reloc(entry->sname); } int genimg_get_cat_count(enum ih_category category) @@ -643,11 +636,7 @@ char *get_table_entry_name(const table_entry_t *table, char *msg, int id) table = get_table_entry(table, id); if (!table) return msg; -#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) - return table->lname; -#else - return table->lname + gd->reloc_off; -#endif + return manual_reloc(table->lname); } const char *genimg_get_os_name(uint8_t os) @@ -677,11 +666,7 @@ static const char *genimg_get_short_name(const table_entry_t *table, int val) table = get_table_entry(table, val); if (!table) return "unknown"; -#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) - return table->sname; -#else - return table->sname + gd->reloc_off; -#endif + return manual_reloc(table->sname); } const char *genimg_get_type_short_name(uint8_t type) @@ -724,12 +709,8 @@ int get_table_entry_id(const table_entry_t *table, const table_entry_t *t; for (t = table; t->id >= 0; ++t) { -#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC) - if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0) -#else - if (t->sname && strcasecmp(t->sname, name) == 0) -#endif - return (t->id); + if (t->sname && !strcasecmp(manual_reloc(t->sname), name)) + return t->id; } debug("Invalid %s Type: %s\n", table_name, name); diff --git a/include/relocate.h b/include/relocate.h index 9ceeecd..c4fad33 100644 --- a/include/relocate.h +++ b/include/relocate.h @@ -7,7 +7,11 @@ #ifndef _RELOCATE_H_ #define _RELOCATE_H_ -#include +#ifndef USE_HOSTCC +#include + +DECLARE_GLOBAL_DATA_PTR; +#endif /** * copy_uboot_to_ram() - Copy U-Boot to its new relocated position @@ -35,4 +39,22 @@ int clear_bss(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; +} + #endif /* _RELOCATE_H_ */ -- cgit v1.1 From c5a68d29e38ce25646ee42eb49a29364aab84531 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:19 -0600 Subject: image: Avoid #ifdefs for manual relocation Add a macro to handle manually relocating a pointer. Update the iamge code to use this to avoid needing #ifdefs. This also fixes a bug where the 'done' flag was not set. Signed-off-by: Simon Glass --- common/image-sig.c | 40 ++++++++++++++++++++++------------------ include/relocate.h | 6 ++++++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/common/image-sig.c b/common/image-sig.c index fa9407b..1aa0b58 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -9,6 +9,7 @@ #include DECLARE_GLOBAL_DATA_PTR; #include +#include #include #include #include @@ -56,17 +57,19 @@ struct checksum_algo *image_get_checksum_algo(const char *full_name) int i; const char *name; -#if defined(CONFIG_NEEDS_MANUAL_RELOC) - static bool done; + if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) { + static bool done; - if (!done) { - done = true; - for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) { - checksum_algos[i].name += gd->reloc_off; - checksum_algos[i].calculate += gd->reloc_off; + if (!done) { + done = true; + for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) { + struct checksum_algo *algo = &checksum_algos[i]; + + MANUAL_RELOC(algo->name); + MANUAL_RELOC(algo->calculate); + } } } -#endif for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) { 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; const char *name; -#if defined(CONFIG_NEEDS_MANUAL_RELOC) - static bool done; - - if (!done) { - crypto = ll_entry_start(struct crypto_algo, cryptos); - end = ll_entry_end(struct crypto_algo, cryptos); - for (; crypto < end; crypto++) { - crypto->name += gd->reloc_off; - crypto->verify += gd->reloc_off; + if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) { + static bool done; + + if (!done) { + done = true; + crypto = ll_entry_start(struct crypto_algo, cryptos); + end = ll_entry_end(struct crypto_algo, cryptos); + for (; crypto < end; crypto++) { + MANUAL_RELOC(crypto->name); + MANUAL_RELOC(crypto->verify); + } } } -#endif /* Move name to after the comma */ name = strchr(full_name, ','); diff --git a/include/relocate.h b/include/relocate.h index c4fad33..26682da 100644 --- a/include/relocate.h +++ b/include/relocate.h @@ -57,4 +57,10 @@ static inline void *manual_reloc(void *ptr) 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_ */ -- cgit v1.1 From 4ed37abc49c20b5dd0dc3ecd3eac53659057e455 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 07:03:20 -0600 Subject: image: Remove ifdefs around image_setup_linux() el at Drop some more ifdefs in image-board.c and also the FPGA part of bootm.c which calls into it. Signed-off-by: Simon Glass --- common/bootm.c | 16 ++++++++-------- common/image-board.c | 11 +++-------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/common/bootm.c b/common/bootm.c index ea71522..fe17d1d 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -296,15 +296,15 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, #endif #if IMAGE_ENABLE_FIT -#if defined(CONFIG_FPGA) - /* find bitstreams */ - ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, - NULL, NULL); - if (ret) { - printf("FPGA image is corrupted or invalid\n"); - return 1; + if (IS_ENABLED(CONFIG_FPGA)) { + /* find bitstreams */ + ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, + NULL, NULL); + if (ret) { + printf("FPGA image is corrupted or invalid\n"); + return 1; + } } -#endif /* find all of the loadables */ ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT, diff --git a/common/image-board.c b/common/image-board.c index 898f0a2..1d6842f 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -814,7 +814,6 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, } #endif -#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -853,9 +852,7 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) return 0; } -#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ -#ifdef CONFIG_SYS_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -883,15 +880,14 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); -#if defined(DEBUG) && defined(CONFIG_CMD_BDI) - do_bdinfo(NULL, 0, 0, NULL); +#if defined(DEBUG) + if (IS_ENABLED(CONFIG_CMD_BDI) + do_bdinfo(NULL, 0, 0, NULL); #endif return 0; } -#endif /* CONFIG_SYS_BOOT_GET_KBD */ -#ifdef CONFIG_LMB int image_setup_linux(bootm_headers_t *images) { ulong of_size = images->ft_len; @@ -925,7 +921,6 @@ int image_setup_linux(bootm_headers_t *images) return 0; } -#endif /* CONFIG_LMB */ void genimg_print_size(uint32_t size) { -- cgit v1.1 From c9d6b5b5dcce6820ea794af5f046803cdd43b37b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:14 -0600 Subject: compiler: Rename host_build() to tools_build() With the new TOOLS_LIBCRYPTO and some other changes, it seems that we are heading towards calling this a tools build rather than a host build, although of course it does happen on the host. I cannot think of anything built by the host which cannot be described as a tool, so rename this function. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/image-fit.c | 8 ++++---- common/image.c | 12 ++++++------ include/compiler.h | 5 +++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index 5a0a0cc..6f8e67e 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -509,7 +509,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); - if (!host_build()) { + if (!tools_build()) { printf("%s Data Start: ", p); if (ret) { printf("unavailable\n"); @@ -1845,7 +1845,7 @@ int fit_conf_get_node(const void *fit, const char *conf_uname) if (conf_uname == NULL) { /* get configuration unit name from the default property */ 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); if (noffset < 0) return noffset; @@ -2093,7 +2093,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr, } 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)) { puts("Unsupported Architecture\n"); bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); @@ -2158,7 +2158,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr, } /* 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); len = (ulong)size; diff --git a/common/image.c b/common/image.c index 2f2fd05..66685b4 100644 --- a/common/image.c +++ b/common/image.c @@ -460,11 +460,11 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, ret = -ENOSPC; break; case IH_COMP_GZIP: - if (!host_build() && CONFIG_IS_ENABLED(GZIP)) + if (!tools_build() && CONFIG_IS_ENABLED(GZIP)) ret = gunzip(load_buf, unc_len, image_buf, &image_len); break; case IH_COMP_BZIP2: - if (!host_build() && CONFIG_IS_ENABLED(BZIP2)) { + if (!tools_build() && CONFIG_IS_ENABLED(BZIP2)) { uint size = unc_len; /* @@ -478,7 +478,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, } break; case IH_COMP_LZMA: - if (!host_build() && CONFIG_IS_ENABLED(LZMA)) { + if (!tools_build() && CONFIG_IS_ENABLED(LZMA)) { SizeT lzma_len = unc_len; ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, @@ -487,7 +487,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, } break; case IH_COMP_LZO: - if (!host_build() && CONFIG_IS_ENABLED(LZO)) { + if (!tools_build() && CONFIG_IS_ENABLED(LZO)) { size_t size = unc_len; ret = lzop_decompress(image_buf, image_len, load_buf, &size); @@ -495,7 +495,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, } break; case IH_COMP_LZ4: - if (!host_build() && CONFIG_IS_ENABLED(LZ4)) { + if (!tools_build() && CONFIG_IS_ENABLED(LZ4)) { size_t size = unc_len; ret = ulz4fn(image_buf, image_len, load_buf, &size); @@ -503,7 +503,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, } break; case IH_COMP_ZSTD: - if (!host_build() && CONFIG_IS_ENABLED(ZSTD)) { + if (!tools_build() && CONFIG_IS_ENABLED(ZSTD)) { struct abuf in, out; abuf_init_set(&in, image_buf, image_len); diff --git a/include/compiler.h b/include/compiler.h index 6b0d3bf..8cf1179 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -155,11 +155,12 @@ typedef unsigned long int uintptr_t; #endif /** - * host_build() - check if we are building for the host + * tools_build() - check if we are building host tools * * @return true if building for the host, false if for a target */ -static inline bool host_build(void) { +static inline bool tools_build(void) +{ #ifdef USE_HOSTCC return true; #else -- cgit v1.1 From 5500a408dd81d5e5718a0fcd98ce55586d125853 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:15 -0600 Subject: kconfig: Add tools support to CONFIG_IS_ENABLED() At present we must separately test for the host build for many options, since we force them to be enabled. For example, CONFIG_FIT is always enabled in the host tools, even if CONFIG_FIT is not enabled by the board itself. It would be more convenient if we could use, for example, CONFIG_IS_ENABLED(FIT) and get CONFIG_HOST_FIT, when building for the host. Add support for this. With this and the tools_build() function, we should be able to remove all the #ifdefs currently needed in code that is build by tools and targets. This will be even nicer when we move to using CONFIG(xxx) everywhere, since all the #ifdef and IS_ENABLED/CONFIG_IS_ENABLED stuff will go away. Signed-off-by: Simon Glass Suggested-by: Rasmus Villemoes # b4f73886 Reviewed-by: Alexandru Gagniuc --- include/linux/kconfig.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index d109ed3..a1d1a29 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -31,11 +31,14 @@ (config_enabled(option)) /* - * U-Boot add-on: Helper macros to reference to different macros - * (CONFIG_ or CONFIG_SPL_ prefixed), depending on the build context. + * U-Boot add-on: Helper macros to reference to different macros (prefixed by + * 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_ #elif defined(CONFIG_SPL_BUILD) #define _CONFIG_PREFIX SPL_ @@ -49,6 +52,7 @@ /* * 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_SPL_FOO if CONFIG_SPL_BUILD is defined. * CONFIG_TPL_FOO if CONFIG_TPL_BUILD is defined. @@ -76,18 +80,21 @@ /* * 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 defined and CONFIG_SPL_FOO is set to 'y', * 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', * 0 otherwise. * * 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 defined and CONFIG_SPL_FOO is set to 'y', * abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', * nothing otherwise. * * 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 defined and CONFIG_SPL_FOO is set to 'y', * abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', -- cgit v1.1 From e02b3fd4b9cf34c7d22254e8d6db69e2f4471f4f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:16 -0600 Subject: image: Add Kconfig options for FIT in the tools build In preparation for enabling CONFIG_IS_ENABLED() on the host build, add some options to enable the various FIT options expected in these tools. This will ensure that the code builds correctly when CONFIG_TOOLS_xxx is distinct from CONFIG_xxx. Drop some #ifdefs which are immediately unnecessary (many more are in later patches). Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc Reviewed-by: Alexandru Gagniuc --- common/image-fit-sig.c | 3 ++- common/image-fit.c | 4 ++-- tools/Kconfig | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c index b979cd2..e95e64b 100644 --- a/common/image-fit-sig.c +++ b/common/image-fit-sig.c @@ -72,11 +72,12 @@ static int fit_image_setup_verify(struct image_sign_info *info, char *algo_name; const char *padding_name; +#ifndef USE_HOSTCC if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) { *err_msgp = "Total size too large"; return 1; } - +#endif if (fit_image_hash_get_algo(fit, noffset, &algo_name)) { *err_msgp = "Can't get hash algo property"; return -1; diff --git a/common/image-fit.c b/common/image-fit.c index 6f8e67e..17c6d4e 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -170,7 +170,7 @@ int fit_get_subimage_count(const void *fit, int images_noffset) return count; } -#if CONFIG_IS_ENABLED(FIT_PRINT) || CONFIG_IS_ENABLED(SPL_FIT_PRINT) +#if CONFIG_IS_ENABLED(FIT_PRINT) /** * fit_image_print_data() - prints out the hash node details * @fit: pointer to the FIT format image header @@ -578,7 +578,7 @@ 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) */ +#endif /* CONFIG_IS_ENABLED(FIT_PRINT) */ /** * fit_get_desc - get node description property diff --git a/tools/Kconfig b/tools/Kconfig index d6f82cd..ea986ab 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -20,4 +20,29 @@ config TOOLS_LIBCRYPTO This selection does not affect target features, such as runtime FIT 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_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 + endmenu -- cgit v1.1 From 603d15a572d5b1e2894db87b86d85a092dacdfd1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:17 -0600 Subject: spl: cypto: Bring back SPL_ versions of SHA Unfortunately these were removed by mistake. This means that adding hash support to SPL brings in all software algorithms, with a substantial increase in code size. The origin of the problem was renaming them to SPL_FIT_xxx and then these were removed altogether in a later commit. Add them back. This aligns with CONFIG_MD5, for example, which has an SPL variant. Signed-off-by: Simon Glass Fixes: f5bc9c25f31 ("image: Rename SPL_SHAxxx_SUPPORT to SPL_FIT_SHAxxx") Fixes: eb5171ddec9 ("common: Remove unused CONFIG_FIT_SHAxxx selectors") Reviewed-by: Alexandru Gagniuc --- lib/Kconfig | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/Kconfig b/lib/Kconfig index 034af72..7899e75 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -373,7 +373,6 @@ config SHA256 The SHA256 algorithm produces a 256-bit (32-byte) hash value (digest). - config SHA512 bool "Enable SHA512 support" help @@ -399,6 +398,48 @@ config SHA_HW_ACCEL hashing algorithms. This affects the 'hash' command and also the 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). + +endif + if SHA_HW_ACCEL config SHA512_HW_ACCEL -- cgit v1.1 From 2c21256b27d70b5950bd059330cdab027fb6ab7e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:18 -0600 Subject: hash: Use Kconfig to enable hashing in host tools and SPL At present when building host tools, we force CONFIG_SHAxxx to be enabled regardless of the board Kconfig setting. This is done in the image.h header file. For SPL we currently just assume the algorithm is desired if U-Boot proper enables it. Clean this up by adding new Kconfig options to enable hashing on the host, relying on CONFIG_IS_ENABLED() to deal with the different builds. Add new SPL Kconfigs for hardware-accelerated hashing, to maintain the current settings. This allows us to drop the image.h code and the I_WANT_MD5 hack. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/hash.c | 49 +++++++++++++++++++++++-------------------------- include/fdt_support.h | 2 +- include/hash.h | 6 +++++- include/image.h | 5 ----- lib/Kconfig | 18 ++++++++++++++++++ tools/Kconfig | 25 +++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 33 deletions(-) diff --git a/common/hash.c b/common/hash.c index 3884298..2b8e7a4 100644 --- a/common/hash.c +++ b/common/hash.c @@ -25,6 +25,7 @@ #else #include "mkimage.h" #include +#include #endif /* !USE_HOSTCC*/ #include @@ -41,7 +42,7 @@ DECLARE_GLOBAL_DATA_PTR; static void reloc_update(void); -#if defined(CONFIG_SHA1) && !defined(CONFIG_SHA_PROG_HW_ACCEL) +#if CONFIG_IS_ENABLED(SHA1) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) static int hash_init_sha1(struct hash_algo *algo, void **ctxp) { sha1_context *ctx = malloc(sizeof(sha1_context)); @@ -69,7 +70,7 @@ static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, } #endif -#if defined(CONFIG_SHA256) && !defined(CONFIG_SHA_PROG_HW_ACCEL) +#if CONFIG_IS_ENABLED(SHA256) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) static int hash_init_sha256(struct hash_algo *algo, void **ctxp) { sha256_context *ctx = malloc(sizeof(sha256_context)); @@ -97,7 +98,7 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void } #endif -#if defined(CONFIG_SHA384) && !defined(CONFIG_SHA_PROG_HW_ACCEL) +#if CONFIG_IS_ENABLED(SHA384) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) static int hash_init_sha384(struct hash_algo *algo, void **ctxp) { sha512_context *ctx = malloc(sizeof(sha512_context)); @@ -125,7 +126,7 @@ static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void } #endif -#if defined(CONFIG_SHA512) && !defined(CONFIG_SHA_PROG_HW_ACCEL) +#if CONFIG_IS_ENABLED(SHA512) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) static int hash_init_sha512(struct hash_algo *algo, void **ctxp) { sha512_context *ctx = malloc(sizeof(sha512_context)); @@ -207,18 +208,13 @@ static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf, 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 * is enable we will use that, otherwise a software version of the algorithm. * Note that algorithm names must be in lower case. */ static struct hash_algo hash_algo[] = { -#if I_WANT_MD5 +#if CONFIG_IS_ENABLED(MD5) { .name = "md5", .digest_size = MD5_SUM_LEN, @@ -226,17 +222,17 @@ static struct hash_algo hash_algo[] = { .hash_func_ws = md5_wd, }, #endif -#ifdef CONFIG_SHA1 +#if CONFIG_IS_ENABLED(SHA1) { .name = "sha1", .digest_size = SHA1_SUM_LEN, .chunk_size = CHUNKSZ_SHA1, -#ifdef CONFIG_SHA_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA_HW_ACCEL) .hash_func_ws = hw_sha1, #else .hash_func_ws = sha1_csum_wd, #endif -#ifdef CONFIG_SHA_PROG_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) .hash_init = hw_sha_init, .hash_update = hw_sha_update, .hash_finish = hw_sha_finish, @@ -247,17 +243,17 @@ static struct hash_algo hash_algo[] = { #endif }, #endif -#ifdef CONFIG_SHA256 +#if CONFIG_IS_ENABLED(SHA256) { .name = "sha256", .digest_size = SHA256_SUM_LEN, .chunk_size = CHUNKSZ_SHA256, -#ifdef CONFIG_SHA_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA_HW_ACCEL) .hash_func_ws = hw_sha256, #else .hash_func_ws = sha256_csum_wd, #endif -#ifdef CONFIG_SHA_PROG_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) .hash_init = hw_sha_init, .hash_update = hw_sha_update, .hash_finish = hw_sha_finish, @@ -268,17 +264,17 @@ static struct hash_algo hash_algo[] = { #endif }, #endif -#ifdef CONFIG_SHA384 +#if CONFIG_IS_ENABLED(SHA384) { .name = "sha384", .digest_size = SHA384_SUM_LEN, .chunk_size = CHUNKSZ_SHA384, -#ifdef CONFIG_SHA512_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) .hash_func_ws = hw_sha384, #else .hash_func_ws = sha384_csum_wd, #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_update = hw_sha_update, .hash_finish = hw_sha_finish, @@ -289,17 +285,17 @@ static struct hash_algo hash_algo[] = { #endif }, #endif -#ifdef CONFIG_SHA512 +#if CONFIG_IS_ENABLED(SHA512) { .name = "sha512", .digest_size = SHA512_SUM_LEN, .chunk_size = CHUNKSZ_SHA512, -#ifdef CONFIG_SHA512_HW_ACCEL +#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) .hash_func_ws = hw_sha512, #else .hash_func_ws = sha512_csum_wd, #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_update = hw_sha_update, .hash_finish = hw_sha_finish, @@ -331,9 +327,9 @@ static struct hash_algo hash_algo[] = { }; /* Try to minimize code size for boards that don't want much hashing */ -#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) || \ - defined(CONFIG_CRC32_VERIFY) || defined(CONFIG_CMD_HASH) || \ - defined(CONFIG_SHA384) || defined(CONFIG_SHA512) +#if CONFIG_IS_ENABLED(SHA256) || CONFIG_IS_ENABLED(CMD_SHA1SUM) || \ + CONFIG_IS_ENABLED(CRC32_VERIFY) || CONFIG_IS_ENABLED(CMD_HASH) || \ + CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512) #define multi_hash() 1 #else #define multi_hash() 0 @@ -438,7 +434,8 @@ int hash_block(const char *algo_name, const void *data, unsigned int len, 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 * diff --git a/include/fdt_support.h b/include/fdt_support.h index 72a5b90..88d129c 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -7,7 +7,7 @@ #ifndef __FDT_SUPPORT_H #define __FDT_SUPPORT_H -#ifdef CONFIG_OF_LIBFDT +#if defined(CONFIG_OF_LIBFDT) && !defined(USE_HOSTCC) #include #include diff --git a/include/hash.h b/include/hash.h index 97bb3ed..cfafbe7 100644 --- a/include/hash.h +++ b/include/hash.h @@ -6,13 +6,17 @@ #ifndef _HASH_H #define _HASH_H +#ifdef USE_HOSTCC +#include +#endif + struct cmd_tbl; /* * Maximum digest size for all algorithms we support. Having this value * 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 #else #define HASH_MAX_DIGEST_SIZE 32 diff --git a/include/image.h b/include/image.h index 73a763a..03857f4 100644 --- a/include/image.h +++ b/include/image.h @@ -31,11 +31,6 @@ struct fdt_region; #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 "" diff --git a/lib/Kconfig b/lib/Kconfig index 7899e75..64765ac 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -438,6 +438,24 @@ config SPL_SHA384 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 diff --git a/tools/Kconfig b/tools/Kconfig index ea986ab..6ffc2c0 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -45,4 +45,29 @@ config TOOLS_FIT_SIGNATURE_MAX_SIZE depends on TOOLS_FIT_SIGNATURE default 0x10000000 +config TOOLS_MD5 + def_bool y + help + Enable MD5 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 -- cgit v1.1 From d54f7e3f2328ea361c3a58714127ed9b3ad0f70c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:19 -0600 Subject: hash: Drop some #ifdefs in hash.c We can use the __maybe_unused attribute to avoid some of the #ifdefs in this file. Update the functions accordingly. Note: The actual hashing interface is still a mess, with four separate combinations and lots of #ifdefs. This should really use a driver approach, e.g. as is done with partition drivers. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/hash.c | 54 +++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/common/hash.c b/common/hash.c index 2b8e7a4..3b591ba0 100644 --- a/common/hash.c +++ b/common/hash.c @@ -24,6 +24,7 @@ #include #else #include "mkimage.h" +#include #include #include #endif /* !USE_HOSTCC*/ @@ -42,8 +43,7 @@ DECLARE_GLOBAL_DATA_PTR; static void reloc_update(void); -#if CONFIG_IS_ENABLED(SHA1) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) -static int hash_init_sha1(struct hash_algo *algo, void **ctxp) +static int __maybe_unused hash_init_sha1(struct hash_algo *algo, void **ctxp) { sha1_context *ctx = malloc(sizeof(sha1_context)); sha1_starts(ctx); @@ -51,15 +51,16 @@ static int hash_init_sha1(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf, - unsigned int size, int is_last) +static int __maybe_unused hash_update_sha1(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, + int is_last) { sha1_update((sha1_context *)ctx, buf, size); return 0; } -static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, - int size) +static int __maybe_unused hash_finish_sha1(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) { if (size < algo->digest_size) return -1; @@ -68,10 +69,8 @@ static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, free(ctx); return 0; } -#endif -#if CONFIG_IS_ENABLED(SHA256) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) -static int hash_init_sha256(struct hash_algo *algo, void **ctxp) +static int __maybe_unused hash_init_sha256(struct hash_algo *algo, void **ctxp) { sha256_context *ctx = malloc(sizeof(sha256_context)); sha256_starts(ctx); @@ -79,15 +78,16 @@ static int hash_init_sha256(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_sha256(struct hash_algo *algo, void *ctx, - const void *buf, unsigned int size, int is_last) +static int __maybe_unused hash_update_sha256(struct hash_algo *algo, void *ctx, + const void *buf, uint size, + int is_last) { sha256_update((sha256_context *)ctx, buf, size); return 0; } -static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void - *dest_buf, int size) +static int __maybe_unused hash_finish_sha256(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) { if (size < algo->digest_size) return -1; @@ -96,10 +96,8 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void free(ctx); return 0; } -#endif -#if CONFIG_IS_ENABLED(SHA384) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) -static int hash_init_sha384(struct hash_algo *algo, void **ctxp) +static int __maybe_unused hash_init_sha384(struct hash_algo *algo, void **ctxp) { sha512_context *ctx = malloc(sizeof(sha512_context)); sha384_starts(ctx); @@ -107,15 +105,16 @@ static int hash_init_sha384(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_sha384(struct hash_algo *algo, void *ctx, - const void *buf, unsigned int size, int is_last) +static int __maybe_unused hash_update_sha384(struct hash_algo *algo, void *ctx, + const void *buf, uint size, + int is_last) { sha384_update((sha512_context *)ctx, buf, size); return 0; } -static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void - *dest_buf, int size) +static int __maybe_unused hash_finish_sha384(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) { if (size < algo->digest_size) return -1; @@ -124,10 +123,8 @@ static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void free(ctx); return 0; } -#endif -#if CONFIG_IS_ENABLED(SHA512) && !CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) -static int hash_init_sha512(struct hash_algo *algo, void **ctxp) +static int __maybe_unused hash_init_sha512(struct hash_algo *algo, void **ctxp) { sha512_context *ctx = malloc(sizeof(sha512_context)); sha512_starts(ctx); @@ -135,15 +132,16 @@ static int hash_init_sha512(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_sha512(struct hash_algo *algo, void *ctx, - const void *buf, unsigned int size, int is_last) +static int __maybe_unused hash_update_sha512(struct hash_algo *algo, void *ctx, + const void *buf, uint size, + int is_last) { sha512_update((sha512_context *)ctx, buf, size); return 0; } -static int hash_finish_sha512(struct hash_algo *algo, void *ctx, void - *dest_buf, int size) +static int __maybe_unused hash_finish_sha512(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) { if (size < algo->digest_size) return -1; @@ -152,8 +150,6 @@ static int hash_finish_sha512(struct hash_algo *algo, void *ctx, void free(ctx); return 0; } -#endif - static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) { -- cgit v1.1 From bf371b4cf599ad1a448577daaba997a0b0ba6c9c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:20 -0600 Subject: image: Drop IMAGE_ENABLE_FIT Make use of the host Kconfig for FIT. With this we can use CONFIG_IS_ENABLED(FIT) directly in the host build, so drop the unnecessary indirection. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- arch/arm/mach-imx/hab.c | 2 +- common/bootm.c | 10 +++++----- common/image-board.c | 16 ++++++++-------- common/image.c | 2 +- include/image.h | 17 ++++++++--------- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index cc39e6b..55317ab 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -591,7 +591,7 @@ static ulong get_image_ivt_offset(ulong img_addr) return (image_get_image_size((image_header_t *)img_addr) + 0x1000 - 1) & ~(0x1000 - 1); #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: return (fit_get_size(buf) + 0x1000 - 1) & ~(0x1000 - 1); #endif diff --git a/common/bootm.c b/common/bootm.c index fe17d1d..8d614fe 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -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); break; #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type(images.fit_hdr_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 */ } else if (images.legacy_hdr_valid) { 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) { int ret; @@ -295,7 +295,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, set_working_fdt_addr(map_to_sysmem(images.ft_addr)); #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) if (IS_ENABLED(CONFIG_FPGA)) { /* find bitstreams */ ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, @@ -858,7 +858,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, const void *buf; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) int os_noffset; #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); break; #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: os_noffset = fit_image_load(images, img_addr, &fit_uname_kernel, &fit_uname_config, diff --git a/common/image-board.c b/common/image-board.c index 1d6842f..0ad75fd 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -282,7 +282,7 @@ int genimg_get_format(const void *img_addr) if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; #endif -#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT +#if CONFIG_IS_ENABLED(FIT) || IMAGE_ENABLE_OF_LIBFDT if (fdt_check_header(img_addr) == 0) return IMAGE_FORMAT_FIT; #endif @@ -307,7 +307,7 @@ int genimg_get_format(const void *img_addr) */ int genimg_has_config(bootm_headers_t *images) { -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) if (images->fit_uname_cfg) return 1; #endif @@ -348,7 +348,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, #ifdef CONFIG_SUPPORT_RAW_INITRD char *end; #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) const char *fit_uname_config = images->fit_uname_cfg; const char *fit_uname_ramdisk = NULL; ulong default_addr; @@ -380,7 +380,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, rd_len = 0; rd_data = 0; } else if (select || genimg_has_config(images)) { -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) if (select) { /* * If the init ramdisk comes from the FIT image and @@ -409,7 +409,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); } -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) } else { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, @@ -450,7 +450,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, rd_load = image_get_load(rd_hdr); break; #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: rd_noffset = fit_image_load(images, rd_addr, &fit_uname_ramdisk, @@ -623,14 +623,14 @@ error: int boot_get_setup(bootm_headers_t *images, u8 arch, ulong *setup_start, ulong *setup_len) { -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) return boot_get_setup_fit(images, arch, setup_start, setup_len); #else return -ENOENT; #endif } -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) #if defined(CONFIG_FPGA) int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, u8 arch, const ulong *ld_start, ulong * const ld_len) diff --git a/common/image.c b/common/image.c index 66685b4..59b5e70 100644 --- a/common/image.c +++ b/common/image.c @@ -18,7 +18,7 @@ #include #endif -#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT +#if CONFIG_IS_ENABLED(FIT) || IMAGE_ENABLE_OF_LIBFDT #include #include #endif diff --git a/include/image.h b/include/image.h index 03857f4..6c22921 100644 --- a/include/image.h +++ b/include/image.h @@ -25,9 +25,9 @@ struct fdt_region; #ifdef USE_HOSTCC #include +#include /* 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 @@ -46,16 +46,15 @@ struct fdt_region; #define IMAGE_ENABLE_IGNORE 1 #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 */ -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) #include #include #include -#endif /* IMAGE_ENABLE_FIT */ +#endif /* FIT */ #ifdef CONFIG_SYS_BOOT_GET_CMDLINE # define IMAGE_BOOT_GET_CMDLINE 1 @@ -328,7 +327,7 @@ typedef struct bootm_headers { image_header_t legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid; -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) const char *fit_uname_cfg; /* configuration node unit name */ void *fit_hdr_os; /* os FIT image header */ @@ -983,7 +982,7 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) /* cmdline argument format parsing */ int fit_parse_conf(const char *spec, ulong addr_curr, ulong *addr, const char **conf_name); @@ -1157,7 +1156,7 @@ int fit_conf_get_prop_node(const void *fit, int noffset, int fit_check_ramdisk(const void *fit, int os_noffset, uint8_t arch, int verify); -#endif /* IMAGE_ENABLE_FIT */ +#endif /* FIT */ int calculate_hash(const void *data, int data_len, const char *algo, uint8_t *value, int *value_len); @@ -1180,7 +1179,7 @@ int calculate_hash(const void *data, int data_len, const char *algo, # define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE) #endif -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) #ifdef USE_HOSTCC void *image_get_host_blob(void); void image_set_host_blob(void *host_blob); @@ -1335,7 +1334,7 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name); */ struct padding_algo *image_get_padding_algo(const char *name); -#if IMAGE_ENABLE_FIT +#if CONFIG_IS_ENABLED(FIT) /** * fit_image_verify_required_sigs() - Verify signatures marked as 'required' -- cgit v1.1 From 0c303f9a6628de9664b4f9140464a6f9d8224c36 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:21 -0600 Subject: image: Drop IMAGE_ENABLE_OF_LIBFDT Add a host Kconfig for OF_LIBFDT. With this we can use CONFIG_IS_ENABLED(OF_LIBFDT) directly in the tools build, so drop the unnecessary indirection. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- arch/arc/lib/bootm.c | 2 +- arch/arm/lib/bootm.c | 4 ++-- arch/microblaze/lib/bootm.c | 2 +- arch/nds32/lib/bootm.c | 4 ++-- arch/riscv/lib/bootm.c | 4 ++-- board/synopsys/hsdk/hsdk.c | 2 +- common/bootm.c | 4 ++-- common/image-board.c | 8 ++++---- common/image.c | 2 +- include/image.h | 3 --- lib/lmb.c | 2 +- tools/Kconfig | 5 +++++ 12 files changed, 22 insertions(+), 20 deletions(-) diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index 41408c2..ed6c5df 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -63,7 +63,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); 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; r2 = (unsigned int)images->ft_addr; } else { diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index dd6a693..a59a5e6 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -199,7 +199,7 @@ static void boot_prep_linux(bootm_headers_t *images) { 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 debug("using: FDT\n"); 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); 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; else r2 = gd->bd->bi_boot_params; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 3a6da6e..12ea324 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -75,7 +75,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) 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"); if (image_setup_linux(images)) { printf("FDT creation failed! hanging..."); diff --git a/arch/nds32/lib/bootm.c b/arch/nds32/lib/bootm.c index 1c7f785..71ebfb4 100644 --- a/arch/nds32/lib/bootm.c +++ b/arch/nds32/lib/bootm.c @@ -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", (ulong)theKernel); - if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { #ifdef CONFIG_OF_LIBFDT debug("using: FDT\n"); if (image_setup_linux(images)) { @@ -110,7 +110,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) #endif } 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); else theKernel(0, machid, bd->bi_boot_params); diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index ff1bdf7..2e1e286 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -64,7 +64,7 @@ static void announce_and_cleanup(int fake) 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 debug("using: FDT\n"); if (image_setup_linux(images)) { @@ -96,7 +96,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) announce_and_cleanup(fake); if (!fake) { - if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { #ifdef CONFIG_SMP ret = smp_call_function(images->ep, (ulong)images->ft_addr, 0, 0); diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c index 892b94b..226fbba 100644 --- a/board/synopsys/hsdk/hsdk.c +++ b/board/synopsys/hsdk/hsdk.c @@ -871,7 +871,7 @@ int board_prep_linux(bootm_headers_t *images) if (env_common.core_mask.val == ALL_CPU_MASK) 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"); return 0; } diff --git a/common/bootm.c b/common/bootm.c index 8d614fe..4482f84 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -271,7 +271,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, return 1; } -#if IMAGE_ENABLE_OF_LIBFDT +#if CONFIG_IS_ENABLED(OF_LIBFDT) /* find flattened device tree */ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, &images.ft_addr, &images.ft_len); @@ -706,7 +706,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, } } #endif -#if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB) +#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, diff --git a/common/image-board.c b/common/image-board.c index 0ad75fd..cb2479f 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -282,7 +282,7 @@ int genimg_get_format(const void *img_addr) if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; #endif -#if CONFIG_IS_ENABLED(FIT) || IMAGE_ENABLE_OF_LIBFDT +#if CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT) if (fdt_check_header(img_addr) == 0) return IMAGE_FORMAT_FIT; #endif @@ -895,7 +895,7 @@ int image_setup_linux(bootm_headers_t *images) struct lmb *lmb = &images->lmb; int ret; - if (IMAGE_ENABLE_OF_LIBFDT) + if (CONFIG_IS_ENABLED(OF_LIBFDT)) boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); if (IMAGE_BOOT_GET_CMDLINE) { @@ -907,13 +907,13 @@ int image_setup_linux(bootm_headers_t *images) } } - if (IMAGE_ENABLE_OF_LIBFDT) { + if (CONFIG_IS_ENABLED(OF_LIBFDT)) { ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); if (ret) return ret; } - if (IMAGE_ENABLE_OF_LIBFDT && of_size) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) { ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); if (ret) return ret; diff --git a/common/image.c b/common/image.c index 59b5e70..5b77113 100644 --- a/common/image.c +++ b/common/image.c @@ -18,7 +18,7 @@ #include #endif -#if CONFIG_IS_ENABLED(FIT) || IMAGE_ENABLE_OF_LIBFDT +#if CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT) #include #include #endif diff --git a/include/image.h b/include/image.h index 6c22921..f09eb9d 100644 --- a/include/image.h +++ b/include/image.h @@ -28,7 +28,6 @@ struct fdt_region; #include /* new uImage format support enabled on host */ -#define IMAGE_ENABLE_OF_LIBFDT 1 #define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ #define CONFIG_FIT_RSASSA_PSS 1 @@ -46,8 +45,6 @@ struct fdt_region; #define IMAGE_ENABLE_IGNORE 1 #define IMAGE_INDENT_STRING " " -#define IMAGE_ENABLE_OF_LIBFDT CONFIG_IS_ENABLED(OF_LIBFDT) - #endif /* USE_HOSTCC */ #if CONFIG_IS_ENABLED(FIT) diff --git a/lib/lmb.c b/lib/lmb.c index 7936477..676b3a0 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -153,7 +153,7 @@ static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob) arch_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); } diff --git a/tools/Kconfig b/tools/Kconfig index 6ffc2c0..747d221 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -50,6 +50,11 @@ config TOOLS_MD5 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 -- cgit v1.1 From e059157f0d5737b63fe2f1fec145509d82508109 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:22 -0600 Subject: image: Use Kconfig to enable CONFIG_FIT_VERBOSE on host Add a host Kconfig for FIT_VERBOSE. With this we can use CONFIG_IS_ENABLED(FIT_VERBOSE) directly in the tools build, so drop the forcing of this in the image.h header. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- include/image.h | 5 ++--- tools/Kconfig | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/image.h b/include/image.h index f09eb9d..6efbef0 100644 --- a/include/image.h +++ b/include/image.h @@ -28,7 +28,6 @@ struct fdt_region; #include /* new uImage format support enabled on host */ -#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ #define CONFIG_FIT_RSASSA_PSS 1 #define IMAGE_ENABLE_IGNORE 0 @@ -1458,7 +1457,7 @@ int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo); struct cipher_algo *image_get_cipher_algo(const char *full_name); -#ifdef CONFIG_FIT_VERBOSE +#if CONFIG_IS_ENABLED(FIT_VERBOSE) #define fit_unsupported(msg) printf("! %s:%d " \ "FIT images not supported for '%s'\n", \ __FILE__, __LINE__, (msg)) @@ -1470,7 +1469,7 @@ struct cipher_algo *image_get_cipher_algo(const char *full_name); #else #define fit_unsupported(msg) #define fit_unsupported_reset(msg) -#endif /* CONFIG_FIT_VERBOSE */ +#endif /* FIT_VERBOSE */ #endif /* CONFIG_FIT */ #if !defined(USE_HOSTCC) diff --git a/tools/Kconfig b/tools/Kconfig index 747d221..9d1c0ef 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -45,6 +45,11 @@ config TOOLS_FIT_SIGNATURE_MAX_SIZE 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 -- cgit v1.1 From 2bbed3ff8c7fa0c0fa3fd28a9497bf7a99e3388b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:23 -0600 Subject: image: Use Kconfig to enable FIT_RSASSA_PSS on host Add a host Kconfig for FIT_RSASSA_PSS. With this we can use CONFIG_IS_ENABLED(FIT_RSASSA_PSS) directly in the host build, so drop the forcing of this in the image.h header. Drop the #ifdef around padding_pss_verify() too since it is not needed. Use the compiler to check the config where possible, instead of the preprocessor. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- include/image.h | 3 --- include/u-boot/rsa.h | 2 -- lib/rsa/rsa-sign.c | 5 ++--- lib/rsa/rsa-verify.c | 15 ++++----------- tools/Kconfig | 5 +++++ 5 files changed, 11 insertions(+), 19 deletions(-) diff --git a/include/image.h b/include/image.h index 6efbef0..dc872ef 100644 --- a/include/image.h +++ b/include/image.h @@ -27,9 +27,6 @@ struct fdt_region; #include #include -/* new uImage format support enabled on host */ -#define CONFIG_FIT_RSASSA_PSS 1 - #define IMAGE_ENABLE_IGNORE 0 #define IMAGE_INDENT_STRING "" diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h index 89a9c4c..7556aa5 100644 --- a/include/u-boot/rsa.h +++ b/include/u-boot/rsa.h @@ -103,11 +103,9 @@ int padding_pkcs_15_verify(struct image_sign_info *info, uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len); -#ifdef CONFIG_FIT_RSASSA_PSS int padding_pss_verify(struct image_sign_info *info, uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len); -#endif /* CONFIG_FIT_RSASSA_PSS */ #define RSA_DEFAULT_PADDING_NAME "pkcs-1.5" diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index c27a784..0579e52 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -401,15 +401,14 @@ static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo, goto err_sign; } -#ifdef CONFIG_FIT_RSASSA_PSS - if (padding_algo && !strcmp(padding_algo->name, "pss")) { + if (CONFIG_IS_ENABLED(FIT_RSASSA_PSS) && padding_algo && + !strcmp(padding_algo->name, "pss")) { if (EVP_PKEY_CTX_set_rsa_padding(ckey, RSA_PKCS1_PSS_PADDING) <= 0) { ret = rsa_err("Signer padding setup failed"); goto err_sign; } } -#endif /* CONFIG_FIT_RSASSA_PSS */ for (i = 0; i < region_count; i++) { if (!EVP_DigestSignUpdate(context, region[i].data, diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index ad6d33d..600c93a 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -102,7 +102,7 @@ U_BOOT_PADDING_ALGO(pkcs_15) = { }; #endif -#ifdef CONFIG_FIT_RSASSA_PSS +#if CONFIG_IS_ENABLED(FIT_RSASSA_PSS) static void u32_i2osp(uint32_t val, uint8_t *buf) { buf[0] = (uint8_t)((val >> 24) & 0xff); @@ -313,7 +313,6 @@ U_BOOT_PADDING_ALGO(pss) = { #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 * @@ -385,9 +384,7 @@ static int rsa_verify_key(struct image_sign_info *info, return 0; } -#endif -#if CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY) /** * rsa_verify_with_pkey() - Verify a signature against some data using * 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; int ret; + if (!CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)) + return -EACCES; + /* Public key is self-described to fill key_prop */ ret = rsa_gen_key_prop(info->key, info->keylen, &prop); if (ret) { @@ -422,13 +422,6 @@ int rsa_verify_with_pkey(struct image_sign_info *info, 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) /** diff --git a/tools/Kconfig b/tools/Kconfig index 9d1c0ef..8685c80 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -35,6 +35,11 @@ config TOOLS_FIT_PRINT 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 -- cgit v1.1 From e7d285b2f38202f9d7ffbdcae59283f08bafd8b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:24 -0600 Subject: image: Use the correct checks for CRC32 Add a host Kconfig for CRC32. With this we can use CONFIG_IS_ENABLED(CRC32) directly in the host build, so drop the unnecessary indirection. Add a few more conditions to SPL_CRC32 to avoid build failures as well as TPL_CRC32. Also update hash.c to make crc32 optional and to actually take notice of SPL_CRC32. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/hash.c | 13 ++++++++----- common/spl/Kconfig | 13 ++++++++++++- lib/Kconfig | 5 +++++ lib/Makefile | 4 +--- tools/Kconfig | 5 +++++ 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/common/hash.c b/common/hash.c index 3b591ba0..79202e1 100644 --- a/common/hash.c +++ b/common/hash.c @@ -178,7 +178,7 @@ static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx, 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)); *ctx = 0; @@ -186,15 +186,16 @@ static int hash_init_crc32(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_crc32(struct hash_algo *algo, void *ctx, - const void *buf, unsigned int size, int is_last) +static int __maybe_unused hash_update_crc32(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, + int is_last) { *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size); return 0; } -static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf, - int size) +static int __maybe_unused hash_finish_crc32(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) { if (size < algo->digest_size) return -1; @@ -311,6 +312,7 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc16_ccitt, .hash_finish = hash_finish_crc16_ccitt, }, +#if CONFIG_IS_ENABLED(CRC32) { .name = "crc32", .digest_size = 4, @@ -320,6 +322,7 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc32, .hash_finish = hash_finish_crc32, }, +#endif }; /* Try to minimize code size for boards that don't want much hashing */ diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 8a8a971..17ce2f6 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -419,7 +419,8 @@ config SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION config SPL_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 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. @@ -1419,6 +1420,16 @@ config TPL_BOOTROM_SUPPORT BOOT_DEVICE_BOOTROM (or fall-through to the next boot device in the 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 bool "Support misc drivers in TPL" help diff --git a/lib/Kconfig b/lib/Kconfig index 64765ac..70bf8e7 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -496,6 +496,11 @@ config SPL_MD5 security applications, but it can be useful for providing a quick checksum of a block of data. +config CRC32 + def_bool y + help + Enables CRC32 support in U-Boot. This is normally required. + config CRC32C bool diff --git a/lib/Makefile b/lib/Makefile index 454396f..5ddbc77 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -96,9 +96,7 @@ obj-y += display_options.o CFLAGS_display_options.o := $(if $(BUILD_TAG),-DBUILD_TAG='"$(BUILD_TAG)"') obj-$(CONFIG_BCH) += bch.o obj-$(CONFIG_MMC_SPI) += crc7.o -#ifndef CONFIG_TPL_BUILD -obj-y += crc32.o -#endif +obj-$(CONFIG_$(SPL_TPL_)CRC32) += crc32.o obj-$(CONFIG_CRC32C) += crc32c.o obj-y += ctype.o obj-y += div64.o diff --git a/tools/Kconfig b/tools/Kconfig index 8685c80..91ce8ae 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -9,6 +9,11 @@ config MKIMAGE_DTC_PATH some cases the system dtc may not support all required features 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 bool "Use OpenSSL's libcrypto library for host tools" default y -- cgit v1.1 From 806d1ff37b0afe8cbf5658dc01876f6321aed235 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:25 -0600 Subject: image: Drop IMAGE_BOOT_GET_CMDLINE This is not needed with Kconfig, since we can use IS_ENABLED() easily enough and the board code is now in a separate file. Update the only place where this is used and drop it. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/image-board.c | 2 +- include/image.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index cb2479f..6565f01 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -898,7 +898,7 @@ int image_setup_linux(bootm_headers_t *images) if (CONFIG_IS_ENABLED(OF_LIBFDT)) boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); - if (IMAGE_BOOT_GET_CMDLINE) { + if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) { ret = boot_get_cmdline(lmb, &images->cmdline_start, &images->cmdline_end); if (ret) { diff --git a/include/image.h b/include/image.h index dc872ef..00a8099 100644 --- a/include/image.h +++ b/include/image.h @@ -49,12 +49,6 @@ struct fdt_region; #include #endif /* FIT */ -#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 -- cgit v1.1 From 30ba2828652915d29892146022ed92b2bd524ad6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:26 -0600 Subject: image: Drop IMAGE_OF_BOARD_SETUP This is not needed with Kconfig, since we can use IS_ENABLED() easily enough. Drop it. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/image-fdt.c | 4 ++-- include/image.h | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/common/image-fdt.c b/common/image-fdt.c index b698e96..2be6d19 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -582,7 +582,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, /* Append PStore configuration */ fdt_fixup_pstore(blob); #endif - if (IMAGE_OF_BOARD_SETUP) { + if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) { const char *skip_board_fixup; skip_board_fixup = env_get("skip_board_fixup"); @@ -629,7 +629,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, goto err; #if defined(CONFIG_ARCH_KEYSTONE) - if (IMAGE_OF_BOARD_SETUP) + if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) ft_board_setup_ex(blob, gd->bd); #endif diff --git a/include/image.h b/include/image.h index 00a8099..e1e4148 100644 --- a/include/image.h +++ b/include/image.h @@ -49,12 +49,6 @@ struct fdt_region; #include #endif /* FIT */ -#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 -- cgit v1.1 From 3ac0f504125e2f97364ba8cc6bc95c1e350bd35a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:27 -0600 Subject: image: Drop IMAGE_OF_SYSTEM_SETUP This is not needed with Kconfig, since we can use IS_ENABLED() easily enough. Drop it. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/image-fdt.c | 2 +- include/image.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/common/image-fdt.c b/common/image-fdt.c index 2be6d19..abea17b 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -597,7 +597,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); if (fdt_ret) { printf("ERROR: system-specific fdt fixup failed: %s\n", diff --git a/include/image.h b/include/image.h index e1e4148..e190f59 100644 --- a/include/image.h +++ b/include/image.h @@ -49,12 +49,6 @@ struct fdt_region; #include #endif /* FIT */ -#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_save_addr; /* Default Save Address */ extern ulong image_save_size; /* Default Save Size */ -- cgit v1.1 From fa13940740e5ce1822611205bb8ac329c91306fd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:28 -0600 Subject: image: Drop IMAGE_ENABLE_IGNORE We can use the new host_build() function for this, so drop it. Signed-off-by: Simon Glass Reviewed-by: Alexandru Gagniuc --- common/image-fit.c | 2 +- include/image.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index 17c6d4e..f44f552 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1277,7 +1277,7 @@ static int fit_image_check_hash(const void *fit, int noffset, const void *data, } printf("%s", algo); - if (IMAGE_ENABLE_IGNORE) { + if (!tools_build()) { fit_image_hash_get_ignore(fit, noffset, &ignore); if (ignore) { printf("-skipped "); diff --git a/include/image.h b/include/image.h index e190f59..a236180 100644 --- a/include/image.h +++ b/include/image.h @@ -27,7 +27,6 @@ struct fdt_region; #include #include -#define IMAGE_ENABLE_IGNORE 0 #define IMAGE_INDENT_STRING "" #else @@ -37,8 +36,6 @@ struct fdt_region; #include #include -/* Take notice of the 'ignore' property for hashes */ -#define IMAGE_ENABLE_IGNORE 1 #define IMAGE_INDENT_STRING " " #endif /* USE_HOSTCC */ -- cgit v1.1 From 1eccbb16a2c0427488d91e169572c3c397c4c1d5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:29 -0600 Subject: efi: Correct dependency on FIT_SIGNATURE At present EFI_SECURE BOOT selects RSA but does not necessarily enable FIT_SIGNATURE. Mostly this is fine, but a few boards do not enable it, so U-Boot tries to do RSA verification when loading FIT images, but it is not enabled. This worked because the condition for checking the RSA signature is wrong in the fit_image_verify_with_data() function. In order to fix it we need to fix this dependency. Make sure that FIT_SIGNATURE is enabled so that RSA can be used. It might be better to avoid using 'select' in this situation. Signed-off-by: Simon Glass --- lib/efi_loader/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 3d5a5cd..83d584a6 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -336,7 +336,7 @@ config EFI_LOAD_FILE2_INITRD config EFI_SECURE_BOOT bool "Enable EFI secure boot support" - depends on EFI_LOADER + depends on EFI_LOADER && FIT_SIGNATURE select HASH select SHA256 select RSA -- cgit v1.1 From 0ab5e027045f78973b7b7d52a71a89a707398f9f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:32 -0600 Subject: image: Tidy up fit_unsupported_reset() This function is only used in one place and does not need to use the preprocessor. Move it to the C file and convert it to a normal function. Drop fit_unsupported() since it is not used. Signed-off-by: Simon Glass --- common/bootm_os.c | 8 ++++++++ include/image.h | 13 ------------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/common/bootm_os.c b/common/bootm_os.c index d635037..39623f9 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -58,6 +58,14 @@ static void copy_args(char *dest, int argc, char *const argv[], char delim) } #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 static int do_bootm_netbsd(int flag, int argc, char *const argv[], bootm_headers_t *images) diff --git a/include/image.h b/include/image.h index a236180..e397da8 100644 --- a/include/image.h +++ b/include/image.h @@ -1433,19 +1433,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); -#if CONFIG_IS_ENABLED(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 /* FIT_VERBOSE */ #endif /* CONFIG_FIT */ #if !defined(USE_HOSTCC) -- cgit v1.1 From 13c133b995decefdc64160f1df2c58e5bf342e28 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:33 -0600 Subject: image: Drop unnecessary #ifdefs from image.h This file has a lot of conditional code and much of it is unnecessary. Clean this up to reduce the number of build combinations. Signed-off-by: Simon Glass --- include/image.h | 39 ++++----------------------------------- include/u-boot/hash-checksum.h | 5 +++-- lib/hash-checksum.c | 2 +- 3 files changed, 8 insertions(+), 38 deletions(-) diff --git a/include/image.h b/include/image.h index e397da8..04eccb1 100644 --- a/include/image.h +++ b/include/image.h @@ -40,11 +40,10 @@ struct fdt_region; #endif /* USE_HOSTCC */ -#if CONFIG_IS_ENABLED(FIT) #include #include #include -#endif /* FIT */ +#include extern ulong image_load_addr; /* Default Load Address */ extern ulong image_save_addr; /* Default Save Address */ @@ -504,8 +503,7 @@ int genimg_get_type_id(const char *name); int genimg_get_comp_id(const char *name); void genimg_print_size(uint32_t size); -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || \ - defined(USE_HOSTCC) +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) #define IMAGE_ENABLE_TIMESTAMP 1 #else #define IMAGE_ENABLE_TIMESTAMP 0 @@ -523,12 +521,9 @@ enum fit_load_op { int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start, ulong *setup_len); -#ifndef USE_HOSTCC /* Image format types, returned by _get_format() routine */ #define IMAGE_FORMAT_INVALID 0x00 -#if defined(CONFIG_LEGACY_IMAGE_FORMAT) #define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ -#endif #define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ #define IMAGE_FORMAT_ANDROID 0x03 /* Android boot image */ @@ -567,7 +562,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, 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, ulong *setup_start, ulong *setup_len); @@ -644,7 +638,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr, */ 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 * @@ -684,10 +677,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, ulong *initrd_start, ulong *initrd_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); -#endif /* CONFIG_SYS_BOOT_GET_KBD */ -#endif /* !USE_HOSTCC */ /*******************************************************************/ /* Legacy format specific code (prefixed with image_) */ @@ -802,11 +792,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) { -#ifndef USE_HOSTCC /* Let's assume that sandbox can load any architecture */ - if (IS_ENABLED(CONFIG_SANDBOX)) + if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) return true; -#endif return (image_get_arch(hdr) == arch) || (image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64); } @@ -954,7 +942,6 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE -#if CONFIG_IS_ENABLED(FIT) /* cmdline argument format parsing */ int fit_parse_conf(const char *spec, ulong addr_curr, ulong *addr, const char **conf_name); @@ -1128,7 +1115,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset, int fit_check_ramdisk(const void *fit, int os_noffset, uint8_t arch, int verify); -#endif /* FIT */ int calculate_hash(const void *data, int data_len, const char *algo, uint8_t *value, int *value_len); @@ -1151,7 +1137,6 @@ int calculate_hash(const void *data, int data_len, const char *algo, # define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE) #endif -#if CONFIG_IS_ENABLED(FIT) #ifdef USE_HOSTCC void *image_get_host_blob(void); void image_set_host_blob(void *host_blob); @@ -1160,8 +1145,6 @@ void image_set_host_blob(void *host_blob); # define gd_fdt_blob() (gd->fdt_blob) #endif -#endif /* IMAGE_ENABLE_FIT */ - /* * Information passed to the signing routines * @@ -1198,9 +1181,6 @@ struct image_region { int size; }; -#if FIT_IMAGE_ENABLE_VERIFY -# include -#endif struct checksum_algo { const char *name; const int checksum_len; @@ -1210,7 +1190,7 @@ struct checksum_algo { const EVP_MD *(*calculate_sign)(void); #endif int (*calculate)(const char *name, - const struct image_region region[], + const struct image_region *region, int region_count, uint8_t *checksum); }; @@ -1306,8 +1286,6 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name); */ struct padding_algo *image_get_padding_algo(const char *name); -#if CONFIG_IS_ENABLED(FIT) - /** * fit_image_verify_required_sigs() - Verify signatures marked as 'required' * @@ -1433,10 +1411,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); -#endif /* CONFIG_FIT */ - -#if !defined(USE_HOSTCC) -#if defined(CONFIG_ANDROID_BOOT_IMAGE) struct andr_img_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, @@ -1452,12 +1426,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_kcomp(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); -#endif - -#endif /* CONFIG_ANDROID_BOOT_IMAGE */ -#endif /* !USE_HOSTCC */ /** * board_fit_config_name_match() - Check for a matching board name diff --git a/include/u-boot/hash-checksum.h b/include/u-boot/hash-checksum.h index 54e6a73..7f16b37 100644 --- a/include/u-boot/hash-checksum.h +++ b/include/u-boot/hash-checksum.h @@ -7,11 +7,12 @@ #define _RSA_CHECKSUM_H #include -#include #include #include #include +struct image_region; + /** * hash_calculate() - Calculate hash over the data * @@ -23,7 +24,7 @@ * @return 0 if OK, < 0 if error */ 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); #endif diff --git a/lib/hash-checksum.c b/lib/hash-checksum.c index d732ecc..8f2a42f 100644 --- a/lib/hash-checksum.c +++ b/lib/hash-checksum.c @@ -17,7 +17,7 @@ #include int hash_calculate(const char *name, - const struct image_region region[], + const struct image_region *region, int region_count, uint8_t *checksum) { struct hash_algo *algo; -- cgit v1.1 From 78740bcce87518d2c71c96e41429c4e65f516635 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:34 -0600 Subject: image: Drop #ifdefs for fit_print_contents() Use a simple return to drop the unwanted code. Signed-off-by: Simon Glass --- common/image-fit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index f44f552..1e4099d 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -170,7 +170,6 @@ int fit_get_subimage_count(const void *fit, int images_noffset) return count; } -#if CONFIG_IS_ENABLED(FIT_PRINT) /** * fit_image_print_data() - prints out the hash node details * @fit: pointer to the FIT format image header @@ -380,6 +379,9 @@ void fit_print_contents(const void *fit) const char *p; time_t timestamp; + if (!CONFIG_IS_ENABLED(FIT_PRINT)) + return; + /* Indent string is defined in header image.h */ p = IMAGE_INDENT_STRING; @@ -482,6 +484,9 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) int ndepth; int ret; + if (!CONFIG_IS_ENABLED(FIT_PRINT)) + return; + /* Mandatory properties */ ret = fit_get_desc(fit, image_noffset, &desc); printf("%s Description: ", p); @@ -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(FIT_PRINT) */ /** * fit_get_desc - get node description property -- cgit v1.1 From 1df654a6af5b14731383039f868f12db7069a476 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:35 -0600 Subject: image: Drop most #ifdefs in image-board.c Remove ifdefs in this file, so far as possible without too much refactoring. Signed-off-by: Simon Glass --- common/image-board.c | 111 +++++++++++++++++++++++---------------------------- include/image.h | 7 +++- 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index 6565f01..4f3c98d 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -227,16 +227,16 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, kernel_addr = image_load_addr; debug("* kernel: default image load address = 0x%08lx\n", image_load_addr); -#if CONFIG_IS_ENABLED(FIT) - } else if (fit_parse_conf(img_addr, image_load_addr, &kernel_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 (fit_parse_subimage(img_addr, image_load_addr, &kernel_addr, - fit_uname_kernel)) { + } 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); -#endif } else { kernel_addr = hextoul(img_addr, NULL); debug("* kernel: cmdline image address = 0x%08lx\n", @@ -275,21 +275,20 @@ ulong genimg_get_kernel_addr(char * const img_addr) */ int genimg_get_format(const void *img_addr) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - const image_header_t *hdr; + 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; -#endif -#if CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT) - if (fdt_check_header(img_addr) == 0) - return IMAGE_FORMAT_FIT; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - if (android_image_check_header(img_addr) == 0) + 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; -#endif return IMAGE_FORMAT_INVALID; } @@ -307,10 +306,9 @@ int genimg_get_format(const void *img_addr) */ int genimg_has_config(bootm_headers_t *images) { -#if CONFIG_IS_ENABLED(FIT) - if (images->fit_uname_cfg) + if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg) return 1; -#endif + return 0; } @@ -345,9 +343,6 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, const image_header_t *rd_hdr; #endif void *buf; -#ifdef CONFIG_SUPPORT_RAW_INITRD - char *end; -#endif #if CONFIG_IS_ENABLED(FIT) const char *fit_uname_config = images->fit_uname_cfg; const char *fit_uname_ramdisk = NULL; @@ -359,14 +354,12 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, *rd_start = 0; *rd_end = 0; -#ifdef CONFIG_ANDROID_BOOT_IMAGE - /* - * 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]; -#endif + if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { + /* 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]; @@ -474,22 +467,22 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, break; #endif default: -#ifdef CONFIG_SUPPORT_RAW_INITRD - end = NULL; - if (select) - end = strchr(select, ':'); - if (end) { - rd_len = hextoul(++end, NULL); - rd_data = rd_addr; - } else -#endif - { - puts("Wrong Ramdisk Image Format\n"); - rd_data = 0; - rd_len = 0; - rd_load = 0; - return 1; + if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { + char *end = NULL; + + if (select) + end = strchr(select, ':'); + if (end) { + rd_len = hextoul(++end, NULL); + rd_data = rd_addr; + break; + } } + puts("Wrong Ramdisk Image Format\n"); + rd_data = 0; + rd_len = 0; + rd_load = 0; + return 1; } } else if (images->legacy_hdr_valid && image_check_type(&images->legacy_hdr_os_copy, @@ -524,7 +517,6 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -595,15 +587,15 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, memmove_wd((void *)*initrd_start, (void *)rd_data, rd_len, CHUNKSZ); -#ifdef CONFIG_MP /* * Ensure the image is flushed to memory to handle * AMP boot scenarios in which we might not be * HW cache coherent */ - flush_cache((unsigned long)*initrd_start, - ALIGN(rd_len, ARCH_DMA_MINALIGN)); -#endif + if (IS_ENABLED(CONFIG_MP)) { + flush_cache((unsigned long)*initrd_start, + ALIGN(rd_len, ARCH_DMA_MINALIGN)); + } puts("OK\n"); } } else { @@ -618,20 +610,16 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ int boot_get_setup(bootm_headers_t *images, u8 arch, ulong *setup_start, ulong *setup_len) { -#if CONFIG_IS_ENABLED(FIT) + if (!CONFIG_IS_ENABLED(FIT)) + return -ENOENT; + return boot_get_setup_fit(images, arch, setup_start, setup_len); -#else - return -ENOENT; -#endif } -#if CONFIG_IS_ENABLED(FIT) -#if defined(CONFIG_FPGA) int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { @@ -643,6 +631,9 @@ int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, 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"); @@ -714,7 +705,6 @@ int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#endif static void fit_loadable_process(u8 img_type, ulong img_data, @@ -812,7 +802,6 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#endif /** * boot_get_cmdline - allocate and initialize kernel cmdline diff --git a/include/image.h b/include/image.h index 04eccb1..34d13ad 100644 --- a/include/image.h +++ b/include/image.h @@ -298,7 +298,11 @@ typedef struct bootm_headers { image_header_t legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid; -#if CONFIG_IS_ENABLED(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 */ void *fit_hdr_os; /* os FIT image header */ @@ -316,7 +320,6 @@ typedef struct bootm_headers { void *fit_hdr_setup; /* x86 setup FIT image header */ const char *fit_uname_setup; /* x86 setup subimage node name */ int fit_noffset_setup;/* x86 setup subimage node offset */ -#endif #ifndef USE_HOSTCC image_info_t os; /* os image info */ -- cgit v1.1 From 78f88790e3f7693a1ee9a87cc53d79e959c5633f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:36 -0600 Subject: image: Reduce variable scope in boot_get_ramdisk() Move the variables declarations to where they are needed, to reduce the number of #ifdefs needed. Signed-off-by: Simon Glass --- common/image-board.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index 4f3c98d..131584a 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -337,18 +337,8 @@ int genimg_has_config(bootm_headers_t *images) int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, u8 arch, ulong *rd_start, ulong *rd_end) { - ulong rd_addr, rd_load; ulong rd_data, rd_len; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - const image_header_t *rd_hdr; -#endif void *buf; -#if CONFIG_IS_ENABLED(FIT) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_ramdisk = NULL; - ulong default_addr; - int rd_noffset; -#endif const char *select = NULL; *rd_start = 0; @@ -373,8 +363,15 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, rd_len = 0; rd_data = 0; } else if (select || genimg_has_config(images)) { + ulong rd_addr, rd_load; + #if CONFIG_IS_ENABLED(FIT) + const char *fit_uname_config = images->fit_uname_cfg; + const char *fit_uname_ramdisk = NULL; + int rd_noffset; + if (select) { + ulong default_addr; /* * If the init ramdisk comes from the FIT image and * the FIT image address is omitted in the command @@ -427,7 +424,9 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, buf = map_sysmem(rd_addr, 0); switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: + case IMAGE_FORMAT_LEGACY: { + const image_header_t *rd_hdr; + printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", rd_addr); @@ -442,6 +441,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, rd_len = image_get_data_size(rd_hdr); rd_load = image_get_load(rd_hdr); break; + } #endif #if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: -- cgit v1.1 From e4c928792e93ed87abb1633cc3f80c2d0a84dd4a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:37 -0600 Subject: image: Split up boot_get_ramdisk() This function is far too long. Before trying to remove #ifdefs, split out the code that deals with selecting the ramdisk into a separate function. Leave the code indented as it was for easier review. The next patch cleans this up along with checkpatch violations. Signed-off-by: Simon Glass --- common/image-board.c | 149 +++++++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 63 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index 131584a..b693a52 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -313,57 +313,21 @@ int genimg_has_config(bootm_headers_t *images) } /** - * boot_get_ramdisk - main ramdisk handling routine - * @argc: command argument count - * @argv: command argument list + * 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_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 + * @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 */ -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, - u8 arch, ulong *rd_start, ulong *rd_end) +static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, + ulong *rd_datap, ulong *rd_lenp) { - ulong rd_data, rd_len; - void *buf; - const char *select = NULL; - - *rd_start = 0; - *rd_end = 0; - - if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { - /* 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)) { - ulong rd_addr, rd_load; + ulong rd_addr; + char *buf; #if CONFIG_IS_ENABLED(FIT) const char *fit_uname_config = images->fit_uname_cfg; @@ -403,16 +367,16 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, } else { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, - * quit silently. + * 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 0; + return -ENOPKG; else if (rd_noffset < 0) - return 1; + return rd_noffset; } #endif @@ -435,11 +399,10 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, images->verify); if (!rd_hdr) - return 1; + return -ENOENT; - rd_data = image_get_data(rd_hdr); - rd_len = image_get_data_size(rd_hdr); - rd_load = image_get_load(rd_hdr); + *rd_datap = image_get_data(rd_hdr); + *rd_lenp = image_get_data_size(rd_hdr); break; } #endif @@ -451,9 +414,9 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, IH_TYPE_RAMDISK, BOOTSTAGE_ID_FIT_RD_START, FIT_LOAD_OPTIONAL_NON_ZERO, - &rd_data, &rd_len); + rd_datap, rd_lenp); if (rd_noffset < 0) - return 1; + return rd_noffset; images->fit_hdr_rd = map_sysmem(rd_addr, 0); images->fit_uname_rd = fit_uname_ramdisk; @@ -463,7 +426,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: android_image_get_ramdisk((void *)images->os.start, - &rd_data, &rd_len); + rd_datap, rd_lenp); break; #endif default: @@ -473,17 +436,77 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, if (select) end = strchr(select, ':'); if (end) { - rd_len = hextoul(++end, NULL); - rd_data = rd_addr; + *rd_lenp = hextoul(++end, NULL); + *rd_datap = rd_addr; break; } } puts("Wrong Ramdisk Image Format\n"); - rd_data = 0; - rd_len = 0; - rd_load = 0; - return 1; + 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)) { -- cgit v1.1 From f33a2c1bd0fb371511a485cac1f182ba50db51be Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:38 -0600 Subject: image: Remove #ifdefs from select_ramdisk() Use boolean variables to deal with the strange #ifdef logic of this function, so we can remove the #ifdefs. Signed-off-by: Simon Glass --- common/image-board.c | 139 ++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 67 deletions(-) diff --git a/common/image-board.c b/common/image-board.c index b693a52..e766035 100644 --- a/common/image-board.c +++ b/common/image-board.c @@ -26,7 +26,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** * image_get_ramdisk - get and verify ramdisk image * @rd_addr: ramdisk image start address @@ -85,7 +84,6 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, return rd_hdr; } -#endif /*****************************************************************************/ /* Shared dual-format routines */ @@ -326,16 +324,18 @@ int genimg_has_config(bootm_headers_t *images) static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { - ulong rd_addr; + 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 CONFIG_IS_ENABLED(FIT) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_ramdisk = NULL; - int rd_noffset; + if (select) { + ulong default_addr; + bool done = true; - if (select) { - ulong default_addr; + if (CONFIG_IS_ENABLED(FIT)) { /* * If the init ramdisk comes from the FIT image and * the FIT image address is omitted in the command @@ -347,8 +347,8 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, else default_addr = image_load_addr; - if (fit_parse_conf(select, default_addr, - &rd_addr, &fit_uname_config)) { + 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, @@ -356,60 +356,58 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, &fit_uname_ramdisk)) { debug("* ramdisk: subimage '%s' from image at 0x%08lx\n", fit_uname_ramdisk, rd_addr); - } else -#endif - { - rd_addr = hextoul(select, NULL); - debug("* ramdisk: cmdline image address = 0x%08lx\n", - rd_addr); + } else { + done = false; } -#if CONFIG_IS_ENABLED(FIT) - } else { - /* 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; } -#endif - - /* - * 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. + 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 ) */ - buf = map_sysmem(rd_addr, 0); - switch (genimg_get_format(buf)) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: { + 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); - + 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); - break; + processed = true; } -#endif -#if CONFIG_IS_ENABLED(FIT) - case IMAGE_FORMAT_FIT: - rd_noffset = fit_image_load(images, - rd_addr, &fit_uname_ramdisk, + 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, @@ -421,29 +419,36 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, images->fit_hdr_rd = map_sysmem(rd_addr, 0); images->fit_uname_rd = fit_uname_ramdisk; images->fit_noffset_rd = rd_noffset; - break; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - case IMAGE_FORMAT_ANDROID: + 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); - break; -#endif - default: - 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; - break; - } + 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; } -- cgit v1.1 From b53541f7f61d506c6b19b30357f471472831e9cb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:39 -0600 Subject: image: Remove some #ifdefs from image-fit and image-fit-sig Drop the #ifdefs which are easy to remove without refactoring. Signed-off-by: Simon Glass --- common/Kconfig.boot | 10 ++++++++++ common/image-fit-sig.c | 8 ++------ common/image-fit.c | 7 ++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/common/Kconfig.boot b/common/Kconfig.boot index f23b998..9b84a8d 100644 --- a/common/Kconfig.boot +++ b/common/Kconfig.boot @@ -165,6 +165,16 @@ config SPL_FIT_SIGNATURE select SPL_IMAGE_SIGN_INFO 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 bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)" select SPL_FIT diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c index e95e64b..4edebbf 100644 --- a/common/image-fit-sig.c +++ b/common/image-fit-sig.c @@ -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 * must allocate the array. */ -#ifndef CONFIG_SPL_BUILD - if (!region) + if (!IS_ENABLED(CONFIG_SPL_BUILD) && !region) region = calloc(sizeof(*region), count); -#endif if (!region) return NULL; for (i = 0; i < count; i++) { @@ -72,12 +70,10 @@ static int fit_image_setup_verify(struct image_sign_info *info, char *algo_name; const char *padding_name; -#ifndef USE_HOSTCC - 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"; return 1; } -#endif if (fit_image_hash_get_algo(fit, noffset, &algo_name)) { *err_msgp = "Can't get hash algo property"; return -1; diff --git a/common/image-fit.c b/common/image-fit.c index 1e4099d..33b4a46 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -2009,9 +2009,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr, int type_ok, os_ok; ulong load, load_end, data, len; uint8_t os, comp; -#ifndef USE_HOSTCC - uint8_t os_arch; -#endif const char *prop_name; int ret; @@ -2103,8 +2100,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr, } #ifndef USE_HOSTCC + { + uint8_t os_arch; + fit_image_get_arch(fit, noffset, &os_arch); images->os.arch = os_arch; + } #endif bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); -- cgit v1.1 From a2198cd0185904929d90a1a814d7e0b47877e46b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:40 -0600 Subject: image: Reduce variable scope in boot_get_fdt() Move the variables declarations to where they are needed, to reduce the number of #ifdefs needed. Signed-off-by: Simon Glass --- common/image-fdt.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/common/image-fdt.c b/common/image-fdt.c index abea17b..58c8936 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -276,21 +276,10 @@ error: 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) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - const image_header_t *fdt_hdr; - 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) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_fdt = NULL; - ulong default_addr; - int fdt_noffset; -#endif const char *select = NULL; *of_flat_tree = NULL; @@ -304,6 +293,11 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, select = argv[2]; if (select || genimg_has_config(images)) { #if CONFIG_IS_ENABLED(FIT) + const char *fit_uname_config = images->fit_uname_cfg; + const char *fit_uname_fdt = NULL; + ulong default_addr; + int fdt_noffset; + if (select) { /* * If the FDT blob comes from the FIT image and the @@ -359,7 +353,11 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, buf = map_sysmem(fdt_addr, 0); switch (genimg_get_format(buf)) { #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 */ printf("## Flattened Device Tree from Legacy Image at %08lx\n", fdt_addr); @@ -398,6 +396,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, fdt_addr = load; break; + } #endif case IMAGE_FORMAT_FIT: /* -- cgit v1.1 From 4cb35b7a1fdf060a0839b71f6dbf8d08b1ae62e0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 25 Sep 2021 19:43:41 -0600 Subject: image: Split up boot_get_fdt() This function is far too long. Before trying to remove #ifdefs, split out the code that deals with selecting the FDT into a separate function. Signed-off-by: Simon Glass --- common/image-fdt.c | 226 +++++++++++++++++++++++++++++------------------------ 1 file changed, 126 insertions(+), 100 deletions(-) diff --git a/common/image-fdt.c b/common/image-fdt.c index 58c8936..7aad6d5 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -252,53 +252,29 @@ error: } /** - * 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. - * Curently 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 + * select_fdt() - Select and locate the FDT to use * - * 1, if fdt image is found but corrupted - * of_flat_tree and of_size are set to 0 if no fdt exists + * @images: pointer to the bootm images structure + * @select: name of FDT to select, or NULL for any + * @arch: expected FDT architecture + * @fdt_addrp: pointer to a ulong variable, will hold FDT pointer + * @return 0 if OK, -ENOPKG if no FDT (but an error should not be reported), + * other -ve value on other error */ -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); +static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, + ulong *fdt_addrp) +{ + const char *buf; + ulong fdt_addr; - if (argc > 2) - select = argv[2]; - if (select || genimg_has_config(images)) { #if CONFIG_IS_ENABLED(FIT) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_fdt = NULL; - ulong default_addr; - int fdt_noffset; + const char *fit_uname_config = images->fit_uname_cfg; + const char *fit_uname_fdt = NULL; + ulong default_addr; + int fdt_noffset; - if (select) { + if (select) { /* * If the FDT blob comes from the FIT image and the * FIT image address is omitted in the command line @@ -312,48 +288,47 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, else default_addr = image_load_addr; - if (fit_parse_conf(select, default_addr, - &fdt_addr, &fit_uname_config)) { + if (fit_parse_conf(select, default_addr, &fdt_addr, + &fit_uname_config)) { debug("* fdt: config '%s' from image at 0x%08lx\n", fit_uname_config, fdt_addr); - } else if (fit_parse_subimage(select, default_addr, - &fdt_addr, &fit_uname_fdt)) { + } else if (fit_parse_subimage(select, default_addr, &fdt_addr, + &fit_uname_fdt)) { debug("* fdt: subimage '%s' from image at 0x%08lx\n", fit_uname_fdt, fdt_addr); } else #endif - { - fdt_addr = hextoul(select, NULL); - debug("* fdt: cmdline image address = 0x%08lx\n", - 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; + { + fdt_addr = hextoul(select, NULL); + debug("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); } -#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. +#if CONFIG_IS_ENABLED(FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument */ - buf = map_sysmem(fdt_addr, 0); - switch (genimg_get_format(buf)) { + 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 -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) - 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; @@ -363,7 +338,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, fdt_addr); fdt_hdr = image_get_fdt(fdt_addr); if (!fdt_hdr) - goto no_fdt; + return -ENOPKG; /* * move image data to the load address, @@ -384,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)) { fdt_error("fdt overwritten"); - goto error; + return -EFAULT; } debug(" Loading FDT from 0x%08lx to 0x%08lx\n", @@ -398,24 +373,24 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, break; } #endif - case IMAGE_FORMAT_FIT: - /* - * This case will catch both: new uImage format - * (libfdt based) and raw FDT blob (also libfdt - * based). - */ + case IMAGE_FORMAT_FIT: + /* + * This case will catch both: new uImage format + * (libfdt based) and raw FDT blob (also libfdt + * based). + */ #if CONFIG_IS_ENABLED(FIT) /* check FDT blob vs FIT blob */ if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) { ulong load, len; - fdt_noffset = boot_get_fdt_fit(images, - fdt_addr, &fit_uname_fdt, - &fit_uname_config, - arch, &load, &len); + fdt_noffset = boot_get_fdt_fit(images, fdt_addr, + &fit_uname_fdt, + &fit_uname_config, + arch, &load, &len); if (fdt_noffset < 0) - goto error; + return -ENOENT; images->fit_hdr_fdt = map_sysmem(fdt_addr, 0); images->fit_uname_fdt = fit_uname_fdt; @@ -423,22 +398,73 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, fdt_addr = load; break; - } else + } else #endif - { - /* - * FDT blob - */ - debug("* fdt: raw FDT blob\n"); - printf("## Flattened Device Tree blob at %08lx\n", - (long)fdt_addr); - } - break; - default: - puts("ERROR: Did not find a cmdline Flattened Device Tree\n"); - goto error; + { + /* + * FDT blob + */ + debug("* fdt: raw FDT blob\n"); + printf("## Flattened Device Tree blob at %08lx\n", + (long)fdt_addr); } + 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); fdt_blob = map_sysmem(fdt_addr, 0); } else if (images->legacy_hdr_valid && -- cgit v1.1