|
|
@ -26,6 +26,11 @@ void load_elf32_section(struct file *fp, uint32_t address,
|
|
|
|
uint32_t file_offset, uint32_t length)
|
|
|
|
uint32_t file_offset, uint32_t length)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint8_t *elf_loc = (uint8_t *)address;
|
|
|
|
uint8_t *elf_loc = (uint8_t *)address;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
|
|
|
printf("Init data: %08x length %08x\n", address, length);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
cilo_seek(fp, file_offset, SEEK_SET);
|
|
|
|
cilo_seek(fp, file_offset, SEEK_SET);
|
|
|
|
cilo_read(elf_loc, length, 1, fp);
|
|
|
|
cilo_read(elf_loc, length, 1, fp);
|
|
|
|
|
|
|
|
|
|
|
@ -41,6 +46,10 @@ void load_elf32_uninitialized_memory(uint32_t address, uint32_t length)
|
|
|
|
int i = 0;
|
|
|
|
int i = 0;
|
|
|
|
uint8_t *p = (uint8_t *)address;
|
|
|
|
uint8_t *p = (uint8_t *)address;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
|
|
|
printf("Uninit data: %08x, len %08x\n", address, length);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
p[i] = 0;
|
|
|
|
p[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -98,6 +107,7 @@ int load_elf32_file(struct file *fp)
|
|
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|
struct elf32_phdr phdr;
|
|
|
|
struct elf32_phdr phdr;
|
|
|
|
|
|
|
|
uint32_t offset = 0xffffffff;
|
|
|
|
|
|
|
|
|
|
|
|
cilo_seek(fp, hdr.phoff, SEEK_SET);
|
|
|
|
cilo_seek(fp, hdr.phoff, SEEK_SET);
|
|
|
|
/* read in program header(s), determine total memory size of image */
|
|
|
|
/* read in program header(s), determine total memory size of image */
|
|
|
@ -105,11 +115,18 @@ int load_elf32_file(struct file *fp)
|
|
|
|
for (i = 0; i < hdr.phnum; i++) {
|
|
|
|
for (i = 0; i < hdr.phnum; i++) {
|
|
|
|
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
|
|
|
|
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (phdr.type != ELF_PT_LOAD) continue;
|
|
|
|
|
|
|
|
|
|
|
|
mem_sz += phdr.memsz;
|
|
|
|
mem_sz += phdr.memsz;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (phdr.paddr < offset) offset = phdr.paddr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* read the PT_LOAD segments into memory at paddr + mem_sz
|
|
|
|
#ifdef DEBUG
|
|
|
|
*/
|
|
|
|
printf("mem_sz = %08x\n", mem_sz);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* read the PT_LOAD segments into memory at paddr + mem_sz */
|
|
|
|
cilo_seek(fp, hdr.phoff, SEEK_SET);
|
|
|
|
cilo_seek(fp, hdr.phoff, SEEK_SET);
|
|
|
|
for (i = 0; i < hdr.phnum; i++) {
|
|
|
|
for (i = 0; i < hdr.phnum; i++) {
|
|
|
|
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
|
|
|
|
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
|
|
|
@ -117,34 +134,35 @@ int load_elf32_file(struct file *fp)
|
|
|
|
/* skip unloadable segments */
|
|
|
|
/* skip unloadable segments */
|
|
|
|
if (phdr.type != ELF_PT_LOAD) continue;
|
|
|
|
if (phdr.type != ELF_PT_LOAD) continue;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t leftover = phdr.memsz - phdr.filesz;
|
|
|
|
/* uint32_t leftover = phdr.memsz - phdr.filesz; */
|
|
|
|
load_elf32_section(fp, mem_sz + phdr.paddr,
|
|
|
|
load_elf32_section(fp, mem_sz + phdr.paddr,
|
|
|
|
phdr.offset, phdr.filesz);
|
|
|
|
phdr.offset, phdr.filesz);
|
|
|
|
|
|
|
|
|
|
|
|
if (leftover > 0) {
|
|
|
|
/* if (leftover > 0) {
|
|
|
|
load_elf32_uninitialized_memory(mem_sz + phdr.paddr +
|
|
|
|
load_elf32_uninitialized_memory(mem_sz + phdr.paddr +
|
|
|
|
phdr.filesz, leftover);
|
|
|
|
phdr.filesz, leftover);
|
|
|
|
}
|
|
|
|
} */
|
|
|
|
|
|
|
|
|
|
|
|
cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1),
|
|
|
|
cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1),
|
|
|
|
SEEK_SET);
|
|
|
|
SEEK_SET);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* assume the entry point is the smallest address we're loading */
|
|
|
|
/* assume the entry point is the smallest address we're loading */
|
|
|
|
uint32_t load_offset = mem_sz + hdr.entry;
|
|
|
|
uint32_t load_offset = mem_sz + offset;
|
|
|
|
|
|
|
|
|
|
|
|
printf("Loaded %d bytes at %08x.\n", mem_sz, load_offset);
|
|
|
|
printf("Loaded %d bytes at %08x.\n", mem_sz, load_offset);
|
|
|
|
|
|
|
|
|
|
|
|
printf("Kicking into Linux.\n");
|
|
|
|
printf("Kicking into Linux.\n");
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf("bootcpy: %08x, kdataoffset: %08x, kdatalength: %08x\n",
|
|
|
|
printf("load_offset = 0x%08x\n", load_offset);
|
|
|
|
loader_addr, load_offset, mem_sz);
|
|
|
|
printf("hdr.entry = 0x%08x\n", hdr.entry);
|
|
|
|
printf("kentrypt: %08x, kloadoffset: %08x\n", hdr.entry, hdr.entry);
|
|
|
|
printf("mem_sz = 0x%08x\n", mem_sz);
|
|
|
|
|
|
|
|
printf("offset = 0x%08x\n", offset);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* Jump to the copy routine */
|
|
|
|
/* Jump to the copy routine */
|
|
|
|
stage_two(load_offset, hdr.entry, mem_sz);
|
|
|
|
stage_two(load_offset, hdr.entry, mem_sz, offset);
|
|
|
|
|
|
|
|
|
|
|
|
return -1; /* something failed, badly */
|
|
|
|
return -1; /* something failed, badly */
|
|
|
|
}
|
|
|
|
}
|
|
|
|