summaryrefslogtreecommitdiff
path: root/arch/arm/lib
diff options
context:
space:
mode:
authorBin Chen <bin.chen@linaro.org>2018-01-27 16:59:09 +1100
committerTom Rini <trini@konsulko.com>2018-02-07 22:06:11 -0500
commit6808ef9ac2a66a261bf341a99c3edb1e69f1cbdd (patch)
tree06c6405823dc4510fe08da28adb05e516420711b /arch/arm/lib
parent104816142f9c6a4c8c164e7541a3424bcf5e8e91 (diff)
move booti_setup to arch/arm/lig/image.c
Follow bootz's pattern by moving the booti_setup to arch/arm/lib. This allows to use booti_setup in other paths, e.g booting an Android image containing Image format. Note that kernel relocation is move out of booti_setup and it is the caller's responsibility to do it and allows them do it differently. say, cmd/booti.c just do a manually, while in the bootm path, we can use bootm_load_os(with some changes). Signed-off-by: Bin Chen <bin.chen@linaro.org> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/image.c77
2 files changed, 78 insertions, 1 deletions
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 876024fc15..b5ffffd4e3 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -32,7 +32,7 @@ endif
obj-$(CONFIG_CPU_V7M) += cmd_boot.o
obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
-obj-$(CONFIG_CMD_BOOTI) += bootm.o
+obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
diff --git a/arch/arm/lib/image.c b/arch/arm/lib/image.c
new file mode 100644
index 0000000000..f72cf63ed8
--- /dev/null
+++ b/arch/arm/lib/image.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <mapmem.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define LINUX_ARM64_IMAGE_MAGIC 0x644d5241
+
+/* See Documentation/arm64/booting.txt in the Linux kernel */
+struct Image_header {
+ uint32_t code0; /* Executable code */
+ uint32_t code1; /* Executable code */
+ uint64_t text_offset; /* Image load offset, LE */
+ uint64_t image_size; /* Effective Image size, LE */
+ uint64_t flags; /* Kernel flags, LE */
+ uint64_t res2; /* reserved */
+ uint64_t res3; /* reserved */
+ uint64_t res4; /* reserved */
+ uint32_t magic; /* Magic number */
+ uint32_t res5;
+};
+
+int booti_setup(ulong image, ulong *relocated_addr, ulong *size)
+{
+ struct Image_header *ih;
+ uint64_t dst;
+ uint64_t image_size, text_offset;
+
+ *relocated_addr = image;
+
+ ih = (struct Image_header *)map_sysmem(image, 0);
+
+ if (ih->magic != le32_to_cpu(LINUX_ARM64_IMAGE_MAGIC)) {
+ puts("Bad Linux ARM64 Image magic!\n");
+ return 1;
+ }
+
+ /*
+ * Prior to Linux commit a2c1d73b94ed, the text_offset field
+ * is of unknown endianness. In these cases, the image_size
+ * field is zero, and we can assume a fixed value of 0x80000.
+ */
+ if (ih->image_size == 0) {
+ puts("Image lacks image_size field, assuming 16MiB\n");
+ image_size = 16 << 20;
+ text_offset = 0x80000;
+ } else {
+ image_size = le64_to_cpu(ih->image_size);
+ text_offset = le64_to_cpu(ih->text_offset);
+ }
+
+ *size = image_size;
+
+ /*
+ * If bit 3 of the flags field is set, the 2MB aligned base of the
+ * kernel image can be anywhere in physical memory, so respect
+ * images->ep. Otherwise, relocate the image to the base of RAM
+ * since memory below it is not accessible via the linear mapping.
+ */
+ if (le64_to_cpu(ih->flags) & BIT(3))
+ dst = image - text_offset;
+ else
+ dst = gd->bd->bi_dram[0].start;
+
+ *relocated_addr = ALIGN(dst, SZ_2M) + text_offset;
+
+ unmap_sysmem(ih);
+
+ return 0;
+}