The board I developed for contains an Atmega128 attached to an ethernet controller. Also, it contains a bootloader that can program and dump the flash and eeprom memory.
What I wanted is a complete snapshot of a working board for production use (special bootloader/firmware version without final encryption keys). It will also have the default MAC and IP address and checksum information in EEprom.
So, first I prepare a complete working board and start dumping the program memory in encrypted format by using a special bootloader function. The tool automatically writes out a special format complete with checksums etc.
bootload -m 00-01-23-45-67-89 -d -i dump.img -b 172.16.0.0Then I call the encryption/decryption tool to turn it into a plain binary.
imgtool -d -b dump.bin -i dump.imgI do the same with the bootloader that is located at 0x1E000.
bootload -m 00-01-23-45-67-89 -d -i bldump.img -s 0x1E000 -b 172.16.0.0And decrypt that as well:
imgtool -d -b bldump.bin -i bldump.img -s 0x1E000Then comes the EEprom dump which is already in plain binary form:
bootload -m 00-01-23-45-67-89 -e -b 172.16.0.0You might want to crop it down to a reasonable working size since programming the EEprom is terribly slow.
srec_cat eeprom.bin -binary -crop 0x0 0x80 -o eeprom.bin -binaryWe also need small files containing the (lock-)fuses and the CPU signature that needs to match before programming. The order of bytes need to be reversed.
You could also compile this data with your project.
signature.bin (3 bytes):
02 97 1E for atmega128.fuse.bin (3 bytes):
BF D8 FFlock.bin (1 byte):
DC blocks programming cable and user-mode reads of bootloader area. The lock is written last and will activate the bootloader boot process.There are various ways to combine it all together. I chose to combined the flash sections first:
srec_cat dump.bin -binary bldump.bin -binary -offset 0x1E000 -o combined_dump.hex -inteland then add the extra sections:
avr-objcopy -O elf32-avr -I ihex combined_dump.hex --gap-fill 0xFF --add-section .eeprom=eeprom.bin --add-section .fuse=fuse.bin --add-section .lock=lock.bin --add-section .signature=signature.bin --rename-section .sec1=.text --rename-section .sec2=.text --set-section-flags=.eeprom="alloc,load" --set-section-flags=.fuse="alloc,load" --set-section-flags=.lock="alloc,load" --set-section-flags=.signature="alloc,load" temp.elfThe final step is assigning the section addresses and turning the file into executable ELF format.
avr-ld -s -mavr5 -o ProductionFile.elf temp.elf --section-start .eeprom=0x810000 --section-start .fuse=0x820000 --section-start .lock=0x830000 --section-start .signature=0x840000The section offsets don't mean very much but the programming tool might check for them.
After this, you can delete all other intermediate files.
Ready to test to production file...
Stk500 -cUSB -datmega128 -ipProductionFile.elf -e -pafebAnd there you have it.
I hope you stumbled upon this post and found it useful.
1 comment:
Another method without extra files:
/*
Add to [Linker options]:
-Wl,-section-start=.fuse=0x820000
-Wl,-section-start=.lock=0x830000
-Wl,-section-start=.signature=0x840000
*/
typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t;
#define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
SIGNATURE = {
.B2 = 0x02, .B1 = 0x97, .B0 = 0x1E,
};
typedef struct {unsigned char low;unsigned char high;unsigned char extended;} __fuse_t;
#define FUSE __fuse_t __fuse __attribute__((section (".fuse")))
FUSE = {
.low = 0x7F, .high = 0xC9, .extended = 0xFF,
};
__attribute__((section (".lock"))) const unsigned char __lock =
0xFF;
Post a Comment