summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-07-09 08:21:04 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-07-09 08:21:04 +0200
commit0e8bd85d9b2f981ad24847badda70c73397d8385 (patch)
treead0e96ae3da29ab5c5797d99555d280e9b4d5d14
parentb5ba232df1cf1fd68bd2d7dfb0f3f70f11903c99 (diff)
parenta54a47ff7710d12e5a6c88953b3da85cc162c1ea (diff)
downloadbarebox-0e8bd85d9b2f981ad24847badda70c73397d8385.tar.gz
barebox-0e8bd85d9b2f981ad24847badda70c73397d8385.tar.xz
Merge branch 'for-next/bootm'
-rw-r--r--arch/arm/lib32/bootm.c50
-rw-r--r--arch/arm/lib64/armlinux.c12
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/lib/bootm.c59
-rw-r--r--arch/ppc/lib/ppclinux.c52
-rw-r--r--common/Kconfig4
-rw-r--r--common/Makefile1
-rw-r--r--common/bootm.c75
-rw-r--r--common/elf.c145
-rw-r--r--common/filetype.c5
-rw-r--r--include/bootm.h5
-rw-r--r--include/elf.h10
-rw-r--r--include/filetype.h1
13 files changed, 340 insertions, 80 deletions
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index c8bf72f0e0..b1ac2df731 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -130,11 +130,13 @@ static int get_kernel_addresses(size_t image_size,
return 0;
}
-static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap)
+static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
+ int swap, void *fdt)
{
unsigned long kernel;
unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
enum arm_security_state state = bootm_arm_security_state();
+ void *fdt_load_address = NULL;
int ret;
kernel = data->os_res->start + data->os_entry;
@@ -163,16 +165,28 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
free_mem = PAGE_ALIGN(initrd_end + 1);
}
- ret = bootm_load_devicetree(data, free_mem);
- if (ret)
- return ret;
+ if (!fdt) {
+ fdt = bootm_get_devicetree(data);
+ if (IS_ERR(fdt))
+ return PTR_ERR(fdt);
+ }
+
+ if (fdt) {
+ fdt_load_address = (void *)free_mem;
+ ret = bootm_load_devicetree(data, fdt, free_mem);
+
+ free(fdt);
+
+ if (ret)
+ return ret;
+ }
if (bootm_verbose(data)) {
printf("\nStarting kernel at 0x%08lx", kernel);
if (initrd_size)
printf(", initrd at 0x%08lx", initrd_start);
- if (data->oftree)
- printf(", oftree at 0x%p", data->oftree);
+ if (fdt_load_address)
+ printf(", oftree at 0x%p", fdt_load_address);
printf("...\n");
}
@@ -188,8 +202,8 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
if (data->dryrun)
return 0;
- start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree,
- state);
+ start_linux((void *)kernel, swap, initrd_start, initrd_size,
+ fdt_load_address, state);
restart_machine();
@@ -212,7 +226,7 @@ static int do_bootm_linux(struct image_data *data)
if (ret)
return ret;
- return __do_bootm_linux(data, mem_free, 0);
+ return __do_bootm_linux(data, mem_free, 0, NULL);
}
static struct image_handler uimage_handler = {
@@ -237,7 +251,7 @@ struct zimage_header {
#define ZIMAGE_MAGIC 0x016F2818
-static int do_bootz_linux_fdt(int fd, struct image_data *data)
+static int do_bootz_linux_fdt(int fd, struct image_data *data, void **outfdt)
{
struct fdt_header __header, *header;
void *oftree;
@@ -245,9 +259,6 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
u32 end;
- if (data->oftree)
- return -ENXIO;
-
header = &__header;
ret = read(fd, header, sizeof(*header));
if (ret < 0)
@@ -287,8 +298,8 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
pr_err("unable to unflatten devicetree\n");
goto err_free;
}
- data->oftree = of_get_fixed_tree(root);
- if (!data->oftree) {
+ *outfdt = of_get_fixed_tree(root);
+ if (!*outfdt) {
pr_err("Unable to get fixed tree\n");
ret = -EINVAL;
goto err_free;
@@ -296,7 +307,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
free(oftree);
} else {
- data->oftree = oftree;
+ *outfdt = oftree;
}
pr_info("zImage: concatenated oftree detected\n");
@@ -318,6 +329,7 @@ static int do_bootz_linux(struct image_data *data)
size_t image_size;
unsigned long load_address = data->os_address;
unsigned long mem_free;
+ void *fdt = NULL;
fd = open(data->os_file, O_RDONLY);
if (fd < 0) {
@@ -388,13 +400,13 @@ static int do_bootz_linux(struct image_data *data)
*(u32 *)ptr = swab32(*(u32 *)ptr);
}
- ret = do_bootz_linux_fdt(fd, data);
+ ret = do_bootz_linux_fdt(fd, data, &fdt);
if (ret && ret != -ENXIO)
goto err_out;
close(fd);
- return __do_bootm_linux(data, mem_free, swap);
+ return __do_bootm_linux(data, mem_free, swap, fdt);
err_out:
close(fd);
@@ -559,7 +571,7 @@ static int do_bootm_aimage(struct image_data *data)
else
mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M);
- return __do_bootm_linux(data, mem_free, 0);
+ return __do_bootm_linux(data, mem_free, 0, NULL);
err_out:
linux_bootargs_overwrite(NULL);
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 238e8b67a4..afa56792fb 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -38,6 +38,7 @@ static int do_bootm_linux(struct image_data *data)
resource_size_t start, end;
unsigned long text_offset, image_size, devicetree, kernel;
int ret;
+ void *fdt;
text_offset = le64_to_cpup(data->os_header + 8);
image_size = le64_to_cpup(data->os_header + 16);
@@ -54,7 +55,16 @@ static int do_bootm_linux(struct image_data *data)
devicetree = ALIGN(kernel + image_size, PAGE_SIZE);
- ret = bootm_load_devicetree(data, devicetree);
+ fdt = bootm_get_devicetree(data);
+ if (IS_ERR(fdt)) {
+ ret = PTR_ERR(fdt);
+ goto out;
+ }
+
+ ret = bootm_load_devicetree(data, fdt, devicetree);
+
+ free(fdt);
+
if (ret)
goto out;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 359f67883c..9aedf9a77b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -7,6 +7,7 @@ config MIPS
select HAVE_CONFIGURABLE_MEMORY_LAYOUT
select HAVE_CONFIGURABLE_TEXT_BASE
select HAS_DMA
+ select ELF
default y
config SYS_SUPPORTS_BIG_ENDIAN
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 91e7e1c68a..f14540a4c4 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -10,6 +10,7 @@
#include <restart.h>
#include <asm/byteorder.h>
+#include <asm/io.h>
static int do_bootm_barebox(struct image_data *data)
{
@@ -42,11 +43,69 @@ static struct binfmt_hook binfmt_barebox_hook = {
.exec = "bootm",
};
+static int do_bootm_elf(struct image_data *data)
+{
+ void (*entry)(int, void *);
+ struct elf_image *elf;
+ void *fdt, *buf;
+ int ret = 0;
+
+ buf = read_file(data->os_file, NULL);
+ if (!buf)
+ return -EINVAL;
+
+ elf = elf_load_image(buf);
+ if (IS_ERR(elf))
+ return PTR_ERR(elf);
+
+ fdt = bootm_get_devicetree(data);
+ if (IS_ERR(fdt)) {
+ ret = PTR_ERR(fdt);
+ goto bootm_elf_done;
+ }
+
+ pr_info("Starting application at 0x%08lx, dts 0x%08lx...\n",
+ phys_to_virt(elf->entry), data->of_root_node);
+
+ if (data->dryrun)
+ goto bootm_elf_done;
+
+ shutdown_barebox();
+
+ entry = (void *)elf->entry;
+
+ entry(-2, phys_to_virt((unsigned long)fdt));
+
+ pr_err("ELF application terminated\n");
+ ret = -EINVAL;
+
+bootm_elf_done:
+ elf_release_image(elf);
+ free(fdt);
+ free(buf);
+
+ return ret;
+}
+
+static struct image_handler elf_handler = {
+ .name = "ELF",
+ .bootm = do_bootm_elf,
+ .filetype = filetype_elf,
+};
+
+static struct binfmt_hook binfmt_elf_hook = {
+ .type = filetype_elf,
+ .exec = "bootm",
+};
+
static int mips_register_image_handler(void)
{
register_image_handler(&barebox_handler);
binfmt_register(&binfmt_barebox_hook);
+ register_image_handler(&elf_handler);
+ binfmt_register(&binfmt_elf_hook);
+
return 0;
}
late_initcall(mips_register_image_handler);
diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 3fca6b2720..05c29be7da 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -14,35 +14,37 @@
#include <restart.h>
#include <fs.h>
-static int bootm_relocate_fdt(void *addr, struct image_data *data)
+static struct fdt_header *bootm_relocate_fdt(struct image_data *data,
+ struct fdt_header *fdt)
{
- if (addr < LINUX_TLB1_MAX_ADDR) {
+ void *os = (void *)data->os_address;
+ void *newfdt;
+
+ if (os < LINUX_TLB1_MAX_ADDR) {
/* The kernel is within the boot TLB mapping.
* Put the DTB above if there is no space
* below.
*/
- if (addr < (void *)data->oftree->totalsize) {
- addr = (void *)PAGE_ALIGN((phys_addr_t)addr +
+ if (os < (void *)fdt->totalsize) {
+ os = (void *)PAGE_ALIGN((phys_addr_t)os +
data->os->header.ih_size);
- addr += data->oftree->totalsize;
- if (addr < LINUX_TLB1_MAX_ADDR)
- addr = LINUX_TLB1_MAX_ADDR;
+ os += fdt->totalsize;
+ if (os < LINUX_TLB1_MAX_ADDR)
+ os = LINUX_TLB1_MAX_ADDR;
}
}
- if (addr > LINUX_TLB1_MAX_ADDR) {
+ if (os > LINUX_TLB1_MAX_ADDR) {
pr_crit("Unable to relocate DTB to Linux TLB\n");
- return 1;
+ return NULL;
}
- addr = (void *)PAGE_ALIGN_DOWN((phys_addr_t)addr -
- data->oftree->totalsize);
- memcpy(addr, data->oftree, data->oftree->totalsize);
- free(data->oftree);
- data->oftree = addr;
+ newfdt = (void *)PAGE_ALIGN_DOWN((phys_addr_t)os - fdt->totalsize);
+ memcpy(newfdt, fdt, fdt->totalsize);
+ free(fdt);
- pr_info("Relocating device tree to 0x%p\n", addr);
- return 0;
+ pr_info("Relocating device tree to 0x%p\n", newfdt);
+ return newfdt;
}
static int do_bootm_linux(struct image_data *data)
@@ -50,13 +52,14 @@ static int do_bootm_linux(struct image_data *data)
void (*kernel)(void *, void *, unsigned long,
unsigned long, unsigned long);
int ret;
+ struct fdt_header *fdt;
ret = bootm_load_os(data, data->os_address);
if (ret)
return ret;
- data->oftree = of_get_fixed_tree(data->of_root_node);
- if (!data->oftree) {
+ fdt = of_get_fixed_tree(data->of_root_node);
+ if (!fdt) {
pr_err("bootm: No devicetree given.\n");
return -EINVAL;
}
@@ -68,17 +71,14 @@ static int do_bootm_linux(struct image_data *data)
* Linux mapped TLB.
*/
if (IS_ENABLED(CONFIG_MPC85xx)) {
- void *addr = data->oftree;
-
- if ((addr + data->oftree->totalsize) > LINUX_TLB1_MAX_ADDR) {
- addr = (void *)data->os_address;
-
- if (bootm_relocate_fdt(addr, data))
+ if (((void *)fdt + fdt->totalsize) > LINUX_TLB1_MAX_ADDR) {
+ fdt = bootm_relocate_fdt(data, fdt);
+ if (!fdt)
goto error;
}
}
- fdt_add_reserve_map(data->oftree);
+ fdt_add_reserve_map(fdt);
kernel = (void *)(data->os_address + data->os_entry);
@@ -90,7 +90,7 @@ static int do_bootm_linux(struct image_data *data)
* r6: NULL
* r7: NULL
*/
- kernel(data->oftree, kernel, 0, 0, 0);
+ kernel(fdt, kernel, 0, 0, 0);
restart_machine();
diff --git a/common/Kconfig b/common/Kconfig
index 75aea460a3..4909c82322 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -46,6 +46,10 @@ config BLOCK
config BLOCK_WRITE
bool
+config ELF
+ bool
+ depends on MIPS
+
config FILETYPE
bool
diff --git a/common/Makefile b/common/Makefile
index 1ff7d2370b..b6284c2552 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -8,6 +8,7 @@ obj-y += misc.o
obj-pbl-y += memsize.o
obj-y += resource.o
obj-y += bootsource.o
+obj-$(CONFIG_ELF) += elf.o
obj-y += restart.o
obj-y += poweroff.o
obj-$(CONFIG_AUTO_COMPLETE) += complete.o
diff --git a/common/bootm.c b/common/bootm.c
index 5ff6683fe7..169000cccb 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -320,28 +320,24 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
}
/*
- * bootm_load_devicetree() - load devicetree
+ * bootm_get_devicetree() - get devicetree
*
* @data: image data context
- * @load_address: The address where the devicetree should be loaded to
*
- * This loads the devicetree to a RAM location. load_address must be a valid
- * address. The resulting devicetree will be found at data->oftree.
+ * This gets the fixed devicetree from the various image sources or the internal
+ * devicetree. It returns a pointer to the allocated devicetree which must be
+ * freed after use.
*
- * Return: 0 on success, negative error code otherwise
+ * Return: pointer to the fixed devicetree or a ERR_PTR() on failure.
*/
-int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
+void *bootm_get_devicetree(struct image_data *data)
{
enum filetype type;
- int fdt_size;
struct fdt_header *oftree;
int ret;
- if (data->oftree)
- return 0;
-
if (!IS_ENABLED(CONFIG_OFTREE))
- return 0;
+ return ERR_PTR(-ENOSYS);
if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
fit_has_image(data->os_fit, data->fit_config, "fdt")) {
@@ -351,7 +347,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
&of_tree, &of_size);
if (ret)
- return ret;
+ return ERR_PTR(ret);
data->of_root_node = of_unflatten_dtb(of_tree);
} else if (data->oftree_file) {
@@ -362,7 +358,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
if ((int)type < 0) {
printf("could not open %s: %s\n", data->oftree_file,
strerror(-type));
- return (int)type;
+ return ERR_PTR((int)type);
}
switch (type) {
@@ -375,11 +371,11 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
FILESIZE_MAX);
break;
default:
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
if (ret)
- return ret;
+ return ERR_PTR(ret);
data->of_root_node = of_unflatten_dtb(oftree);
@@ -388,13 +384,13 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
if (IS_ERR(data->of_root_node)) {
data->of_root_node = NULL;
pr_err("unable to unflatten devicetree\n");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
} else {
data->of_root_node = of_get_root_node();
if (!data->of_root_node)
- return 0;
+ return NULL;
if (bootm_verbose(data) > 1 && data->of_root_node)
printf("using internal devicetree\n");
@@ -408,31 +404,47 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
oftree = of_get_fixed_tree(data->of_root_node);
if (!oftree)
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
- fdt_size = be32_to_cpu(oftree->totalsize);
+ fdt_add_reserve_map(oftree);
- data->oftree_res = request_sdram_region("oftree", load_address,
- fdt_size);
- if (!data->oftree_res) {
- free(oftree);
- return -ENOMEM;
- }
+ return oftree;
+}
- memcpy((void *)data->oftree_res->start, oftree, fdt_size);
+/*
+ * bootm_load_devicetree() - load devicetree
+ *
+ * @data: image data context
+ * @fdt: The flat device tree to load
+ * @load_address: The address where the devicetree should be loaded to
+ *
+ * This loads the devicetree to a RAM location. load_address must be a valid
+ * address which is requested with request_sdram_region. The associated region
+ * is released automatically in the bootm error path.
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+int bootm_load_devicetree(struct image_data *data, void *fdt,
+ unsigned long load_address)
+{
+ int fdt_size;
- free(oftree);
+ if (!IS_ENABLED(CONFIG_OFTREE))
+ return -ENOSYS;
- oftree = (void *)data->oftree_res->start;
+ fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
- fdt_add_reserve_map(oftree);
+ data->oftree_res = request_sdram_region("oftree", load_address,
+ fdt_size);
+ if (!data->oftree_res)
+ return -ENOMEM;
+
+ memcpy((void *)data->oftree_res->start, fdt, fdt_size);
of_print_cmdline(data->of_root_node);
if (bootm_verbose(data) > 1)
of_print_nodes(data->of_root_node, 0);
- data->oftree = oftree;
-
return 0;
}
@@ -576,7 +588,6 @@ int bootm_boot(struct bootm_data *bootm_data)
* When we only allow booting signed images make sure everything
* we boot is in the OS image and not given separately.
*/
- data->oftree = NULL;
data->oftree_file = NULL;
data->initrd_file = NULL;
if (os_type != filetype_oftree) {
diff --git a/common/elf.c b/common/elf.c
new file mode 100644
index 0000000000..8edf388564
--- /dev/null
+++ b/common/elf.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
+ */
+
+#include <common.h>
+#include <elf.h>
+#include <memory.h>
+
+struct elf_section {
+ struct list_head list;
+ struct resource *r;
+};
+
+static int elf_request_region(struct elf_image *elf, resource_size_t start,
+ resource_size_t size)
+{
+ struct list_head *list = &elf->list;
+ struct resource *r_new;
+ struct elf_section *r;
+
+ r = xzalloc(sizeof(*r));
+ r_new = request_sdram_region("elf_section", start, size);
+ if (!r_new) {
+ pr_err("Failed to request region: %pa %pa\n", &start, &size);
+ return -EINVAL;
+ }
+
+ r->r = r_new;
+ list_add_tail(&r->list, list);
+
+ return 0;
+}
+
+static void elf_release_regions(struct elf_image *elf)
+{
+ struct list_head *list = &elf->list;
+ struct elf_section *r, *r_tmp;
+
+ list_for_each_entry_safe(r, r_tmp, list, list) {
+ release_sdram_region(r->r);
+ free(r);
+ }
+}
+
+
+static int load_elf_phdr_segment(struct elf_image *elf, void *src,
+ Elf32_Phdr *phdr)
+{
+ void *dst = (void *)phdr->p_paddr;
+ int ret;
+
+ /* we care only about PT_LOAD segments */
+ if (phdr->p_type != PT_LOAD)
+ return 0;
+
+ if (!phdr->p_filesz)
+ return 0;
+
+ pr_debug("Loading phdr to 0x%p (%i bytes)\n", dst, phdr->p_filesz);
+
+ ret = elf_request_region(elf, (resource_size_t)dst, phdr->p_filesz);
+ if (ret)
+ return ret;
+
+ memcpy(dst, src, phdr->p_filesz);
+
+ if (phdr->p_filesz < phdr->p_memsz)
+ memset(dst + phdr->p_filesz, 0x00,
+ phdr->p_memsz - phdr->p_filesz);
+
+ return 0;
+}
+
+static int load_elf_image_phdr(struct elf_image *elf)
+{
+ void *buf = elf->buf;
+ Elf32_Ehdr *ehdr = buf;
+ Elf32_Phdr *phdr = (Elf32_Phdr *)(buf + ehdr->e_phoff);
+ int i, ret;
+
+ elf->entry = ehdr->e_entry;
+
+ for (i = 0; i < ehdr->e_phnum; ++i) {
+ void *src = buf + phdr->p_offset;
+
+ ret = load_elf_phdr_segment(elf, src, phdr);
+ /* in case of error elf_load_image() caller should clean up and
+ * call elf_release_image() */
+ if (ret)
+ return ret;
+
+ ++phdr;
+ }
+
+ return 0;
+}
+
+static int elf_check_image(void *buf)
+{
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)buf;
+
+ if (strncmp(buf, ELFMAG, SELFMAG)) {
+ pr_err("ELF magic not found.\n");
+ return -EINVAL;
+ }
+
+ if (ehdr->e_type != ET_EXEC) {
+ pr_err("Non EXEC ELF image.\n");
+ return -ENOEXEC;
+ }
+
+ return 0;
+}
+
+struct elf_image *elf_load_image(void *buf)
+{
+ struct elf_image *elf;
+ int ret;
+
+ elf = xzalloc(sizeof(*elf));
+
+ INIT_LIST_HEAD(&elf->list);
+
+ elf->buf = buf;
+
+ ret = elf_check_image(buf);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = load_elf_image_phdr(elf);
+ if (ret) {
+ elf_release_image(elf);
+ return ERR_PTR(ret);
+ }
+
+ return elf;
+}
+
+void elf_release_image(struct elf_image *elf)
+{
+ elf_release_regions(elf);
+
+ free(elf);
+}
diff --git a/common/filetype.c b/common/filetype.c
index bb807df721..c5f2384a6c 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -27,6 +27,7 @@
#include <envfs.h>
#include <disks.h>
#include <image-sparse.h>
+#include <elf.h>
struct filetype_str {
const char *name; /* human readable filetype */
@@ -69,6 +70,7 @@ static const struct filetype_str filetype_str[] = {
[filetype_kwbimage_v1] = { "MVEBU kwbimage (v1)", "kwb1" },
[filetype_android_sparse] = { "Android sparse image", "sparse" },
[filetype_arm64_linux_image] = { "ARM aarch64 Linux image", "aarch64-linux" },
+ [filetype_elf] = { "ELF", "elf" },
};
const char *file_type_to_string(enum filetype f)
@@ -356,6 +358,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize)
buf[7] == 0x47530000)
return filetype_ch_image_be;
+ if (strncmp(buf8, ELFMAG, 4) == 0)
+ return filetype_elf;
+
return filetype_unknown;
}
diff --git a/include/bootm.h b/include/bootm.h
index 62951d6058..fdc73f711a 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -78,7 +78,6 @@ struct image_data {
void *fit_config;
struct device_node *of_root_node;
- struct fdt_header *oftree;
struct resource *oftree_res;
/*
@@ -126,7 +125,9 @@ int bootm_load_os(struct image_data *data, unsigned long load_address);
bool bootm_has_initrd(struct image_data *data);
int bootm_load_initrd(struct image_data *data, unsigned long load_address);
-int bootm_load_devicetree(struct image_data *data, unsigned long load_address);
+void *bootm_get_devicetree(struct image_data *data);
+int bootm_load_devicetree(struct image_data *data, void *fdt,
+ unsigned long load_address);
int bootm_get_os_size(struct image_data *data);
enum bootm_verify bootm_get_verify_mode(void);
diff --git a/include/elf.h b/include/elf.h
index ebcec7db0d..92c8d9c127 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -2,6 +2,7 @@
#define _LINUX_ELF_H
#include <linux/types.h>
+#include <linux/list.h>
//#include <linux/auxvec.h>
//#include <linux/elf-em.h>
#include <asm/elf.h>
@@ -397,4 +398,13 @@ static inline void arch_write_notes(struct file *file) { }
#define ELF_CORE_WRITE_EXTRA_NOTES arch_write_notes(file)
#endif /* ARCH_HAVE_EXTRA_ELF_NOTES */
+struct elf_image {
+ struct list_head list;
+ unsigned long entry;
+ void *buf;
+};
+
+struct elf_image *elf_load_image(void *buf);
+void elf_release_image(struct elf_image *elf);
+
#endif /* _LINUX_ELF_H */
diff --git a/include/filetype.h b/include/filetype.h
index d9963a2449..237ed3fbe9 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -42,6 +42,7 @@ enum filetype {
filetype_kwbimage_v1,
filetype_android_sparse,
filetype_arm64_linux_image,
+ filetype_elf,
filetype_max,
};