summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib32/bootm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib32/bootm.c')
-rw-r--r--arch/arm/lib32/bootm.c72
1 files changed, 63 insertions, 9 deletions
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index d64e705c40..e814593dce 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
#include <bootm.h>
#include <boot.h>
#include <common.h>
@@ -20,7 +22,7 @@
#include <restart.h>
#include <globalvar.h>
#include <tee/optee.h>
-
+#include <image-fit.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
#include <asm/barebox-arm.h>
@@ -104,11 +106,25 @@ static int get_kernel_addresses(size_t image_size,
spacing = SZ_1M;
if (*load_address == UIMAGE_INVALID_ADDRESS) {
+ unsigned long mem_end = mem_start + mem_size - 1;
+ unsigned long kaddr;
+
/*
* Place the kernel at an address where it does not need to
* relocate itself before decompression.
*/
- *load_address = mem_start + image_decomp_size;
+ kaddr = mem_start + image_decomp_size;
+
+ /*
+ * Make sure we do not place the image outside of the
+ * available memory.
+ */
+ if (((kaddr + image_size + spacing) > mem_end) &&
+ ((mem_end - image_size - spacing) >= mem_start))
+ kaddr = mem_end - image_size - spacing;
+
+ *load_address = PAGE_ALIGN_DOWN(kaddr);
+
if (verbose)
printf("no OS load address, defaulting to 0x%08lx\n",
*load_address);
@@ -153,6 +169,34 @@ static int optee_verify_header_request_region(struct image_data *data, struct op
return ret;
}
+static int bootm_load_tee_from_fit(struct image_data *data)
+{
+ int ret = 0;
+ struct optee_header hdr;
+
+ if (data->os_fit &&
+ fit_has_image(data->os_fit, data->fit_config, "tee")) {
+ const void *tee;
+ unsigned long tee_size;
+
+ ret = fit_open_image(data->os_fit, data->fit_config, "tee",
+ &tee, &tee_size);
+ if (ret) {
+ pr_err("Error opening tee fit image: %s\n", strerror(-ret));
+ return ret;
+ }
+ memcpy(&hdr, tee, sizeof(hdr));
+ if (optee_verify_header_request_region(data, &hdr) < 0) {
+ pr_err("%s", strerror(errno));
+ ret = -errno;
+ goto out;
+ }
+ memcpy((void *)data->tee_res->start, tee + sizeof(hdr), hdr.init_size);
+ printf("Read optee image to %pa, size 0x%08x\n", (void *)data->tee_res->start, hdr.init_size);
+ }
+out:
+ return ret;
+}
static int bootm_load_tee_from_file(struct image_data *data)
{
int fd, ret;
@@ -249,10 +293,16 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
return ret;
}
- if (IS_ENABLED(CONFIG_BOOTM_OPTEE) && data->tee_file) {
- ret = bootm_load_tee_from_file(data);
- if (ret)
- return ret;
+ if (IS_ENABLED(CONFIG_BOOTM_OPTEE)) {
+ if (data->tee_file && !IS_ENABLED(CONFIG_BOOTM_FORCE_SIGNED_IMAGES)) {
+ ret = bootm_load_tee_from_file(data);
+ if (ret)
+ return ret;
+ } else if (IS_ENABLED(CONFIG_FITIMAGE)) {
+ ret = bootm_load_tee_from_fit(data);
+ if (ret)
+ return ret;
+ }
}
@@ -277,6 +327,10 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
if (data->dryrun)
return 0;
+ ret = of_overlay_load_firmware();
+ if (ret)
+ return ret;
+
if (data->tee_res)
tee = (void *)data->tee_res->start;
else
@@ -373,7 +427,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data, void **outfdt)
if (IS_BUILTIN(CONFIG_OFTREE)) {
struct device_node *root;
- root = of_unflatten_dtb(oftree);
+ root = of_unflatten_dtb(oftree, header->totalsize);
if (IS_ERR(root)) {
pr_err("unable to unflatten devicetree\n");
goto err_free;
@@ -698,8 +752,8 @@ static struct binfmt_hook binfmt_barebox_hook = {
.exec = "bootm",
};
-BAREBOX_MAGICVAR_NAMED(global_bootm_boot_atag, global.bootm.boot_atag,
- "If true, ignore device tree and boot using ATAGs");
+BAREBOX_MAGICVAR(global.bootm.boot_atag,
+ "If true, ignore device tree and boot using ATAGs");
static int armlinux_register_image_handler(void)
{