Browse Source

fix bootelf 64bits

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 7 months ago
parent
commit
4069f02058
  1. 89
      cmd/elf.c
  2. 3
      configs/sytc_defconfig
  3. 43
      include/elf.h

89
cmd/elf.c

@ -23,6 +23,41 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#endif #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((unsigned long)dst, phdr->p_filesz);
++phdr;
}
return ehdr->e_entry;
}
/* /*
* A very simple elf loader, assumes the image is valid, returns the * A very simple elf loader, assumes the image is valid, returns the
* entry point address. * entry point address.
@ -34,6 +69,9 @@ static unsigned long load_elf_image_phdr(unsigned long addr)
int i; int i;
ehdr = (Elf32_Ehdr *)addr; ehdr = (Elf32_Ehdr *)addr;
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return load_elf64_image_phdr(addr);
phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
/* Load each program header */ /* Load each program header */
@ -54,6 +92,55 @@ static unsigned long load_elf_image_phdr(unsigned long addr)
return ehdr->e_entry; 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 + ehdr->e_shoff +
(ehdr->e_shstrndx * sizeof(Elf64_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 = (Elf64_Shdr *)(addr + 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 + shdr->sh_offset;
memcpy((void *)(uintptr_t)shdr->sh_addr,
(const void *)image, shdr->sh_size);
}
flush_cache(shdr->sh_addr, shdr->sh_size);
}
return ehdr->e_entry;
}
static unsigned long load_elf_image_shdr(unsigned long addr) static unsigned long load_elf_image_shdr(unsigned long addr)
{ {
Elf32_Ehdr *ehdr; /* Elf header structure pointer */ Elf32_Ehdr *ehdr; /* Elf header structure pointer */
@ -63,6 +150,8 @@ static unsigned long load_elf_image_shdr(unsigned long addr)
int i; /* Loop counter */ int i; /* Loop counter */
ehdr = (Elf32_Ehdr *)addr; 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 */ /* Find the section header string table for output info */
shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +

3
configs/sytc_defconfig

@ -48,8 +48,9 @@ CONFIG_FASTBOOT_BUF_SIZE=0x07000000
CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_BOOTZ=y CONFIG_CMD_BOOTZ=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_DTIMG=y CONFIG_CMD_DTIMG=y
# CONFIG_CMD_ELF is not set CONFIG_CMD_ELF=y
# CONFIG_CMD_IMI is not set # CONFIG_CMD_IMI is not set
# CONFIG_CMD_IMLS is not set # CONFIG_CMD_IMLS is not set
# CONFIG_CMD_XIMG is not set # CONFIG_CMD_XIMG is not set

43
include/elf.h

@ -114,6 +114,24 @@ typedef struct elfhdr{
header string table" entry offset */ header string table" entry offset */
} Elf32_Ehdr; } Elf32_Ehdr;
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf64_Half e_type; /* object file type */
Elf64_Half e_machine; /* machine */
Elf64_Word e_version; /* object file version */
Elf64_Addr e_entry; /* virtual entry point */
Elf64_Off e_phoff; /* program header table offset */
Elf64_Off e_shoff; /* section header table offset */
Elf64_Word e_flags; /* processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size */
Elf64_Half e_phentsize; /* program header entry size */
Elf64_Half e_phnum; /* number of program header entries */
Elf64_Half e_shentsize; /* section header entry size */
Elf64_Half e_shnum; /* number of section header entries */
Elf64_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf64_Ehdr;
/* e_type */ /* e_type */
#define ET_NONE 0 /* No file type */ #define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */ #define ET_REL 1 /* relocatable file */
@ -231,6 +249,20 @@ typedef struct {
Elf32_Word sh_entsize; /* section entry size */ Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr; } Elf32_Shdr;
typedef struct {
Elf64_Word sh_name; /* name - index into section header
string table section */
Elf64_Word sh_type; /* type */
Elf64_Xword sh_flags; /* flags */
Elf64_Addr sh_addr; /* address */
Elf64_Off sh_offset; /* file offset */
Elf64_Xword sh_size; /* section size */
Elf64_Word sh_link; /* section header table index link */
Elf64_Word sh_info; /* extra information */
Elf64_Xword sh_addralign; /* address alignment */
Elf64_Xword sh_entsize; /* section entry size */
} Elf64_Shdr;
/* Special Section Indexes */ /* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */ #define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ #define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
@ -418,6 +450,17 @@ typedef struct {
Elf32_Word p_align; /* memory alignment */ Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr; } Elf32_Phdr;
typedef struct {
Elf64_Word p_type; /* segment type */
Elf64_Word p_flags; /* flags */
Elf64_Off p_offset; /* segment offset */
Elf64_Addr p_vaddr; /* virtual address of segment */
Elf64_Addr p_paddr; /* physical address of segment */
Elf64_Xword p_filesz; /* number of bytes in file for seg */
Elf64_Xword p_memsz; /* number of bytes in mem. for seg */
Elf64_Xword p_align; /* memory alignment */
} Elf64_Phdr;
/* Segment types - p_type */ /* Segment types - p_type */
#define PT_NULL 0 /* unused */ #define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */ #define PT_LOAD 1 /* loadable segment */

Loading…
Cancel
Save