static int load_elf_rom( unsigned long *entry, int fd ) { int i, lszz_offs, elf_offs; char buf[128], *addr; Elf_ehdr ehdr; Elf_phdr *phdr; size_t s; printk("Loading '%s'\n", get_file_path(fd)); /* the ELF-image (usually) starts at offset 0x4000 */ if( (elf_offs=find_elf(fd)) < 0 ) { printk("----> %s is not an ELF image\n", buf ); exit(1); } if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) fatal_error("elf_readhdrs failed\n"); *entry = ehdr.e_entry; /* load segments. Compressed ROM-image assumed to be located immediately * after the last segment */ lszz_offs = elf_offs; for( i=0; i<ehdr.e_phnum; i++ ) { /* p_memsz, p_flags */ s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); seek_io( fd, elf_offs + phdr[i].p_offset ); /* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n", phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, phdr[i].p_vaddr ); */ if( phdr[i].p_vaddr != phdr[i].p_paddr ) printk("WARNING: ELF segment virtual addr != physical addr\n"); lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); if( !s ) continue; if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) fatal_error("Claim failed!\n"); addr = (char*)phdr[i].p_vaddr; if( read_io(fd, addr, s) != s ) fatal_error("read failed\n"); #if 0 /* patch CODE segment */ if( *entry >= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); } #endif flush_icache_range( addr, addr+s ); /*printk("ELF ROM-section loaded at %08lX (size %08lX)\n", (unsigned long)phdr[i].p_vaddr, (unsigned long)phdr[i].p_memsz );*/ } free( phdr ); return lszz_offs; }
void *load_elf(char *spec) { #if 0 int fd; void *entry=NULL; int i, lszz_offs, elf_offs; char buf[128]; // , *addr; Elf_ehdr ehdr; Elf_phdr *phdr; size_t s; if( (fd=open_io(spec)) == -1 ) return NULL; if( (elf_offs=find_elf(fd)) < 0 ) { printk("----> %s is not an ELF image\n", buf ); return NULL; } if( !(phdr=elf_readhdrs(fd, 0, &ehdr)) ) { printk("elf32_readhdrs failed\n"); return NULL; } (unsigned long long *)entry = ehdr.e_entry; lszz_offs = elf_offs; for( i=0; i<ehdr.e_phnum; i++ ) { s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); seek_io( fd, elf_offs + phdr[i].p_offset ); /* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n", phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, phdr[i].p_vaddr ); */ if( phdr[i].p_vaddr != phdr[i].p_paddr ) printk("WARNING: ELF segment virtual addr != physical addr\n"); lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); if( !s ) continue; printk("ELF ROM-section loaded at %08lX (size %08lX)\n", (unsigned long)phdr[i].p_vaddr, (unsigned long)phdr[i].p_memsz); } free( phdr ); return entry; #else return NULL; #endif }
/*-------------------------------------------- | Name: tiny_elfloader | Description: | Parameters: none | Return Type: none | Comments: | See: ----------------------------------------------*/ int tiny_elfloader(void){ unsigned long addr=0; _elf_printf(_lepton_bootstrap_banner); _elf_printf("compilation date %s-%s\r\n",__kernel_date__,__kernel_time__); // if(!(addr=find_elf())) { _elf_printf("No ELF signature found at 0x%x and 0x%x\r\n", ELF_MEMORY_ADDRESS_BOOTLOADER, ELF_MEMORY_ADDRESS_APPLICATION); return 0; } // _tiny_elfloader(addr,0x00000000); return 0; }
int elf_load(struct sys_info *info, ihandle_t dev, const char *cmdline, void **boot_notes) { Elf_ehdr ehdr; Elf_phdr *phdr = NULL; unsigned long checksum_offset, file_size; unsigned short checksum = 0; int retval = -1; unsigned int offset; image_name = image_version = NULL; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { goto out; } offset = find_elf(&ehdr); if (!offset) { retval = LOADER_NOT_SUPPORT; goto out; } #if DEBUG printk("ELF header:\n"); printk(" ehdr.e_type = %d\n", (int)ehdr.e_type); printk(" ehdr.e_machine = %d\n", (int)ehdr.e_machine); printk(" ehdr.e_version = %d\n", (int)ehdr.e_version); printk(" ehdr.e_entry = 0x%08x\n", (int)ehdr.e_entry); printk(" ehdr.e_phoff = 0x%08x\n", (int)ehdr.e_phoff); printk(" ehdr.e_shoff = 0x%08x\n", (int)ehdr.e_shoff); printk(" ehdr.e_flags = %d\n", (int)ehdr.e_flags); printk(" ehdr.e_ehsize = 0x%08x\n", (int)ehdr.e_ehsize); printk(" ehdr.e_phentsize = 0x%08x\n", (int)ehdr.e_phentsize); printk(" ehdr.e_phnum = %d\n", (int)ehdr.e_phnum); #endif if (ehdr.e_phnum > MAX_HEADERS) { printk ("elfload: too many program headers (MAX_HEADERS)\n"); retval = 0; goto out; } phdr = elf_readhdrs(offset, &ehdr); if (!phdr) goto out; if (!check_mem_ranges(info, phdr, ehdr.e_phnum)) goto out; checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset); printf("Loading %s", image_name ? image_name : "image"); if (image_version) printf(" version %s", image_version); printf("...\n"); if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset, &file_size)) goto out; if (checksum_offset) { if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum)) goto out; } /* If we are attempting an ELF boot image, we pass a non-NULL pointer into boot_notes and mark the image as elf-boot rather than standard ELF */ if (boot_notes) { *boot_notes = (void *)virt_to_phys(build_boot_notes(info, cmdline)); feval("elf-boot saved-program-state >sps.file-type !"); } else { feval("elf saved-program-state >sps.file-type !"); } //debug("current time: %lu\n", currticks()); debug("entry point is " FMT_elf "\n", addr_fixup(ehdr.e_entry)); // Initialise saved-program-state PUSH(addr_fixup(ehdr.e_entry)); feval("saved-program-state >sps.entry !"); PUSH(file_size); feval("saved-program-state >sps.file-size !"); feval("-1 state-valid !"); out: close_io(fd); if (phdr) free(phdr); if (image_name) free(image_name); if (image_version) free(image_version); return retval; }