rv, php->p_filesz, php->p_vaddr, php->p_offset);
return -1;
}
- AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at %x\n",
+ AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at 0x%04x\n",
php->p_filesz, php->p_vaddr);
return 0;
}
continue;
if (php->p_vaddr < 0x800000) {
/* Explicit flash section. Load it. */
+ if (firmware->flash == NULL) {
+ firmware->flashbase = 0;
+ firmware->flashsize = php->p_vaddr + php->p_filesz;
+ firmware->flash = malloc(firmware->flashsize);
+ memset(firmware->flash, 0xff, firmware->flashsize);
+ uint8_t *where = firmware->flash + php->p_vaddr;
+ elf_copy_segment(fd, php, &where);
+
+ } else {
+ long gapSize = php->p_vaddr - firmware->flashsize;
+ if (gapSize < 0) {
+ AVR_LOG(NULL, LOG_ERROR,
+ "Overlapping flash sections!\n");
+ return -1;
+ } else if (gapSize > 0) {
+ firmware->flash = realloc(firmware->flash,php->p_vaddr );
+ uint8_t *where = firmware->flash + firmware->flashsize;
+ memset(where, 0xff, gapSize);
+ firmware->flashsize = php->p_vaddr;
+ }
+ firmware->flash = realloc(firmware->flash,
+ firmware->flashsize + php->p_filesz);
+ if (!firmware->flash)
+ return -1;
+ uint8_t *where = firmware->flash + firmware->flashsize;
+ elf_copy_segment(fd, php, &where);
+ firmware->flashsize += php->p_filesz;
+ }
- if (elf_handle_segment(fd, php, &firmware->flash, "Flash"))
- continue;
- firmware->flashsize = php->p_filesz;
- firmware->flashbase = php->p_vaddr;
} else if (php->p_vaddr < 0x810000) {
/* Data space. If there are initialised variables, treat
* them as extra initialised flash. The C startup function
* understands that and will copy them to RAM.
*/
- if (firmware->flash) {
+ if (firmware->flash != NULL) {
uint8_t *where;
firmware->flash = realloc(firmware->flash,
return -1;
where = firmware->flash + firmware->flashsize;
elf_copy_segment(fd, php, &where);
+ AVR_LOG(NULL, LOG_DEBUG, ".data section %d bytes copied to flash at 0x%04x\n", php->p_filesz, firmware->flashsize);
firmware->flashsize += php->p_filesz;
} else {
/* If this ever happens, add a second pass. */
}
}
+ avr_t *avr = avr_make_mcu_by_name(firmware->mmcu);
+ if (avr != NULL) {
+ if (firmware->flash == NULL) {
+ AVR_LOG(NULL, LOG_ERROR,
+ "no flash!\n",
+ php->p_filesz, php->p_vaddr);
+ return -1;
+ } else {
+ long gapSize = avr->flashend + 1 - firmware->flashsize;
+ if (gapSize < 0) {
+ AVR_LOG(NULL, LOG_ERROR,
+ "flash size 0x%04x too large for selected mmcu device %s!\n", firmware->flashsize, firmware->mmcu);
+ return -1;
+ } else if (gapSize > 0) {
+ firmware->flash = realloc(firmware->flash, firmware->flashsize + gapSize);
+ uint8_t *where = firmware->flash + firmware->flashsize;
+ memset(where, 0xff, gapSize);
+ firmware->flashsize += gapSize;
+ }
+ }
+ }
/* Scan the section table for .mmcu magic and symbols. */
while ((scn = elf_nextscn(elf, scn)) != NULL) {
}
#endif // ELF_SYMBOLS
}
+ if (firmware->flash != NULL) {
+ AVR_LOG(NULL, LOG_DEBUG, "end of flash initialization (size=0x%04x)\n", firmware->flashsize);
+ }
elf_end(elf);
close(fd);
return 0;