[PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Fri Jan 17 08:49:03 CET 2020
On Fri, Jan 17, 2020 at 5:27 AM Lokesh Vutla <lokeshvutla at ti.com> wrote:
>
> Simon,
>
> On 13/01/20 11:24 AM, Keerthy wrote:
> > Move the generic elf loading/validating functions to lib/
> > so that they can be re-used and accessed by code existing
> > outside cmd.
> >
> > Signed-off-by: Keerthy <j-keerthy at ti.com>
> > Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
>
> Are you okay with this patch? If yes, Ill apply to u-boot-ti along with other
> patches in this series.
Yes.
Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
Regards,
Simon
>
> Thanks and regards,
> Lokesh
>
> > ---
> > Changes in v2:
> >
> > * Factored out all the generic elf handling functions under lib/elf.c
> >
> > cmd/Kconfig | 1 +
> > cmd/elf.c | 229 --------------------------------------------
> > include/elf.h | 4 +
> > lib/Kconfig | 3 +
> > lib/Makefile | 1 +
> > lib/elf.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > 6 files changed, 265 insertions(+), 229 deletions(-)
> > create mode 100644 lib/elf.c
> >
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 298feae24d..6f4f08d02a 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -375,6 +375,7 @@ config CMD_ADTIMG
> > config CMD_ELF
> > bool "bootelf, bootvx"
> > default y
> > + select ELF
> > help
> > Boot an ELF/vxWorks image from the memory.
> >
> > diff --git a/cmd/elf.c b/cmd/elf.c
> > index 32f12a72b9..23cc17aebc 100644
> > --- a/cmd/elf.c
> > +++ b/cmd/elf.c
> > @@ -26,211 +26,6 @@
> > #include <linux/linkage.h>
> > #endif
> >
> > -/*
> > - * A very simple ELF64 loader, assumes the image is valid, returns the
> > - * entry point address.
> > - *
> > - * Note if U-Boot is 32-bit, the loader assumes the to segment's
> > - * physical address and size is within the lower 32-bit address space.
> > - */
> > -static unsigned long load_elf64_image_phdr(unsigned long addr)
> > -{
> > - Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > - Elf64_Phdr *phdr; /* Program header structure pointer */
> > - int i;
> > -
> > - ehdr = (Elf64_Ehdr *)addr;
> > - phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> > -
> > - /* Load each program header */
> > - for (i = 0; i < ehdr->e_phnum; ++i) {
> > - void *dst = (void *)(ulong)phdr->p_paddr;
> > - void *src = (void *)addr + phdr->p_offset;
> > -
> > - debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> > - i, dst, (ulong)phdr->p_filesz);
> > - if (phdr->p_filesz)
> > - 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);
> > - flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > - roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > - ++phdr;
> > - }
> > -
> > - if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > - EF_PPC64_ELFV1_ABI)) {
> > - /*
> > - * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > - * descriptor pointer with the first double word being the
> > - * address of the entry point of the function.
> > - */
> > - uintptr_t addr = ehdr->e_entry;
> > -
> > - return *(Elf64_Addr *)addr;
> > - }
> > -
> > - return ehdr->e_entry;
> > -}
> > -
> > -static unsigned long load_elf64_image_shdr(unsigned long addr)
> > -{
> > - Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > - Elf64_Shdr *shdr; /* Section header structure pointer */
> > - unsigned char *strtab = 0; /* String table pointer */
> > - unsigned char *image; /* Binary image pointer */
> > - int i; /* Loop counter */
> > -
> > - ehdr = (Elf64_Ehdr *)addr;
> > -
> > - /* Find the section header string table for output info */
> > - shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > - (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> > -
> > - if (shdr->sh_type == SHT_STRTAB)
> > - strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> > -
> > - /* Load each appropriate section */
> > - for (i = 0; i < ehdr->e_shnum; ++i) {
> > - shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > - (i * sizeof(Elf64_Shdr)));
> > -
> > - if (!(shdr->sh_flags & SHF_ALLOC) ||
> > - shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > - continue;
> > - }
> > -
> > - if (strtab) {
> > - debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > - (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > - &strtab[shdr->sh_name],
> > - (unsigned long)shdr->sh_addr,
> > - (long)shdr->sh_size);
> > - }
> > -
> > - if (shdr->sh_type == SHT_NOBITS) {
> > - memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > - shdr->sh_size);
> > - } else {
> > - image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> > - memcpy((void *)(uintptr_t)shdr->sh_addr,
> > - (const void *)image, shdr->sh_size);
> > - }
> > - flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > - roundup((shdr->sh_addr + shdr->sh_size),
> > - ARCH_DMA_MINALIGN) -
> > - rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > - }
> > -
> > - if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > - EF_PPC64_ELFV1_ABI)) {
> > - /*
> > - * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > - * descriptor pointer with the first double word being the
> > - * address of the entry point of the function.
> > - */
> > - uintptr_t addr = ehdr->e_entry;
> > -
> > - return *(Elf64_Addr *)addr;
> > - }
> > -
> > - return ehdr->e_entry;
> > -}
> > -
> > -/*
> > - * A very simple ELF loader, assumes the image is valid, returns the
> > - * entry point address.
> > - *
> > - * The loader firstly reads the EFI class to see if it's a 64-bit image.
> > - * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> > - */
> > -static unsigned long load_elf_image_phdr(unsigned long addr)
> > -{
> > - Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > - Elf32_Phdr *phdr; /* Program header structure pointer */
> > - int i;
> > -
> > - ehdr = (Elf32_Ehdr *)addr;
> > - if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > - return load_elf64_image_phdr(addr);
> > -
> > - phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> > -
> > - /* Load each program header */
> > - for (i = 0; i < ehdr->e_phnum; ++i) {
> > - void *dst = (void *)(uintptr_t)phdr->p_paddr;
> > - void *src = (void *)addr + phdr->p_offset;
> > -
> > - debug("Loading phdr %i to 0x%p (%i bytes)\n",
> > - i, dst, phdr->p_filesz);
> > - if (phdr->p_filesz)
> > - 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);
> > - flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > - roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > - ++phdr;
> > - }
> > -
> > - return ehdr->e_entry;
> > -}
> > -
> > -static unsigned long load_elf_image_shdr(unsigned long addr)
> > -{
> > - Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > - Elf32_Shdr *shdr; /* Section header structure pointer */
> > - unsigned char *strtab = 0; /* String table pointer */
> > - unsigned char *image; /* Binary image pointer */
> > - int i; /* Loop counter */
> > -
> > - ehdr = (Elf32_Ehdr *)addr;
> > - if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > - return load_elf64_image_shdr(addr);
> > -
> > - /* Find the section header string table for output info */
> > - shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > - (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> > -
> > - if (shdr->sh_type == SHT_STRTAB)
> > - strtab = (unsigned char *)(addr + shdr->sh_offset);
> > -
> > - /* Load each appropriate section */
> > - for (i = 0; i < ehdr->e_shnum; ++i) {
> > - shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > - (i * sizeof(Elf32_Shdr)));
> > -
> > - if (!(shdr->sh_flags & SHF_ALLOC) ||
> > - shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > - continue;
> > - }
> > -
> > - if (strtab) {
> > - debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > - (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > - &strtab[shdr->sh_name],
> > - (unsigned long)shdr->sh_addr,
> > - (long)shdr->sh_size);
> > - }
> > -
> > - if (shdr->sh_type == SHT_NOBITS) {
> > - memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > - shdr->sh_size);
> > - } else {
> > - image = (unsigned char *)addr + shdr->sh_offset;
> > - memcpy((void *)(uintptr_t)shdr->sh_addr,
> > - (const void *)image, shdr->sh_size);
> > - }
> > - flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > - roundup((shdr->sh_addr + shdr->sh_size),
> > - ARCH_DMA_MINALIGN) -
> > - rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > - }
> > -
> > - return ehdr->e_entry;
> > -}
> > -
> > /* Allow ports to override the default behavior */
> > static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> > int argc, char * const argv[])
> > @@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> > return ret;
> > }
> >
> > -/*
> > - * Determine if a valid ELF image exists at the given memory location.
> > - * First look at the ELF header magic field, then make sure that it is
> > - * executable.
> > - */
> > -int valid_elf_image(unsigned long addr)
> > -{
> > - Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -
> > - ehdr = (Elf32_Ehdr *)addr;
> > -
> > - if (!IS_ELF(*ehdr)) {
> > - printf("## No elf image at address 0x%08lx\n", addr);
> > - return 0;
> > - }
> > -
> > - if (ehdr->e_type != ET_EXEC) {
> > - printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > - return 0;
> > - }
> > -
> > - return 1;
> > -}
> > -
> > /* Interpreter command to boot an arbitrary ELF image from memory */
> > int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> > {
> > diff --git a/include/elf.h b/include/elf.h
> > index 81f40191d7..e7c51986df 100644
> > --- a/include/elf.h
> > +++ b/include/elf.h
> > @@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
> >
> > #ifndef __ASSEMBLER__
> > int valid_elf_image(unsigned long addr);
> > +unsigned long load_elf64_image_phdr(unsigned long addr);
> > +unsigned long load_elf64_image_shdr(unsigned long addr);
> > +unsigned long load_elf_image_phdr(unsigned long addr);
> > +unsigned long load_elf_image_shdr(unsigned long addr);
> > #endif
> >
> > #endif /* _ELF_H */
> > diff --git a/lib/Kconfig b/lib/Kconfig
> > index d040a87d26..b155ced4b2 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -601,4 +601,7 @@ config TEST_FDTDEC
> > config LIB_DATE
> > bool
> >
> > +config ELF
> > + bool "enable basic elf loading/validating functions"
> > +
> > endmenu
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 6b7b9ce85c..93f22d210e 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
> > endif
> >
> > obj-y += date.o
> > +obj-$(CONFIG_ELF) += elf.o
> >
> > #
> > # Build a fast OID lookup registry from include/linux/oid_registry.h
> > diff --git a/lib/elf.c b/lib/elf.c
> > new file mode 100644
> > index 0000000000..54ac4ee502
> > --- /dev/null
> > +++ b/lib/elf.c
> > @@ -0,0 +1,256 @@
> > +/*
> > + * Copyright (c) 2001 William L. Pitts
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms are freely
> > + * permitted provided that the above copyright notice and this
> > + * paragraph and the following disclaimer are duplicated in all
> > + * such forms.
> > + *
> > + * This software is provided "AS IS" and without any express or
> > + * implied warranties, including, without limitation, the implied
> > + * warranties of merchantability and fitness for a particular
> > + * purpose.
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <cpu_func.h>
> > +#include <elf.h>
> > +#include <env.h>
> > +#include <net.h>
> > +#include <vxworks.h>
> > +#ifdef CONFIG_X86
> > +#include <vbe.h>
> > +#include <asm/e820.h>
> > +#include <linux/linkage.h>
> > +#endif
> > +
> > +/*
> > + * A very simple ELF64 loader, assumes the image is valid, returns the
> > + * entry point address.
> > + *
> > + * Note if U-Boot is 32-bit, the loader assumes the to segment's
> > + * physical address and size is within the lower 32-bit address space.
> > + */
> > +unsigned long load_elf64_image_phdr(unsigned long addr)
> > +{
> > + Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > + Elf64_Phdr *phdr; /* Program header structure pointer */
> > + int i;
> > +
> > + ehdr = (Elf64_Ehdr *)addr;
> > + phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> > +
> > + /* Load each program header */
> > + for (i = 0; i < ehdr->e_phnum; ++i) {
> > + void *dst = (void *)(ulong)phdr->p_paddr;
> > + void *src = (void *)addr + phdr->p_offset;
> > +
> > + debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> > + i, dst, (ulong)phdr->p_filesz);
> > + if (phdr->p_filesz)
> > + 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);
> > + flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > + roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > + ++phdr;
> > + }
> > +
> > + if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > + EF_PPC64_ELFV1_ABI)) {
> > + /*
> > + * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > + * descriptor pointer with the first double word being the
> > + * address of the entry point of the function.
> > + */
> > + uintptr_t addr = ehdr->e_entry;
> > +
> > + return *(Elf64_Addr *)addr;
> > + }
> > +
> > + return ehdr->e_entry;
> > +}
> > +
> > +unsigned long load_elf64_image_shdr(unsigned long addr)
> > +{
> > + Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > + Elf64_Shdr *shdr; /* Section header structure pointer */
> > + unsigned char *strtab = 0; /* String table pointer */
> > + unsigned char *image; /* Binary image pointer */
> > + int i; /* Loop counter */
> > +
> > + ehdr = (Elf64_Ehdr *)addr;
> > +
> > + /* Find the section header string table for output info */
> > + shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > + (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> > +
> > + if (shdr->sh_type == SHT_STRTAB)
> > + strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> > +
> > + /* Load each appropriate section */
> > + for (i = 0; i < ehdr->e_shnum; ++i) {
> > + shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > + (i * sizeof(Elf64_Shdr)));
> > +
> > + if (!(shdr->sh_flags & SHF_ALLOC) ||
> > + shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > + continue;
> > + }
> > +
> > + if (strtab) {
> > + debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > + &strtab[shdr->sh_name],
> > + (unsigned long)shdr->sh_addr,
> > + (long)shdr->sh_size);
> > + }
> > +
> > + if (shdr->sh_type == SHT_NOBITS) {
> > + memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > + shdr->sh_size);
> > + } else {
> > + image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> > + memcpy((void *)(uintptr_t)shdr->sh_addr,
> > + (const void *)image, shdr->sh_size);
> > + }
> > + flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > + roundup((shdr->sh_addr + shdr->sh_size),
> > + ARCH_DMA_MINALIGN) -
> > + rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > + }
> > +
> > + if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > + EF_PPC64_ELFV1_ABI)) {
> > + /*
> > + * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > + * descriptor pointer with the first double word being the
> > + * address of the entry point of the function.
> > + */
> > + uintptr_t addr = ehdr->e_entry;
> > +
> > + return *(Elf64_Addr *)addr;
> > + }
> > +
> > + return ehdr->e_entry;
> > +}
> > +
> > +/*
> > + * A very simple ELF loader, assumes the image is valid, returns the
> > + * entry point address.
> > + *
> > + * The loader firstly reads the EFI class to see if it's a 64-bit image.
> > + * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> > + */
> > +unsigned long load_elf_image_phdr(unsigned long addr)
> > +{
> > + Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > + Elf32_Phdr *phdr; /* Program header structure pointer */
> > + int i;
> > +
> > + ehdr = (Elf32_Ehdr *)addr;
> > + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > + return load_elf64_image_phdr(addr);
> > +
> > + phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> > +
> > + /* Load each program header */
> > + for (i = 0; i < ehdr->e_phnum; ++i) {
> > + void *dst = (void *)(uintptr_t)phdr->p_paddr;
> > + void *src = (void *)addr + phdr->p_offset;
> > +
> > + debug("Loading phdr %i to 0x%p (%i bytes)\n",
> > + i, dst, phdr->p_filesz);
> > + if (phdr->p_filesz)
> > + 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);
> > + flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > + roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > + ++phdr;
> > + }
> > +
> > + return ehdr->e_entry;
> > +}
> > +
> > +unsigned long load_elf_image_shdr(unsigned long addr)
> > +{
> > + Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > + Elf32_Shdr *shdr; /* Section header structure pointer */
> > + unsigned char *strtab = 0; /* String table pointer */
> > + unsigned char *image; /* Binary image pointer */
> > + int i; /* Loop counter */
> > +
> > + ehdr = (Elf32_Ehdr *)addr;
> > + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > + return load_elf64_image_shdr(addr);
> > +
> > + /* Find the section header string table for output info */
> > + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > + (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> > +
> > + if (shdr->sh_type == SHT_STRTAB)
> > + strtab = (unsigned char *)(addr + shdr->sh_offset);
> > +
> > + /* Load each appropriate section */
> > + for (i = 0; i < ehdr->e_shnum; ++i) {
> > + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > + (i * sizeof(Elf32_Shdr)));
> > +
> > + if (!(shdr->sh_flags & SHF_ALLOC) ||
> > + shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > + continue;
> > + }
> > +
> > + if (strtab) {
> > + debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > + &strtab[shdr->sh_name],
> > + (unsigned long)shdr->sh_addr,
> > + (long)shdr->sh_size);
> > + }
> > +
> > + if (shdr->sh_type == SHT_NOBITS) {
> > + memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > + shdr->sh_size);
> > + } else {
> > + image = (unsigned char *)addr + shdr->sh_offset;
> > + memcpy((void *)(uintptr_t)shdr->sh_addr,
> > + (const void *)image, shdr->sh_size);
> > + }
> > + flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > + roundup((shdr->sh_addr + shdr->sh_size),
> > + ARCH_DMA_MINALIGN) -
> > + rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > + }
> > +
> > + return ehdr->e_entry;
> > +}
> > +
> > +/*
> > + * Determine if a valid ELF image exists at the given memory location.
> > + * First look at the ELF header magic field, then make sure that it is
> > + * executable.
> > + */
> > +int valid_elf_image(unsigned long addr)
> > +{
> > + Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +
> > + ehdr = (Elf32_Ehdr *)addr;
> > +
> > + if (!IS_ELF(*ehdr)) {
> > + printf("## No elf image at address 0x%08lx\n", addr);
> > + return 0;
> > + }
> > +
> > + if (ehdr->e_type != ET_EXEC) {
> > + printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > + return 0;
> > + }
> > +
> > + return 1;
> > +}
> >
More information about the U-Boot
mailing list