cmd: Clean up cmd_elf a little bit
This commit cleans up cmd_elf.c per U-Boot coding convention, and removes the unnecessary DECLARE_GLOBAL_DATA_PTR and out-of-date powerpc comments (it actually supports not only powerpc targets). Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
a726075911
commit
ebca3df781
115
common/cmd_elf.c
115
common/cmd_elf.c
|
@ -14,17 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <bootm.h>
|
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <linux/ctype.h>
|
|
||||||
#include <net.h>
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
#include <net.h>
|
||||||
#include <vxworks.h>
|
#include <vxworks.h>
|
||||||
|
|
||||||
#if defined(CONFIG_WALNUT) || defined(CONFIG_SYS_VXWORKS_MAC_PTR)
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned long load_elf_image_phdr(unsigned long addr);
|
static unsigned long load_elf_image_phdr(unsigned long addr);
|
||||||
static unsigned long load_elf_image_shdr(unsigned long addr);
|
static unsigned long load_elf_image_shdr(unsigned long addr);
|
||||||
|
|
||||||
|
@ -54,18 +48,16 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/*
|
||||||
* Determine if a valid ELF image exists at the given memory location.
|
* Determine if a valid ELF image exists at the given memory location.
|
||||||
* First looks at the ELF header magic field, the makes sure that it is
|
* First look at the ELF header magic field, then make sure that it is
|
||||||
* executable and makes sure that it is for a PowerPC.
|
* executable.
|
||||||
* ====================================================================== */
|
*/
|
||||||
int valid_elf_image(unsigned long addr)
|
int valid_elf_image(unsigned long addr)
|
||||||
{
|
{
|
||||||
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
|
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
ehdr = (Elf32_Ehdr *)addr;
|
||||||
|
|
||||||
ehdr = (Elf32_Ehdr *) addr;
|
|
||||||
|
|
||||||
if (!IS_ELF(*ehdr)) {
|
if (!IS_ELF(*ehdr)) {
|
||||||
printf("## No elf image at address 0x%08lx\n", addr);
|
printf("## No elf image at address 0x%08lx\n", addr);
|
||||||
|
@ -77,19 +69,10 @@ int valid_elf_image(unsigned long addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (ehdr->e_machine != EM_PPC) {
|
|
||||||
printf("## Not a PowerPC elf image at address 0x%08lx\n", addr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/* Interpreter command to boot an arbitrary ELF image from memory */
|
||||||
* Interpreter command to boot an arbitrary ELF image from memory.
|
|
||||||
* ====================================================================== */
|
|
||||||
int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
unsigned long addr; /* Address of the ELF image */
|
unsigned long addr; /* Address of the ELF image */
|
||||||
|
@ -97,7 +80,6 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
char *sload, *saddr;
|
char *sload, *saddr;
|
||||||
const char *ep = getenv("autostart");
|
const char *ep = getenv("autostart");
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
|
||||||
int rcode = 0;
|
int rcode = 0;
|
||||||
|
|
||||||
sload = saddr = NULL;
|
sload = saddr = NULL;
|
||||||
|
@ -138,14 +120,15 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
rcode = 1;
|
rcode = 1;
|
||||||
|
|
||||||
printf("## Application terminated, rc = 0x%lx\n", rc);
|
printf("## Application terminated, rc = 0x%lx\n", rc);
|
||||||
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/*
|
||||||
* Interpreter command to boot VxWorks from a memory image. The image can
|
* Interpreter command to boot VxWorks from a memory image. The image can
|
||||||
* be either an ELF image or a raw binary. Will attempt to setup the
|
* be either an ELF image or a raw binary. Will attempt to setup the
|
||||||
* bootline and other parameters correctly.
|
* bootline and other parameters correctly.
|
||||||
* ====================================================================== */
|
*/
|
||||||
int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
unsigned long addr; /* Address of image */
|
unsigned long addr; /* Address of image */
|
||||||
|
@ -154,12 +137,10 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
char *tmp; /* Temporary char pointer */
|
char *tmp; /* Temporary char pointer */
|
||||||
char build_buf[128]; /* Buffer for building the bootline */
|
char build_buf[128]; /* Buffer for building the bootline */
|
||||||
|
|
||||||
/* ---------------------------------------------------
|
/*
|
||||||
*
|
|
||||||
* Check the loadaddr variable.
|
* Check the loadaddr variable.
|
||||||
* If we don't know where the image is then we're done.
|
* If we don't know where the image is then we're done.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
addr = load_addr;
|
addr = load_addr;
|
||||||
else
|
else
|
||||||
|
@ -167,7 +148,8 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_NET)
|
#if defined(CONFIG_CMD_NET)
|
||||||
/*
|
/*
|
||||||
* Check to see if we need to tftp the image ourselves before starting
|
* Check to see if we need to tftp the image ourselves
|
||||||
|
* before starting
|
||||||
*/
|
*/
|
||||||
if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) {
|
if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) {
|
||||||
if (net_loop(TFTPGET) <= 0)
|
if (net_loop(TFTPGET) <= 0)
|
||||||
|
@ -177,18 +159,18 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This should equate
|
/*
|
||||||
* to NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET
|
* This should equate to
|
||||||
|
* NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET
|
||||||
* from the VxWorks BSP header files.
|
* from the VxWorks BSP header files.
|
||||||
* This will vary from board to board
|
* This will vary from board to board
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_WALNUT)
|
#if defined(CONFIG_WALNUT)
|
||||||
tmp = (char *) CONFIG_SYS_NVRAM_BASE_ADDR + 0x500;
|
tmp = (char *)CONFIG_SYS_NVRAM_BASE_ADDR + 0x500;
|
||||||
eth_getenv_enetaddr("ethaddr", (uchar *)build_buf);
|
eth_getenv_enetaddr("ethaddr", (uchar *)build_buf);
|
||||||
memcpy(tmp, &build_buf[3], 3);
|
memcpy(tmp, &build_buf[3], 3);
|
||||||
#elif defined(CONFIG_SYS_VXWORKS_MAC_PTR)
|
#elif defined(CONFIG_SYS_VXWORKS_MAC_PTR)
|
||||||
tmp = (char *) CONFIG_SYS_VXWORKS_MAC_PTR;
|
tmp = (char *)CONFIG_SYS_VXWORKS_MAC_PTR;
|
||||||
eth_getenv_enetaddr("ethaddr", (uchar *)build_buf);
|
eth_getenv_enetaddr("ethaddr", (uchar *)build_buf);
|
||||||
memcpy(tmp, build_buf, 6);
|
memcpy(tmp, build_buf, 6);
|
||||||
#else
|
#else
|
||||||
|
@ -199,7 +181,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
* Use bootaddr to find the location in memory that VxWorks
|
* Use bootaddr to find the location in memory that VxWorks
|
||||||
* will look for the bootline string. The default value for
|
* will look for the bootline string. The default value for
|
||||||
* PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which
|
* PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which
|
||||||
* defaults to 0x4200
|
* defaults to 0x4200.
|
||||||
*/
|
*/
|
||||||
tmp = getenv("bootaddr");
|
tmp = getenv("bootaddr");
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
|
@ -210,7 +192,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
/*
|
/*
|
||||||
* Check to see if the bootline is defined in the 'bootargs'
|
* Check to see if the bootline is defined in the 'bootargs'
|
||||||
* parameter. If it is not defined, we may be able to
|
* parameter. If it is not defined, we may be able to
|
||||||
* construct the info
|
* construct the info.
|
||||||
*/
|
*/
|
||||||
bootline = getenv("bootargs");
|
bootline = getenv("bootargs");
|
||||||
if (bootline) {
|
if (bootline) {
|
||||||
|
@ -252,44 +234,42 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
/*
|
/*
|
||||||
* If the data at the load address is an elf image, then
|
* If the data at the load address is an elf image, then
|
||||||
* treat it like an elf image. Otherwise, assume that it is a
|
* treat it like an elf image. Otherwise, assume that it is a
|
||||||
* binary image
|
* binary image.
|
||||||
*/
|
*/
|
||||||
|
if (valid_elf_image(addr))
|
||||||
if (valid_elf_image(addr)) {
|
|
||||||
addr = load_elf_image_shdr(addr);
|
addr = load_elf_image_shdr(addr);
|
||||||
} else {
|
else
|
||||||
puts("## Not an ELF image, assuming binary\n");
|
puts("## Not an ELF image, assuming binary\n");
|
||||||
/* leave addr as load_addr */
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("## Using bootline (@ 0x%lx): %s\n", bootaddr,
|
printf("## Using bootline (@ 0x%lx): %s\n", bootaddr,
|
||||||
(char *) bootaddr);
|
(char *)bootaddr);
|
||||||
printf("## Starting vxWorks at 0x%08lx ...\n", addr);
|
printf("## Starting vxWorks at 0x%08lx ...\n", addr);
|
||||||
|
|
||||||
dcache_disable();
|
dcache_disable();
|
||||||
((void (*)(int)) addr) (0);
|
((void (*)(int))addr)(0);
|
||||||
|
|
||||||
puts("## vxWorks terminated\n");
|
puts("## vxWorks terminated\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/*
|
||||||
* 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.
|
||||||
* ====================================================================== */
|
*/
|
||||||
static unsigned long load_elf_image_phdr(unsigned long addr)
|
static unsigned long load_elf_image_phdr(unsigned long addr)
|
||||||
{
|
{
|
||||||
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
|
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
|
||||||
Elf32_Phdr *phdr; /* Program header structure pointer */
|
Elf32_Phdr *phdr; /* Program header structure pointer */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ehdr = (Elf32_Ehdr *) addr;
|
ehdr = (Elf32_Ehdr *)addr;
|
||||||
phdr = (Elf32_Phdr *) (addr + ehdr->e_phoff);
|
phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
|
||||||
|
|
||||||
/* Load each program header */
|
/* Load each program header */
|
||||||
for (i = 0; i < ehdr->e_phnum; ++i) {
|
for (i = 0; i < ehdr->e_phnum; ++i) {
|
||||||
void *dst = (void *)(uintptr_t) phdr->p_paddr;
|
void *dst = (void *)(uintptr_t)phdr->p_paddr;
|
||||||
void *src = (void *) addr + phdr->p_offset;
|
void *src = (void *)addr + phdr->p_offset;
|
||||||
debug("Loading phdr %i to 0x%p (%i bytes)\n",
|
debug("Loading phdr %i to 0x%p (%i bytes)\n",
|
||||||
i, dst, phdr->p_filesz);
|
i, dst, phdr->p_filesz);
|
||||||
if (phdr->p_filesz)
|
if (phdr->p_filesz)
|
||||||
|
@ -312,44 +292,40 @@ static unsigned long load_elf_image_shdr(unsigned long addr)
|
||||||
unsigned char *image; /* Binary image pointer */
|
unsigned char *image; /* Binary image pointer */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
ehdr = (Elf32_Ehdr *)addr;
|
||||||
|
|
||||||
ehdr = (Elf32_Ehdr *) 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 +
|
||||||
(ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
|
(ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
|
||||||
|
|
||||||
if (shdr->sh_type == SHT_STRTAB)
|
if (shdr->sh_type == SHT_STRTAB)
|
||||||
strtab = (unsigned char *) (addr + shdr->sh_offset);
|
strtab = (unsigned char *)(addr + shdr->sh_offset);
|
||||||
|
|
||||||
/* Load each appropriate section */
|
/* Load each appropriate section */
|
||||||
for (i = 0; i < ehdr->e_shnum; ++i) {
|
for (i = 0; i < ehdr->e_shnum; ++i) {
|
||||||
shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
|
shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
|
||||||
(i * sizeof(Elf32_Shdr)));
|
(i * sizeof(Elf32_Shdr)));
|
||||||
|
|
||||||
if (!(shdr->sh_flags & SHF_ALLOC)
|
if (!(shdr->sh_flags & SHF_ALLOC) ||
|
||||||
|| shdr->sh_addr == 0 || shdr->sh_size == 0) {
|
shdr->sh_addr == 0 || shdr->sh_size == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strtab) {
|
if (strtab) {
|
||||||
debug("%sing %s @ 0x%08lx (%ld bytes)\n",
|
debug("%sing %s @ 0x%08lx (%ld bytes)\n",
|
||||||
(shdr->sh_type == SHT_NOBITS) ?
|
(shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
|
||||||
"Clear" : "Load",
|
|
||||||
&strtab[shdr->sh_name],
|
&strtab[shdr->sh_name],
|
||||||
(unsigned long) shdr->sh_addr,
|
(unsigned long)shdr->sh_addr,
|
||||||
(long) shdr->sh_size);
|
(long)shdr->sh_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shdr->sh_type == SHT_NOBITS) {
|
if (shdr->sh_type == SHT_NOBITS) {
|
||||||
memset((void *)(uintptr_t) shdr->sh_addr, 0,
|
memset((void *)(uintptr_t)shdr->sh_addr, 0,
|
||||||
shdr->sh_size);
|
shdr->sh_size);
|
||||||
} else {
|
} else {
|
||||||
image = (unsigned char *) addr + shdr->sh_offset;
|
image = (unsigned char *)addr + shdr->sh_offset;
|
||||||
memcpy((void *)(uintptr_t) shdr->sh_addr,
|
memcpy((void *)(uintptr_t)shdr->sh_addr,
|
||||||
(const void *) image,
|
(const void *)image, shdr->sh_size);
|
||||||
shdr->sh_size);
|
|
||||||
}
|
}
|
||||||
flush_cache(shdr->sh_addr, shdr->sh_size);
|
flush_cache(shdr->sh_addr, shdr->sh_size);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +333,6 @@ static unsigned long load_elf_image_shdr(unsigned long addr)
|
||||||
return ehdr->e_entry;
|
return ehdr->e_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====================================================================== */
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
bootelf, 3, 0, do_bootelf,
|
bootelf, 3, 0, do_bootelf,
|
||||||
"Boot from an ELF image in memory",
|
"Boot from an ELF image in memory",
|
||||||
|
|
Loading…
Reference in New Issue