Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 62 additions & 44 deletions software/os/mselOS/romgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,24 @@
#define ROMVLOC 0x100000
#define ROMVEND 0x110000

#define SUCCESS 0

int main(int argc, char *argv[])
{
uint32_t romaddr;
uint32_t romaddr;
char* elffile = argv[1];
char* romfile = argv[2];
int elffd;
FILE * romfd;
void* elfmmap;
int err;
int exitCode = SUCCESS;
struct stat fstats;

if(argc != 3)
{
printf("argv[1] should be a path to an ELF file\n");
printf("argv[2] should be a path to an output ROM file\n");
fprintf(stderr, "argv[1] should be a path to an ELF file\n");
fprintf(stderr, "argv[2] should be a path to an output ROM file\n");
exit(-1);
}

Expand All @@ -56,32 +59,34 @@ int main(int argc, char *argv[])
if(elffd < 0)
{
perror("open romfile");
exit(-1);
exitCode = -1;
goto deferDone;
}

fprintf(romfd, "@0000_0000\n");

err = fstat(elffd, &fstats);
if(err < 0)
{
perror("stat");
exit(-1);
perror("stat elffd");
exitCode = -1;
goto deferDone;
}

elfmmap = mmap(NULL, fstats.st_size, PROT_READ, MAP_PRIVATE, elffd, 0);
if(elfmmap == MAP_FAILED)
{
perror("mmap");
exit(-1);
exitCode = -1;
goto deferDone;
}

Elf32_Ehdr* ehdr = elfmmap;
size_t pnum;

if(fstats.st_size < sizeof(*ehdr))
{
printf("ELF File too small\n");
exit(-1);
fprintf(stderr, "ELF File too small\n");
exitCode = -1;
goto deferUnmap;
}

if(ehdr->e_ident[EI_MAG0] != 0x7f ||
Expand All @@ -92,51 +97,64 @@ int main(int argc, char *argv[])
ehdr->e_ident[EI_DATA] != ELFDATA2MSB
)
{
printf("Invalid ELF\n");
exit(-1);
fprintf(stderr, "Invalid ELF\n");
exitCode = -1;
goto deferUnmap;
}

if(fstats.st_size < sizeof(Elf32_Phdr)*ntohs(ehdr->e_phnum) + ntohl(ehdr->e_phoff))
{
printf("ELF File too small\n");
exit(-1);
fprintf(stderr, "ELF File too small\n");
exitCode = -1;
goto deferUnmap;
}

fprintf(romfd, "@0000_0000\n");

for(romaddr = 0; romaddr < ROM_SIZE_LIMIT; romaddr += 4)
{
for(pnum=0; pnum<ntohs(ehdr->e_phnum); pnum++)
{
Elf32_Phdr* phdr = (Elf32_Phdr *)(elfmmap + (ntohl(ehdr->e_phoff) + sizeof(Elf32_Phdr)*pnum));

uint32_t paddr = ntohl(phdr->p_paddr);
uint32_t vaddr = ntohl(phdr->p_vaddr);
uint32_t filesz = ntohl(phdr->p_filesz);
uint32_t memsz = ntohl(phdr->p_memsz);
uint32_t offset = ntohl(phdr->p_offset);

if((paddr - ROMVLOC) != romaddr)
continue;

printf("PHDR paddr@%zu paddr=0x%08x vaddr=0x%08x filesz=%u memsz=%u\n",pnum, paddr, vaddr, filesz, memsz);

{
uint8_t *ptr;
uint32_t i;

ptr = (uint8_t *) elfmmap;
ptr = &ptr[offset];
for(i = 0; i < filesz; i += 4, ptr += 4, romaddr += 4)
fprintf(romfd, "%02x%02x_%02x%02x\n", ptr[0], ptr[1], ptr[2], ptr[3]);
}
}

if(pnum >= ntohs(ehdr->e_phnum))
fprintf(romfd, "%02x%02x_%02x%02x\n", 0, 0, 0, 0);
for(pnum=0; pnum<ntohs(ehdr->e_phnum); pnum++)
{
Elf32_Phdr* phdr = (Elf32_Phdr *)(elfmmap + (ntohl(ehdr->e_phoff) + sizeof(Elf32_Phdr)*pnum));

uint32_t paddr = ntohl(phdr->p_paddr);
uint32_t vaddr = ntohl(phdr->p_vaddr);
uint32_t filesz = ntohl(phdr->p_filesz);
uint32_t memsz = ntohl(phdr->p_memsz);
uint32_t offset = ntohl(phdr->p_offset);

if((paddr - ROMVLOC) != romaddr)
continue;

printf("PHDR paddr@%zu paddr=0x%08x vaddr=0x%08x filesz=%u memsz=%u\n",pnum, paddr, vaddr, filesz, memsz);

{
uint8_t *ptr;
uint32_t i;

ptr = (uint8_t *) elfmmap;
ptr = &ptr[offset];
for(i = 0; i < filesz; i += 4, ptr += 4, romaddr += 4)
fprintf(romfd, "%02x%02x_%02x%02x\n", ptr[0], ptr[1], ptr[2], ptr[3]);
}
}

if(pnum >= ntohs(ehdr->e_phnum))
fprintf(romfd, "%02x%02x_%02x%02x\n", 0, 0, 0, 0);
}

if(romaddr > ROM_SIZE_LIMIT)
fprintf(stderr, "ROM may exceed size limit of %dk\n", ROM_SIZE_KB);
fprintf(stderr, "ROM may exceed size limit of %dk\n", ROM_SIZE_KB);

deferUnmap:
munmap(elfmmap, fstats.st_size);

deferDone:
close(elffd);
fclose(romfd);

if (exitCode != SUCCESS)
exit(exitCode);

return 0;
}