@ -19,8 +19,85 @@
# include <net.h>
# include <vxworks.h>
static unsigned long load_elf_image_phdr ( unsigned long addr ) ;
static unsigned long load_elf_image_shdr ( unsigned long addr ) ;
/*
* A very simple elf loader , assumes the image is valid , returns the
* entry point address .
*/
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 ;
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 ( ( unsigned long ) dst , phdr - > p_filesz ) ;
+ + 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 ;
/* 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 ( shdr - > sh_addr , shdr - > sh_size ) ;
}
return ehdr - > e_entry ;
}
/* Allow ports to override the default behavior */
static unsigned long do_bootelf_exec ( ulong ( * entry ) ( int , char * const [ ] ) ,
@ -253,86 +330,6 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1 ;
}
/*
* A very simple elf loader , assumes the image is valid , returns the
* entry point address .
*/
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 ;
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 ( ( unsigned long ) dst , phdr - > p_filesz ) ;
+ + 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 ;
/* 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 ( shdr - > sh_addr , shdr - > sh_size ) ;
}
return ehdr - > e_entry ;
}
U_BOOT_CMD (
bootelf , 3 , 0 , do_bootelf ,
" Boot from an ELF image in memory " ,