Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optiboot without EEPROM support returns flash on EEPROM request #1227

Closed
mcuee opened this issue Dec 18, 2022 · 27 comments
Closed

Optiboot without EEPROM support returns flash on EEPROM request #1227

mcuee opened this issue Dec 18, 2022 · 27 comments
Labels
wontfix This will not be worked on

Comments

@mcuee
Copy link
Collaborator

mcuee commented Dec 18, 2022

I think this may not be a real issue but kind of strange behavior of the optiboot bootloader firmware.

I jusgt bought a few Uno Clones with CH340. Apparently due to chip shortages the boards come with ATmega328PB and not ATmega328P. The 4.4 version of Optiboot Arduino FW is still used wihout any changes. It does not support EEPROM and it is meant for ATmega328P.
https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/optiboot/optiboot_atmega328.hex

A few interesting behaviors here.

  1. -c arduino and -c urclock will insist that the chip connected is ATmega328P and not ATmega328PB. I think this is because of the bootloader firmware and we can not do anything about it.

  2. -c arduino will read Flash contents as EEPROM contents. -c urclock will do that as well if I specify -xeepromrw.
    @stefanrueger
    Do you think if No. 2 is a problem for avrdude? If yes what can we do here? Is it also the limitation of the paticular old optiboot firmware shipped by Arduino?

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump flash 0 0x10" | .\avrdude -c avrisp2 -p m328pb -qqt
avrdude> dump flash 0 0x10
0000  0c 94 61 00 0c 94 7e 00  0c 94 7e 00 0c 94 7e 00  | .a. .~. .~. .~.|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c avrisp2 -p m328pb -qqt
avrdude> dump eeprom 0 0x10
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c urclock -P COM17 -p m328p -qqt -xeepromrw
avrdude> dump eeprom 0 0x10
0000  0c 94 61 00 0c 94 7e 00  0c 94 7e 00 0c 94 7e 00  | .a. .~. .~. .~.|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c arduino -P COM17 -p m328p -qqt
avrdude> dump eeprom 0 0x10
0000  0c 94 61 00 0c 94 7e 00  0c 94 7e 00 0c 94 7e 00  | .a. .~. .~. .~.|

avrdude>
avrdude>

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c urclock -P COM17 -p m328pb -qqt -xeepromrw
avrdude error: connected part ATmega328P signature does not match -p ATmega328PB's (override with -F or use -p ATmega328P)
avrdude error: unable to read signature data for part ATmega328PB, rc=-1
avrdude error: unable to read signature data, rc=-1

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c arduino -P COM17 -p m328pb -qqt
avrdude error: expected signature for ATmega328PB is 1E 95 16
        double check chip or use -F to override this check
@mcuee mcuee added the question Further information is requested label Dec 18, 2022
@mcuee
Copy link
Collaborator Author

mcuee commented Dec 18, 2022

Even if I change the bootloader FW to @MCUdude's MiniCore and specified the right chip (ATmega328PB), then the first behavior is gone but the second behavior is still there.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c urclock -P COM5 -p m328pb -qq -xbootsize=512 -xshowall
0 0000-00-00 00.00  application 0 store 0 meta 0 boot 512 o8.0 -?s-?-r-- vector 0 (RESET) ATmega328PB

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c urclock -P COM5 -p m328pb -qqt -xbootsize=512
avrdude> dump eeprom 0 0x10
avrdude error: bootloader does not seem to have paged EEPROM read capability
avrdude error: bootloader does not seem to have EEPROM access capability
avrdude error: unable to read eeprom page at addr 0x0000
avrdude error: (dump) error reading eeprom address 0x00000 of part ATmega328PB
               read operation not supported on memory type eeprom
avrdude>
avrdude>

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c urclock -P COM5 -p m328pb -qqt -xbootsize=512 -xeepromrw
avrdude> dump eeprom 0 0x10
0000  0c 94 8f 00 0c 94 a1 00  0c 94 a1 00 0c 94 a1 00  | ... ... ... ...|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c arduino -P COM5 -p m328pb -qqt
avrdude> dump eeprom 0 0x10
0000  0c 94 8f 00 0c 94 a1 00  0c 94 a1 00 0c 94 a1 00  | ... ... ... ...|

avrdude>
avrdude>

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c usbasp -p m328pb -qqt
avrdude> dump eeprom 0 0x10
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump flash 0 0x10" | .\avrdude -c usbasp -p m328pb -qqt
avrdude> dump flash 0 0x10
0000  0c 94 8f 00 0c 94 a1 00  0c 94 a1 00 0c 94 a1 00  | ... ... ... ...|

avrdude>
avrdude>

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 18, 2022

Same for an Nano Clone with ATmega328P with the original 4.4 Optiboot bootloader FW.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c urclock -P COM10 -p m328p -qq -xbootsize=512 -xshowall
0 0000-00-00 00.00  application 0 store 0 meta 0 boot 512 o4.4 -?s-?-r-- vector 0 (RESET) ATmega328P
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c urclock -P COM10 -p m328p -qqt -xbootsize=512 -xeepromrw
avrdude> dump eeprom 0 0x10
0000  0c 94 5c 00 0c 94 6e 00  0c 94 6e 00 0c 94 6e 00  | .\. .n. .n. .n.|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c arduino -P COM10 -p m328p -qqt
avrdude> dump eeprom 0 0x10
0000  0c 94 5c 00 0c 94 6e 00  0c 94 6e 00 0c 94 6e 00  | .\. .n. .n. .n.|

avrdude>
avrdude>

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 18, 2022

@stefanrueger

Now I actually think the second issue is a bug for -c arduino and it is arguable for -c urclock. What is your opinion?

@stefanrueger
Copy link
Collaborator

  1. -c arduino and -c urclock will insist that the chip connected is ATmega328P and not ATmega328PB. I think this is because of the bootloader firmware and we can not do anything about it.

Correct. The bootloader firmware actually does not read the signature memory of the part. The bootloader returns hard-coded signature bytes of the part for which it was compiled. This is normal bootloader practice to save space. If the user burns an ATmega328P bootloader onto an ATmega328PB chip then AVRDUDE will see an m328p signature.

  1. -c arduino will read Flash contents as EEPROM contents. -c urclock will do that as well if I specify -xeepromrw.
    @stefanrueger
    Do you think if No. 2 is a problem for avrdude? If yes what can we do here? Is it also the limitation of the paticular old optiboot firmware shipped by Arduino?

This is a well-known optiboot bug. It returns flash for EEPROM if optiboot has been compiled to not handle EEPROM. This bug has been around for a long time (and possibly still is today but defo was 2016 when I last looked closely at optiboot).

It is not actually AVRDUDE's job to invent workarounds for all the bugs in bootloaders or programmer FW (though I have provided a fair deal of workarounds in the past). In this specific case, knowing about this bug, -c urclock uses the justified and sane default assumption that optiboot cannot deal EEPROM unless there is evidence to the contrary either by

  • A known bootloader in the hash table specifying that indeed it can deal with EEPROM
  • The user specifically promising AVRDUDE with -xeeprom that the bootloader can handle EEPROM

Now, @mcuee, your example is one where the user tells AVRDUDE -xeepromrw that indeed the bootloader can handle EEPROM only to be given flash by the buggy optiboot that actually cannot handle EEPROM.

Soooooo, can you guess what my opinion is?

Ditch optiboot. Never look back. Use urboot. Be happy ever after.

As there is a good alternative in this case I believe we should not spend our energy dancing around optiboot bugs.

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 18, 2022

@stefanrueger

Haha, I support urboot. We need to get avrdude 7.1 released to enable -c urclock.

Hopefully @MCUdude can start to distribute urboot early next year to make urboot more popular.

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 18, 2022

Hopefully @MCUdude can start to distribute urboot early next year to make urboot more popular.

Yes, this is the plan. However, I need to make sure that my cores will continue to support legacy optiboot bootloaders while using -c urclock, so users aren't forced to replace their bootloaders, even though it's highly recommended. It's also important that potential bugs found by mass-testing urboot gets fixed quickly.

@stefanrueger
Copy link
Collaborator

legacy optiboot bootloaders while using -c urclock

You are welcome to add to the hash table those legacy optiboot bootloaders that were shipped with your boards and/or frequently downloaded from your github core; I am happy to help you compute the hashes if you struggle with that.

And our legacy bootloaders will continue to work with -c arduino though with fewer benefits than -c urclock

urboot gets fixed quickly

That is my intention...

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 18, 2022

You are welcome to add to the hash table those legacy optiboot bootloaders that were shipped with your boards and/or frequently downloaded from your github core; I am happy to help you compute the hashes if you struggle with that.

Is this something you could help me automate? The optiboot flash repo is pretty easy for a script to run through.

From what I know, these are the most popular bootloaders:

20 MHz, 115200 baud
16 MHz, 115200 baud
8 MHz, 57600 baud
8 MHz 38400 baud
1 MHz 9600 baud

For UART 0, 1, 2, and 3 where present.

The only parts that should not be added are the AT90USB* parts, as I provide no Arduino core for them.

@stefanrueger
Copy link
Collaborator

stefanrueger commented Dec 18, 2022

The bootloader-hashes script finds all bootloaders recursively in the current directory and outputs the hash lines that can be cut and paste into the table. Sounds like the only thing you'd need to do is grep out the ones you are interested in. BTW, I think the bootloaders for 16 MHz, 115200 baud are probably identical to the ones 8 MHz, 57600 baud (so will have the same hash)

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 18, 2022

@stefanrueger this is the list of bootloader combinations I think are the most common.
However, some of the files have the same hash, even though they are different parts.
I've not removed any duplicates, but you can easily spot the duplicated by using sort -k 5 on the list below:

Optiboot flash hash
    {  512, 0, 0x2afe013b, 0x5775955f }, // optiboot_flash_atmega169_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xd5de2de6 }, // optiboot_flash_atmega169_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x7de5e119, 0xecba44da }, // optiboot_flash_atmega169_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x2afe013b, 0x0ebf1682 }, // optiboot_flash_atmega169_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega169_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0x5790d602, 0x728c740e }, // optiboot_flash_at90can64_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x5419d99f }, // optiboot_flash_at90can64_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x9ff3235b }, // optiboot_flash_at90can64_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xd1e8d0b9 }, // optiboot_flash_at90can64_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0xc76f76e5 }, // optiboot_flash_at90can64_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0xeafeb59b }, // optiboot_flash_at90can64_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x4ad22f5b }, // optiboot_flash_at90can64_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xb495f1ea }, // optiboot_flash_at90can64_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x246dbc35 }, // optiboot_flash_at90can64_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xd92f11b5 }, // optiboot_flash_at90can64_UART0_115200_16000000L_B5_BIGBOOT.hex
    {  512, 0, 0xb83f0d83, 0x3d3da465 }, // optiboot_flash_atmega32_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x8790003e, 0x9f82a66b }, // optiboot_flash_atmega32_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x8790003e, 0x65d86300 }, // optiboot_flash_atmega32_UART0_38400_8000000L_B0.hex
    {  512, 0, 0xb83f0d83, 0x87ac0178 }, // optiboot_flash_atmega32_UART0_38400_8000000L_B7.hex
    {  512, 0, 0xb83f0d83, 0xfae2fc26 }, // optiboot_flash_atmega32_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x8790003e, 0x333e86ec }, // optiboot_flash_atmega32_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x8790003e, 0xc286cdc8 }, // optiboot_flash_atmega32_UART0_115200_20000000L_B0.hex
    {  512, 0, 0xb83f0d83, 0x3330e675 }, // optiboot_flash_atmega32_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x8790003e, 0x55b98295 }, // optiboot_flash_atmega32_UART0_115200_16000000L_B0.hex
    {  512, 0, 0xb83f0d83, 0xde792fb2 }, // optiboot_flash_atmega32_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0xe2724ea2 }, // optiboot_flash_atmega3250p_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0xb21ddc89 }, // optiboot_flash_atmega3250p_UART0_38400_8000000L_B7.hex
    {  512, 0, 0xdaa198fa, 0x70fcc8e9 }, // optiboot_flash_atmega3250p_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0xca6c9014 }, // optiboot_flash_atmega3250p_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0x680e4729 }, // optiboot_flash_atmega3250p_UART0_115200_16000000L_B7.hex
    { 1024, 1, 0xae42ebb8, 0xe11ad957 }, // optiboot_flash_atmega644a_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xdc558cfc }, // optiboot_flash_atmega644a_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xc4b9120d }, // optiboot_flash_atmega644a_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1327cc64 }, // optiboot_flash_atmega644a_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x93195537 }, // optiboot_flash_atmega644a_UART0_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1224da19 }, // optiboot_flash_atmega644a_UART0_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1ec7bc40 }, // optiboot_flash_atmega644a_UART1_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xe9d90a4f }, // optiboot_flash_atmega644a_UART1_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x9d361c4e }, // optiboot_flash_atmega644a_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1e9a5d21 }, // optiboot_flash_atmega644a_UART1_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x3b651e15 }, // optiboot_flash_atmega644a_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xea8fe774 }, // optiboot_flash_atmega644a_UART0_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xb49eaa1f }, // optiboot_flash_atmega644a_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xbdbcaa5b }, // optiboot_flash_atmega644a_UART1_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x8298e287 }, // optiboot_flash_atmega644a_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x50418be4 }, // optiboot_flash_atmega644a_UART0_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xf9f61eb2 }, // optiboot_flash_atmega644a_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x7b6e9bb9 }, // optiboot_flash_atmega644a_UART1_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xe27428c7 }, // optiboot_flash_atmega644a_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xdab405bd }, // optiboot_flash_atmega644a_UART0_115200_16000000L_B0_BIGBOOT.hex
    {  512, 0, 0x281edc46, 0xf013cd1b }, // optiboot_flash_atmega8_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x281edc46, 0x8cc6362a }, // optiboot_flash_atmega8_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x281edc46, 0x1d7084ea }, // optiboot_flash_atmega8_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x281edc46, 0xe35b8b8e }, // optiboot_flash_atmega8_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x281edc46, 0xa6eeec00 }, // optiboot_flash_atmega8_UART0_115200_20000000L_B5
    {  512, 0, 0x281edc46, 0x3f821234 }, // optiboot_flash_atmega8_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x281edc46, 0x8f39129c }, // optiboot_flash_atmega8_UART0_115200_16000000L_B5
    {  512, 0, 0x6e02926f, 0x95dee889 }, // optiboot_flash_atmega168_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x6e02926f, 0x35af7f90 }, // optiboot_flash_atmega168_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x6d0b2063, 0x275726b6 }, // optiboot_flash_atmega168_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x6e02926f, 0xd5185017 }, // optiboot_flash_atmega168_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x6e02926f, 0x7cc1e494 }, // optiboot_flash_atmega168_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x5e0e0dd4, 0x35d5431e }, // optiboot_flash_atmega165p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x5e0e0dd4, 0xe668d759 }, // optiboot_flash_atmega165p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x43900a31, 0xd9660e09 }, // optiboot_flash_atmega165p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x5e0e0dd4, 0xdce1048b }, // optiboot_flash_atmega165p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x5e0e0dd4, 0xa53600f9 }, // optiboot_flash_atmega165p_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x7b09aae5, 0x69bf5c8e }, // optiboot_flash_atmega324p_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x6b6a18c2, 0xf5a5eb3c }, // optiboot_flash_atmega324p_UART1_38400_8000000L_B7.hex
    {  512, 0, 0x7b09aae5, 0xb615bceb }, // optiboot_flash_atmega324p_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x6b6a18c2, 0x0289d638 }, // optiboot_flash_atmega324p_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x7b09aae5, 0x8a733497 }, // optiboot_flash_atmega324p_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x6b6a18c2, 0x6eeef491 }, // optiboot_flash_atmega324p_UART1_57600_8000000L_B0.hex
    {  512, 0, 0x7b09aae5, 0x9a762e7d }, // optiboot_flash_atmega324p_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x6b6a18c2, 0x80502860 }, // optiboot_flash_atmega324p_UART1_57600_8000000L_B7.hex
    {  512, 0, 0xc0548728, 0xbace9eb0 }, // optiboot_flash_atmega324p_UART0_9600_1000000L_B0.hex
    {  512, 0, 0xc0548728, 0xcaee2c76 }, // optiboot_flash_atmega324p_UART0_9600_1000000L_B7.hex
    {  512, 0, 0xd93615c8, 0x43a30b2c }, // optiboot_flash_atmega324p_UART1_9600_1000000L_B0.hex
    {  512, 0, 0xd93615c8, 0x97447ea4 }, // optiboot_flash_atmega324p_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x6b6a18c2, 0x38bfc4ae }, // optiboot_flash_atmega324p_UART1_115200_20000000L_B0.hex
    {  512, 0, 0x6b6a18c2, 0x9b8dfb02 }, // optiboot_flash_atmega324p_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x7b09aae5, 0x6abeaf7f }, // optiboot_flash_atmega324p_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x7b09aae5, 0x3cf239db }, // optiboot_flash_atmega324p_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x7b09aae5, 0x4b40506a }, // optiboot_flash_atmega324p_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x7b09aae5, 0xe75b8b91 }, // optiboot_flash_atmega324p_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x6b6a18c2, 0xba7b95c0 }, // optiboot_flash_atmega324p_UART1_115200_16000000L_B0.hex
    {  512, 0, 0x6b6a18c2, 0x35013504 }, // optiboot_flash_atmega324p_UART1_115200_16000000L_B7.hex
    { 1024, 1, 0xae42ebb8, 0x72e304c8 }, // optiboot_flash_atmega645_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xfbb2c79a }, // optiboot_flash_atmega645_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6a60f73b }, // optiboot_flash_atmega645_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x84ab943f }, // optiboot_flash_atmega645_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x7c2c24f9 }, // optiboot_flash_atmega645_UART0_115200_16000000L_B5_BIGBOOT.hex
    {  512, 0, 0x3efcbf6f, 0xae9b86b1 }, // optiboot_flash_atmega88pb_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x3efcbf6f, 0xa82da96e }, // optiboot_flash_atmega88pb_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xc65332c3, 0x74825a27 }, // optiboot_flash_atmega88pb_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x3efcbf6f, 0x58548b06 }, // optiboot_flash_atmega88pb_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x3efcbf6f, 0x44f778e5 }, // optiboot_flash_atmega88pb_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0x60bc143e, 0x20e29e43 }, // optiboot_flash_atmega2561_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x955eba65 }, // optiboot_flash_atmega2561_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x765d7928 }, // optiboot_flash_atmega2561_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x4080ee21 }, // optiboot_flash_atmega2561_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0x490d324b }, // optiboot_flash_atmega2561_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0x79f90273 }, // optiboot_flash_atmega2561_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x33759a79 }, // optiboot_flash_atmega2561_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xa920ec6f }, // optiboot_flash_atmega2561_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x50c46e8f }, // optiboot_flash_atmega2561_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x3c27b00b }, // optiboot_flash_atmega2561_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xd85f6d82 }, // optiboot_flash_atmega1284p_UART0_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x1fbd2028 }, // optiboot_flash_atmega1284p_UART0_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xed72231d }, // optiboot_flash_atmega1284p_UART1_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x7f4a01a9 }, // optiboot_flash_atmega1284p_UART1_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xb0f7a5b8 }, // optiboot_flash_atmega1284p_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xc20575ef }, // optiboot_flash_atmega1284p_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x88e15790 }, // optiboot_flash_atmega1284p_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x55370f29 }, // optiboot_flash_atmega1284p_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x96d5dbb4 }, // optiboot_flash_atmega1284p_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x658f1f52 }, // optiboot_flash_atmega1284p_UART1_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0xbee18fbd }, // optiboot_flash_atmega1284p_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x1fc522fc }, // optiboot_flash_atmega1284p_UART0_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x10b83310 }, // optiboot_flash_atmega1284p_UART1_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x39e2135a }, // optiboot_flash_atmega1284p_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x3fc0adef }, // optiboot_flash_atmega1284p_UART0_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xa19ba944 }, // optiboot_flash_atmega1284p_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x5bc6b3f2 }, // optiboot_flash_atmega1284p_UART1_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x7ee4239d }, // optiboot_flash_atmega1284p_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x246eaa1b }, // optiboot_flash_atmega1284p_UART0_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xc9469042 }, // optiboot_flash_atmega1284p_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x685e324a }, // optiboot_flash_at90can128_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x40460a3e }, // optiboot_flash_at90can128_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x31358fa6 }, // optiboot_flash_at90can128_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xad844b43 }, // optiboot_flash_at90can128_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0x80d4a95f }, // optiboot_flash_at90can128_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0xbdb2e58f }, // optiboot_flash_at90can128_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x8f1246d8 }, // optiboot_flash_at90can128_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x45af5fee }, // optiboot_flash_at90can128_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xd9678677 }, // optiboot_flash_at90can128_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x9aa1fd94 }, // optiboot_flash_at90can128_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x9bcc1a0e }, // optiboot_flash_atmega2560_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x629de678 }, // optiboot_flash_atmega2560_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x30007b05 }, // optiboot_flash_atmega2560_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x90b8b8bc }, // optiboot_flash_atmega2560_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xd2c7eafc }, // optiboot_flash_atmega2560_UART2_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x08f9d27e }, // optiboot_flash_atmega2560_UART2_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xefb8f92a }, // optiboot_flash_atmega2560_UART3_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xe386a2c9 }, // optiboot_flash_atmega2560_UART3_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0x4b945002 }, // optiboot_flash_atmega2560_UART2_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0x3c39f01e }, // optiboot_flash_atmega2560_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0xd4735023 }, // optiboot_flash_atmega2560_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x679ba32b, 0x0efd4181 }, // optiboot_flash_atmega2560_UART3_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x91c04fe3 }, // optiboot_flash_atmega2560_UART2_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xbefc45da }, // optiboot_flash_atmega2560_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x3dd17c66 }, // optiboot_flash_atmega2560_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x08806ff2 }, // optiboot_flash_atmega2560_UART3_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x9846ce79 }, // optiboot_flash_atmega2560_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0xfb06ea82 }, // optiboot_flash_atmega2560_UART2_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x2c48547d }, // optiboot_flash_atmega2560_UART3_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x60bc143e, 0x332b8fbd }, // optiboot_flash_atmega2560_UART0_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0xf9a539c1, 0x1eb31a77 }, // optiboot_flash_atmega168pb_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xf9a539c1, 0xc8abf849 }, // optiboot_flash_atmega168pb_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x41fc44ac, 0xfa99a078 }, // optiboot_flash_atmega168pb_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xf9a539c1, 0x39b85e77 }, // optiboot_flash_atmega168pb_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xf9a539c1, 0x671dbf66 }, // optiboot_flash_atmega168pb_UART0_115200_16000000L_B5.hex
    {  512, 0, 0xd2abed82, 0xb7ca9aa0 }, // optiboot_flash_atmega329p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xd2abed82, 0x591c05db }, // optiboot_flash_atmega329p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x0367a176, 0x8379176b }, // optiboot_flash_atmega329p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xd2abed82, 0xe9039cee }, // optiboot_flash_atmega329p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xd2abed82, 0xa42a31ae }, // optiboot_flash_atmega329p_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x109d28fd, 0x944d7982 }, // optiboot_flash_atmega328pb_UART1_38400_8000000L_B5.hex
    {  512, 0, 0xaaca6333, 0x7527e2c3 }, // optiboot_flash_atmega328pb_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xaaca6333, 0xe99f2951 }, // optiboot_flash_atmega328pb_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x109d28fd, 0xbcd6db5f }, // optiboot_flash_atmega328pb_UART1_57600_8000000L_B5.hex
    {  512, 0, 0x43d06d19, 0xec3eecdc }, // optiboot_flash_atmega328pb_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x04f203a3, 0xb005f0fa }, // optiboot_flash_atmega328pb_UART1_9600_1000000L_B5.hex
    {  512, 0, 0xaaca6333, 0xeb9f0236 }, // optiboot_flash_atmega328pb_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x109d28fd, 0x7ef5c1ec }, // optiboot_flash_atmega328pb_UART1_115200_20000000L_B5.hex
    {  512, 0, 0x109d28fd, 0x06c4c2ee }, // optiboot_flash_atmega328pb_UART1_115200_16000000L_B5.hex
    {  512, 0, 0xaaca6333, 0xfcb4d5b7 }, // optiboot_flash_atmega328pb_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x9e762fa8, 0xb21ddc89 }, // optiboot_flash_atmega3250_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0xe2724ea2 }, // optiboot_flash_atmega3250_UART0_57600_8000000L_B7.hex
    {  512, 0, 0xdaa198fa, 0x70fcc8e9 }, // optiboot_flash_atmega3250_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0xca6c9014 }, // optiboot_flash_atmega3250_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x9e762fa8, 0x680e4729 }, // optiboot_flash_atmega3250_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x3145df66, 0xc272ddc7 }, // optiboot_flash_atmega324pa_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x071af385, 0x46471318 }, // optiboot_flash_atmega324pa_UART1_38400_8000000L_B7.hex
    {  512, 0, 0x3145df66, 0xe5b50fbd }, // optiboot_flash_atmega324pa_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x071af385, 0x85b4a0de }, // optiboot_flash_atmega324pa_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x3145df66, 0x72ff2709 }, // optiboot_flash_atmega324pa_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x071af385, 0x60508357 }, // optiboot_flash_atmega324pa_UART1_57600_8000000L_B0.hex
    {  512, 0, 0x3145df66, 0xcbaa0339 }, // optiboot_flash_atmega324pa_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x071af385, 0x8ef6048f }, // optiboot_flash_atmega324pa_UART1_57600_8000000L_B7.hex
    {  512, 0, 0x81d8a7ee, 0xcd519875 }, // optiboot_flash_atmega324pa_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x81d8a7ee, 0x111d249a }, // optiboot_flash_atmega324pa_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x06a9ef74, 0x6b5d6b2a }, // optiboot_flash_atmega324pa_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x06a9ef74, 0x34087c9f }, // optiboot_flash_atmega324pa_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x3145df66, 0xd5787c2f }, // optiboot_flash_atmega324pa_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x3145df66, 0xc4f81beb }, // optiboot_flash_atmega324pa_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x071af385, 0xdb04426f }, // optiboot_flash_atmega324pa_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x071af385, 0xd4a6a12d }, // optiboot_flash_atmega324pa_UART1_115200_20000000L_B0.hex
    {  512, 0, 0x071af385, 0x2823c21c }, // optiboot_flash_atmega324pa_UART1_115200_16000000L_B7.hex
    {  512, 0, 0x071af385, 0x1c41a6ff }, // optiboot_flash_atmega324pa_UART1_115200_16000000L_B0.hex
    {  512, 0, 0x3145df66, 0xe7173071 }, // optiboot_flash_atmega324pa_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x3145df66, 0xccd80acb }, // optiboot_flash_atmega324pa_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x5f64e566, 0x21e29c66 }, // optiboot_flash_atmega8535_UART0_38400_8000000L_B0.hex
    {  512, 0, 0xdc6b58da, 0x559f4e01 }, // optiboot_flash_atmega8535_UART0_38400_8000000L_B7.hex
    {  512, 0, 0xdc6b58da, 0xf3221cb1 }, // optiboot_flash_atmega8535_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x5f64e566, 0x308a27e4 }, // optiboot_flash_atmega8535_UART0_57600_8000000L_B0.hex
    {  512, 0, 0xdc6b58da, 0x36dda6dd }, // optiboot_flash_atmega8535_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x5f64e566, 0x4168537d }, // optiboot_flash_atmega8535_UART0_9600_1000000L_B0.hex
    {  512, 0, 0xdc6b58da, 0x4abee68c }, // optiboot_flash_atmega8535_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x5f64e566, 0xf520104b }, // optiboot_flash_atmega8535_UART0_115200_20000000L_B0.hex
    {  512, 0, 0xdc6b58da, 0x82613346 }, // optiboot_flash_atmega8535_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x5f64e566, 0x24b5ffd9 }, // optiboot_flash_atmega8535_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x19c64b08, 0x70ae9c0a }, // optiboot_flash_atmega88_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x19c64b08, 0x4270dce3 }, // optiboot_flash_atmega88_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x25ddbfca, 0x039961cd }, // optiboot_flash_atmega88_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x19c64b08, 0x9bf7763b }, // optiboot_flash_atmega88_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x19c64b08, 0x6159afd6 }, // optiboot_flash_atmega88_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0xae42ebb8, 0x4ec4df61 }, // optiboot_flash_atmega6490_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6f542d9f }, // optiboot_flash_atmega6490_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x66724b13 }, // optiboot_flash_atmega6490_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x987e5f86 }, // optiboot_flash_atmega6490_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4b132863 }, // optiboot_flash_atmega6490_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x72e304c8 }, // optiboot_flash_atmega645p_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xfbb2c79a }, // optiboot_flash_atmega645p_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6a60f73b }, // optiboot_flash_atmega645p_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x84ab943f }, // optiboot_flash_atmega645p_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x7c2c24f9 }, // optiboot_flash_atmega645p_UART0_115200_16000000L_B5_BIGBOOT.hex
    {  512, 0, 0x35e2b5b6, 0xe3f2c268 }, // optiboot_flash_atmega164a_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x46954df9, 0xc307e815 }, // optiboot_flash_atmega164a_UART1_57600_8000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0xc38c7647 }, // optiboot_flash_atmega164a_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x46954df9, 0xe5e526c7 }, // optiboot_flash_atmega164a_UART1_57600_8000000L_B0.hex
    {  512, 0, 0x35e2b5b6, 0x390f2ade }, // optiboot_flash_atmega164a_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x46954df9, 0xe3a119bb }, // optiboot_flash_atmega164a_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x35e2b5b6, 0xe5235996 }, // optiboot_flash_atmega164a_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x46954df9, 0x54a100b1 }, // optiboot_flash_atmega164a_UART1_38400_8000000L_B7.hex
    {  512, 0, 0x74d076c7, 0xe8287590 }, // optiboot_flash_atmega164a_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x74d076c7, 0xe8bed4e0 }, // optiboot_flash_atmega164a_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x59f8865b, 0xdf955279 }, // optiboot_flash_atmega164a_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x59f8865b, 0x0082b42c }, // optiboot_flash_atmega164a_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x404b2202 }, // optiboot_flash_atmega164a_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x65c16403 }, // optiboot_flash_atmega164a_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x46954df9, 0xb062bbd4 }, // optiboot_flash_atmega164a_UART1_115200_20000000L_B0.hex
    {  512, 0, 0x46954df9, 0x8d570578 }, // optiboot_flash_atmega164a_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x46954df9, 0xe4472d82 }, // optiboot_flash_atmega164a_UART1_115200_16000000L_B0.hex
    {  512, 0, 0x46954df9, 0x6660ce56 }, // optiboot_flash_atmega164a_UART1_115200_16000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x3e909f95 }, // optiboot_flash_atmega164a_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x98798052 }, // optiboot_flash_atmega164a_UART0_115200_16000000L_B0.hex
    {  512, 0, 0xc188885a, 0xce4f7081 }, // optiboot_flash_atmega325_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xc188885a, 0xe63cf120 }, // optiboot_flash_atmega325_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x058e72b8, 0x284da256 }, // optiboot_flash_atmega325_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xc188885a, 0xc4ec9a85 }, // optiboot_flash_atmega325_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xc188885a, 0x13d2f0ef }, // optiboot_flash_atmega325_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0xee6789c2, 0xde984e88 }, // optiboot_flash_atmega128_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xee6789c2, 0x047fffc9 }, // optiboot_flash_atmega128_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xd562886c, 0x6a2952aa }, // optiboot_flash_atmega128_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xd562886c, 0xa77e0c20 }, // optiboot_flash_atmega128_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xee6789c2, 0x09a5c098 }, // optiboot_flash_atmega128_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xd562886c, 0x604e9f9a }, // optiboot_flash_atmega128_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xee6789c2, 0xfc7070b2 }, // optiboot_flash_atmega128_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xd562886c, 0xb11bf9e2 }, // optiboot_flash_atmega128_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xee6789c2, 0xc9701422 }, // optiboot_flash_atmega128_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xd562886c, 0xc2be4e0f }, // optiboot_flash_atmega128_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4ec4df61 }, // optiboot_flash_atmega6490p_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6f542d9f }, // optiboot_flash_atmega6490p_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x66724b13 }, // optiboot_flash_atmega6490p_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x987e5f86 }, // optiboot_flash_atmega6490p_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4b132863 }, // optiboot_flash_atmega6490p_UART0_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0xb90059d5, 0x6e225cd3 }, // optiboot_flash_atmega168p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0xb90059d5, 0x8a4282f1 }, // optiboot_flash_atmega168p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x87a200aa, 0x902a90c9 }, // optiboot_flash_atmega168p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xb90059d5, 0x19ff1b96 }, // optiboot_flash_atmega168p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xb90059d5, 0x995224d3 }, // optiboot_flash_atmega168p_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0x70394fcf, 0x98fdf349 }, // optiboot_flash_atmega1284_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xd48d3fb8 }, // optiboot_flash_atmega1284_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xd4f39919 }, // optiboot_flash_atmega1284_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x8be783b2 }, // optiboot_flash_atmega1284_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x0c66f86d }, // optiboot_flash_atmega1284_UART0_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xc3c1fa0a }, // optiboot_flash_atmega1284_UART0_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x8ce72fce }, // optiboot_flash_atmega1284_UART1_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x2607dc62 }, // optiboot_flash_atmega1284_UART1_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x3163b91d }, // optiboot_flash_atmega1284_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x3ef3abf3 }, // optiboot_flash_atmega1284_UART0_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x31a00898 }, // optiboot_flash_atmega1284_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x09e6912d }, // optiboot_flash_atmega1284_UART1_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xa1de91d9 }, // optiboot_flash_atmega1284_UART1_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x433d6e94 }, // optiboot_flash_atmega1284_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x1e70b8cf }, // optiboot_flash_atmega1284_UART0_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xa3cd737c }, // optiboot_flash_atmega1284_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x18bb2f99 }, // optiboot_flash_atmega1284_UART1_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xb135ab3c }, // optiboot_flash_atmega1284_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xf4675d8b }, // optiboot_flash_atmega1284_UART0_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xd96949e5 }, // optiboot_flash_atmega1284_UART1_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0x8c6fdab4, 0x8e5d9c95 }, // optiboot_flash_atmega16_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x47fd9a23, 0x5c54fb4a }, // optiboot_flash_atmega16_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x47fd9a23, 0xf8f086f5 }, // optiboot_flash_atmega16_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x8c6fdab4, 0x57b69579 }, // optiboot_flash_atmega16_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x8c6fdab4, 0xf7dabebc }, // optiboot_flash_atmega16_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x47fd9a23, 0x4d2b24be }, // optiboot_flash_atmega16_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x8c6fdab4, 0xfb8d3b56 }, // optiboot_flash_atmega16_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x47fd9a23, 0xf417591b }, // optiboot_flash_atmega16_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x8c6fdab4, 0xfc0d86b5 }, // optiboot_flash_atmega16_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x47fd9a23, 0x9bdeeb3c }, // optiboot_flash_atmega16_UART0_115200_16000000L_B7.hex
    { 1024, 1, 0xae42ebb8, 0x270bdd64 }, // optiboot_flash_atmega64_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4c3d0b81 }, // optiboot_flash_atmega64_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x94b2a13c }, // optiboot_flash_atmega64_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4cf8b9ab }, // optiboot_flash_atmega64_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x204dbfa5 }, // optiboot_flash_atmega64_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x0774388e }, // optiboot_flash_atmega64_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xbd6f5121 }, // optiboot_flash_atmega64_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x67960f85 }, // optiboot_flash_atmega64_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x583a87ca }, // optiboot_flash_atmega64_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1462de41 }, // optiboot_flash_atmega64_UART1_115200_16000000L_B5_BIGBOOT.hex
    {  512, 0, 0x4abf9198, 0xda79c706 }, // optiboot_flash_atmega8515_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x4abf9198, 0x82098a14 }, // optiboot_flash_atmega8515_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x4abf9198, 0x3b291035 }, // optiboot_flash_atmega8515_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x4abf9198, 0xd57f0c10 }, // optiboot_flash_atmega8515_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x4abf9198, 0x0f838688 }, // optiboot_flash_atmega8515_UART0_115200_16000000L_B0.hex
    {  512, 0, 0xaa622fda, 0x4f06239c }, // optiboot_flash_atmega3290p_UART0_38400_8000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x294107c3 }, // optiboot_flash_atmega3290p_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x0626ce58, 0x211cae4c }, // optiboot_flash_atmega3290p_UART0_9600_1000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x21a0acf6 }, // optiboot_flash_atmega3290p_UART0_115200_20000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x71720261 }, // optiboot_flash_atmega3290p_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x2afe013b, 0xd5de2de6 }, // optiboot_flash_atmega169p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x2afe013b, 0x5775955f }, // optiboot_flash_atmega169p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x7de5e119, 0xecba44da }, // optiboot_flash_atmega169p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x2afe013b, 0x0ebf1682 }, // optiboot_flash_atmega169p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega169p_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0xae42ebb8, 0x97ab29d7 }, // optiboot_flash_atmega644p_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4023218f }, // optiboot_flash_atmega644p_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x94298c9c }, // optiboot_flash_atmega644p_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x27bbf745 }, // optiboot_flash_atmega644p_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x26ced1dc }, // optiboot_flash_atmega644p_UART0_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x1094e6b3 }, // optiboot_flash_atmega644p_UART0_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6d886955 }, // optiboot_flash_atmega644p_UART1_57600_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xc69f1084 }, // optiboot_flash_atmega644p_UART1_38400_8000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x796847db }, // optiboot_flash_atmega644p_UART1_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x767ff663 }, // optiboot_flash_atmega644p_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x0599449e }, // optiboot_flash_atmega644p_UART0_9600_1000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x56979720 }, // optiboot_flash_atmega644p_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x83ea01e1 }, // optiboot_flash_atmega644p_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x66c88213 }, // optiboot_flash_atmega644p_UART0_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x6897b483 }, // optiboot_flash_atmega644p_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x2eb98629 }, // optiboot_flash_atmega644p_UART1_115200_20000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x28a87902 }, // optiboot_flash_atmega644p_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x0b89845e }, // optiboot_flash_atmega644p_UART0_115200_16000000L_B0_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4d7e38df }, // optiboot_flash_atmega644p_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xc9f335c4 }, // optiboot_flash_atmega644p_UART1_115200_16000000L_B0_BIGBOOT.hex
    {  512, 0, 0x2afe013b, 0xd5de2de6 }, // optiboot_flash_atmega165_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x2afe013b, 0x5775955f }, // optiboot_flash_atmega165_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x7de5e119, 0xecba44da }, // optiboot_flash_atmega165_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x2afe013b, 0x0ebf1682 }, // optiboot_flash_atmega165_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega165_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x7426b344, 0x8785ab7e }, // optiboot_flash_atmega162_UART1_57600_8000000L_B0.hex
    {  512, 0, 0xda8d468f, 0xe903fd84 }, // optiboot_flash_atmega162_UART0_38400_8000000L_B0.hex
    {  512, 0, 0xda8d468f, 0x9859287c }, // optiboot_flash_atmega162_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x7426b344, 0x7f9312a9 }, // optiboot_flash_atmega162_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x3d2a281f, 0x1cc1dd8c }, // optiboot_flash_atmega162_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x132fb9cf, 0xb4c6e662 }, // optiboot_flash_atmega162_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x7426b344, 0xceb4839a }, // optiboot_flash_atmega162_UART1_115200_20000000L_B0.hex
    {  512, 0, 0xda8d468f, 0x747f258c }, // optiboot_flash_atmega162_UART0_115200_20000000L_B0.hex
    {  512, 0, 0xda8d468f, 0x9859287c }, // optiboot_flash_atmega162_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x7426b344, 0x8785ab7e }, // optiboot_flash_atmega162_UART1_115200_16000000L_B0.hex
    { 1024, 1, 0x5790d602, 0x3870ca19 }, // optiboot_flash_at90can32_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x09092111 }, // optiboot_flash_at90can32_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x675f40ab }, // optiboot_flash_at90can32_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x650469af }, // optiboot_flash_at90can32_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0x20e0c28b }, // optiboot_flash_at90can32_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x74b9c238, 0x4d1375ab }, // optiboot_flash_at90can32_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x141f9dd1 }, // optiboot_flash_at90can32_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x1584a240 }, // optiboot_flash_at90can32_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0x12c681d4 }, // optiboot_flash_at90can32_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x5790d602, 0xa23efbfe }, // optiboot_flash_at90can32_UART0_115200_16000000L_B5_BIGBOOT.hex
    {  512, 0, 0x2d9a8617, 0x9576f026 }, // optiboot_flash_atmega324a_UART1_57600_8000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0x1c644fb2 }, // optiboot_flash_atmega324a_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x2d9a8617, 0xb73769d1 }, // optiboot_flash_atmega324a_UART1_57600_8000000L_B0.hex
    {  512, 0, 0xeebb98c4, 0x497e8ac5 }, // optiboot_flash_atmega324a_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x2d9a8617, 0x5e488620 }, // optiboot_flash_atmega324a_UART1_38400_8000000L_B0.hex
    {  512, 0, 0xeebb98c4, 0x1e7ff2f9 }, // optiboot_flash_atmega324a_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x2d9a8617, 0xccd64c5b }, // optiboot_flash_atmega324a_UART1_38400_8000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0x0fb6694e }, // optiboot_flash_atmega324a_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x24de513c, 0xba0c877d }, // optiboot_flash_atmega324a_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x24de513c, 0x14cea2eb }, // optiboot_flash_atmega324a_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x6eb4e9a6, 0x7934547f }, // optiboot_flash_atmega324a_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x6eb4e9a6, 0x795931d0 }, // optiboot_flash_atmega324a_UART0_9600_1000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0xa22a39b9 }, // optiboot_flash_atmega324a_UART0_115200_20000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0xf23c1c01 }, // optiboot_flash_atmega324a_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x2d9a8617, 0x79726fb0 }, // optiboot_flash_atmega324a_UART1_115200_20000000L_B0.hex
    {  512, 0, 0x2d9a8617, 0xbab08ccb }, // optiboot_flash_atmega324a_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x2d9a8617, 0x6f998a26 }, // optiboot_flash_atmega324a_UART1_115200_16000000L_B0.hex
    {  512, 0, 0x2d9a8617, 0x379b94b7 }, // optiboot_flash_atmega324a_UART1_115200_16000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0xb7798c1d }, // optiboot_flash_atmega324a_UART0_115200_16000000L_B7.hex
    {  512, 0, 0xeebb98c4, 0xa3ba96e7 }, // optiboot_flash_atmega324a_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x5ccf35cb, 0x898afdb0 }, // optiboot_flash_atmega88p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x5ccf35cb, 0xf0399a23 }, // optiboot_flash_atmega88p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x42f48861, 0x8cfdfcb8 }, // optiboot_flash_atmega88p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x5ccf35cb, 0x8990a68e }, // optiboot_flash_atmega88p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x5ccf35cb, 0xa35ca98a }, // optiboot_flash_atmega88p_UART0_115200_16000000L_B5.hex
    {  512, 0, 0xc0e0c9aa, 0x2fcb09d8 }, // optiboot_flash_atmega328p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0xc0e0c9aa, 0xb15524df }, // optiboot_flash_atmega328p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xe15a32cd, 0x32d973ec }, // optiboot_flash_atmega328p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xc0e0c9aa, 0x0127527c }, // optiboot_flash_atmega328p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xc0e0c9aa, 0x2cbe3881 }, // optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0xae42ebb8, 0x0976c9ef }, // optiboot_flash_atmega649_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xa498f3ed }, // optiboot_flash_atmega649_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x064c9396 }, // optiboot_flash_atmega649_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xc42e67a3 }, // optiboot_flash_atmega649_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xb7ca22b5 }, // optiboot_flash_atmega649_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xc7d736d6 }, // optiboot_flash_atmega640_UART3_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xf1c8ea31 }, // optiboot_flash_atmega640_UART3_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x7e45b263 }, // optiboot_flash_atmega640_UART2_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xe2f5ab2b }, // optiboot_flash_atmega640_UART2_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xe279ccd5 }, // optiboot_flash_atmega640_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x7da86a27 }, // optiboot_flash_atmega640_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xa8c13596 }, // optiboot_flash_atmega640_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xcdd9bb83 }, // optiboot_flash_atmega640_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x781c56b2 }, // optiboot_flash_atmega640_UART2_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x5c86eb3f }, // optiboot_flash_atmega640_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x6abacc22 }, // optiboot_flash_atmega640_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x55c95f39 }, // optiboot_flash_atmega640_UART3_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x5df0eb9e }, // optiboot_flash_atmega640_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xa35dcc84 }, // optiboot_flash_atmega640_UART2_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x49ef04b1 }, // optiboot_flash_atmega640_UART3_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x817efbcf }, // optiboot_flash_atmega640_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x9c06346f }, // optiboot_flash_atmega640_UART2_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x507dd91e }, // optiboot_flash_atmega640_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x615a09e4 }, // optiboot_flash_atmega640_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x21b86ab9 }, // optiboot_flash_atmega640_UART3_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0xaa622fda, 0x294107c3 }, // optiboot_flash_atmega3290_UART0_57600_8000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x4f06239c }, // optiboot_flash_atmega3290_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x0626ce58, 0x211cae4c }, // optiboot_flash_atmega3290_UART0_9600_1000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x21a0acf6 }, // optiboot_flash_atmega3290_UART0_115200_20000000L_B7.hex
    {  512, 0, 0xaa622fda, 0x71720261 }, // optiboot_flash_atmega3290_UART0_115200_16000000L_B7.hex
    {  512, 0, 0xc188885a, 0xe63cf120 }, // optiboot_flash_atmega325p_UART0_38400_8000000L_B5.hex
    {  512, 0, 0xc188885a, 0xce4f7081 }, // optiboot_flash_atmega325p_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x058e72b8, 0x284da256 }, // optiboot_flash_atmega325p_UART0_9600_1000000L_B5.hex
    {  512, 0, 0xc188885a, 0xc4ec9a85 }, // optiboot_flash_atmega325p_UART0_115200_20000000L_B5.hex
    {  512, 0, 0xc188885a, 0x13d2f0ef }, // optiboot_flash_atmega325p_UART0_115200_16000000L_B5.hex
    {  512, 0, 0xe70524cd, 0x76b1e5e7 }, // optiboot_flash_atmega324pb_UART1_57600_8000000L_B7.hex
    {  512, 0, 0x0cf7e212, 0x02724086 }, // optiboot_flash_atmega324pb_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x119c8746, 0xc5b68c97 }, // optiboot_flash_atmega324pb_UART2_38400_8000000L_B7.hex
    {  512, 0, 0xe70524cd, 0x7d44fb76 }, // optiboot_flash_atmega324pb_UART1_57600_8000000L_B0.hex
    {  512, 0, 0x119c8746, 0x515f6cc8 }, // optiboot_flash_atmega324pb_UART2_38400_8000000L_B0.hex
    {  512, 0, 0x0cf7e212, 0x9fd0954e }, // optiboot_flash_atmega324pb_UART0_38400_8000000L_B7.hex
    {  512, 0, 0xe70524cd, 0x7b7220cf }, // optiboot_flash_atmega324pb_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x119c8746, 0xfa254553 }, // optiboot_flash_atmega324pb_UART2_57600_8000000L_B0.hex
    {  512, 0, 0x0cf7e212, 0x1cc4a79d }, // optiboot_flash_atmega324pb_UART0_57600_8000000L_B7.hex
    {  512, 0, 0xe70524cd, 0x73288ce3 }, // optiboot_flash_atmega324pb_UART1_38400_8000000L_B7.hex
    {  512, 0, 0x0cf7e212, 0x1cba5cf5 }, // optiboot_flash_atmega324pb_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x119c8746, 0x1bc2e50d }, // optiboot_flash_atmega324pb_UART2_57600_8000000L_B7.hex
    {  512, 0, 0x23882f25, 0xf4e3bedc }, // optiboot_flash_atmega324pb_UART2_9600_1000000L_B7.hex
    {  512, 0, 0x23882f25, 0x309c6619 }, // optiboot_flash_atmega324pb_UART2_9600_1000000L_B0.hex
    {  512, 0, 0x4eda2f7e, 0xe23050d8 }, // optiboot_flash_atmega324pb_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x4eda2f7e, 0xe571fa99 }, // optiboot_flash_atmega324pb_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x25d48eb2, 0xe5bbf4cb }, // optiboot_flash_atmega324pb_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x25d48eb2, 0x367e2797 }, // optiboot_flash_atmega324pb_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x119c8746, 0x7a7b4a0e }, // optiboot_flash_atmega324pb_UART2_115200_20000000L_B7.hex
    {  512, 0, 0x119c8746, 0x46dce88c }, // optiboot_flash_atmega324pb_UART2_115200_20000000L_B0.hex
    {  512, 0, 0xe70524cd, 0xd64392cc }, // optiboot_flash_atmega324pb_UART1_115200_20000000L_B0.hex
    {  512, 0, 0xe70524cd, 0x2c53ef72 }, // optiboot_flash_atmega324pb_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x0cf7e212, 0x151316da }, // optiboot_flash_atmega324pb_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x0cf7e212, 0x7d599f19 }, // optiboot_flash_atmega324pb_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x0cf7e212, 0x5d9ee2b8 }, // optiboot_flash_atmega324pb_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x0cf7e212, 0xd67c7167 }, // optiboot_flash_atmega324pb_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x119c8746, 0x722ccc92 }, // optiboot_flash_atmega324pb_UART2_115200_16000000L_B7.hex
    {  512, 0, 0x119c8746, 0x929de9d1 }, // optiboot_flash_atmega324pb_UART2_115200_16000000L_B0.hex
    {  512, 0, 0xe70524cd, 0x566a2f82 }, // optiboot_flash_atmega324pb_UART1_115200_16000000L_B0.hex
    {  512, 0, 0xe70524cd, 0x5fdf497d }, // optiboot_flash_atmega324pb_UART1_115200_16000000L_B7.hex
    {  512, 0, 0x76291c3d, 0xb99fa55c }, // optiboot_flash_atmega328_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x76291c3d, 0xca16f284 }, // optiboot_flash_atmega328_UART0_57600_8000000L_B5.hex
    {  512, 0, 0xe6d3ec9c, 0xf39cd12f }, // optiboot_flash_atmega328_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x76291c3d, 0xd4685bd8 }, // optiboot_flash_atmega328_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x76291c3d, 0xf983b103 }, // optiboot_flash_atmega328_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0x2f29a5a8, 0x7f45706b }, // optiboot_flash_atmega1281_UART1_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0xc5174f64 }, // optiboot_flash_atmega1281_UART1_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0xd272f5d9 }, // optiboot_flash_atmega1281_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0xe19b2f1b }, // optiboot_flash_atmega1281_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xe9fba810, 0xc4eebbbc }, // optiboot_flash_atmega1281_UART1_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xe9fba810, 0xb9923382 }, // optiboot_flash_atmega1281_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0x422c3281 }, // optiboot_flash_atmega1281_UART1_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0xcfee8326 }, // optiboot_flash_atmega1281_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0x24ae0a4a }, // optiboot_flash_atmega1281_UART1_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0x2f29a5a8, 0xcfc68538 }, // optiboot_flash_atmega1281_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x82288400 }, // optiboot_flash_atmega6450p_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xe8704cb1 }, // optiboot_flash_atmega6450p_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xb80318bc }, // optiboot_flash_atmega6450p_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x31550abd }, // optiboot_flash_atmega6450p_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x28381b17 }, // optiboot_flash_atmega6450p_UART0_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0x46954df9, 0x54a100b1 }, // optiboot_flash_atmega164p_UART1_38400_8000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0xe5235996 }, // optiboot_flash_atmega164p_UART0_57600_8000000L_B0.hex
    {  512, 0, 0x46954df9, 0xe3a119bb }, // optiboot_flash_atmega164p_UART1_38400_8000000L_B0.hex
    {  512, 0, 0x35e2b5b6, 0x390f2ade }, // optiboot_flash_atmega164p_UART0_57600_8000000L_B7.hex
    {  512, 0, 0x46954df9, 0xe5e526c7 }, // optiboot_flash_atmega164p_UART1_57600_8000000L_B0.hex
    {  512, 0, 0x35e2b5b6, 0xc38c7647 }, // optiboot_flash_atmega164p_UART0_38400_8000000L_B7.hex
    {  512, 0, 0x46954df9, 0xc307e815 }, // optiboot_flash_atmega164p_UART1_57600_8000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0xe3f2c268 }, // optiboot_flash_atmega164p_UART0_38400_8000000L_B0.hex
    {  512, 0, 0x59f8865b, 0xdf955279 }, // optiboot_flash_atmega164p_UART0_9600_1000000L_B0.hex
    {  512, 0, 0x59f8865b, 0x0082b42c }, // optiboot_flash_atmega164p_UART0_9600_1000000L_B7.hex
    {  512, 0, 0x74d076c7, 0xe8287590 }, // optiboot_flash_atmega164p_UART1_9600_1000000L_B0.hex
    {  512, 0, 0x74d076c7, 0xe8bed4e0 }, // optiboot_flash_atmega164p_UART1_9600_1000000L_B7.hex
    {  512, 0, 0x46954df9, 0xb062bbd4 }, // optiboot_flash_atmega164p_UART1_115200_20000000L_B0.hex
    {  512, 0, 0x46954df9, 0x8d570578 }, // optiboot_flash_atmega164p_UART1_115200_20000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x404b2202 }, // optiboot_flash_atmega164p_UART0_115200_20000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x65c16403 }, // optiboot_flash_atmega164p_UART0_115200_20000000L_B0.hex
    {  512, 0, 0x35e2b5b6, 0x3e909f95 }, // optiboot_flash_atmega164p_UART0_115200_16000000L_B7.hex
    {  512, 0, 0x35e2b5b6, 0x98798052 }, // optiboot_flash_atmega164p_UART0_115200_16000000L_B0.hex
    {  512, 0, 0x46954df9, 0xe4472d82 }, // optiboot_flash_atmega164p_UART1_115200_16000000L_B0.hex
    {  512, 0, 0x46954df9, 0x6660ce56 }, // optiboot_flash_atmega164p_UART1_115200_16000000L_B7.hex
    { 1024, 1, 0x70394fcf, 0x990b0718 }, // optiboot_flash_atmega1280_UART2_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xedc43871 }, // optiboot_flash_atmega1280_UART2_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xc8c6b978 }, // optiboot_flash_atmega1280_UART3_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x46efca2b }, // optiboot_flash_atmega1280_UART3_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x48da213b }, // optiboot_flash_atmega1280_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x83e33e5a }, // optiboot_flash_atmega1280_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xe8fba5b2 }, // optiboot_flash_atmega1280_UART1_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x32c02cce }, // optiboot_flash_atmega1280_UART1_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x9fb7469b }, // optiboot_flash_atmega1280_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x72d58ca6 }, // optiboot_flash_atmega1280_UART3_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0xe8d4fd48 }, // optiboot_flash_atmega1280_UART2_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x6f4a2030, 0x7e7f2a4f }, // optiboot_flash_atmega1280_UART1_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x5a177a62 }, // optiboot_flash_atmega1280_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x9f55ef91 }, // optiboot_flash_atmega1280_UART3_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x69c6037a }, // optiboot_flash_atmega1280_UART2_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x131b5a3c }, // optiboot_flash_atmega1280_UART1_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x9c8cdeb7 }, // optiboot_flash_atmega1280_UART3_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x337c346c }, // optiboot_flash_atmega1280_UART0_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0x517bae1c }, // optiboot_flash_atmega1280_UART1_115200_16000000L_B7_BIGBOOT.hex
    { 1024, 1, 0x70394fcf, 0xf25fb27c }, // optiboot_flash_atmega1280_UART2_115200_16000000L_B7_BIGBOOT.hex
    {  512, 0, 0x58b9d0f6, 0x0ac150c9 }, // optiboot_flash_atmega329_UART0_38400_8000000L_B5.hex
    {  512, 0, 0x58b9d0f6, 0x27eeb558 }, // optiboot_flash_atmega329_UART0_57600_8000000L_B5.hex
    {  512, 0, 0x203e2338, 0x7a9110b5 }, // optiboot_flash_atmega329_UART0_9600_1000000L_B5.hex
    {  512, 0, 0x58b9d0f6, 0x8d2698e6 }, // optiboot_flash_atmega329_UART0_115200_20000000L_B5.hex
    {  512, 0, 0x58b9d0f6, 0xc77803d4 }, // optiboot_flash_atmega329_UART0_115200_16000000L_B5.hex
    { 1024, 1, 0xae42ebb8, 0xed657349 }, // optiboot_flash_atmega649p_UART0_38400_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xb8d02007 }, // optiboot_flash_atmega649p_UART0_57600_8000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x4f40d9a6 }, // optiboot_flash_atmega649p_UART0_9600_1000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x28f40c94 }, // optiboot_flash_atmega649p_UART0_115200_20000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xe55392cf }, // optiboot_flash_atmega649p_UART0_115200_16000000L_B5_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x82288400 }, // optiboot_flash_atmega6450_UART0_38400_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xe8704cb1 }, // optiboot_flash_atmega6450_UART0_57600_8000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0xb80318bc }, // optiboot_flash_atmega6450_UART0_9600_1000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x31550abd }, // optiboot_flash_atmega6450_UART0_115200_20000000L_B7_BIGBOOT.hex
    { 1024, 1, 0xae42ebb8, 0x28381b17 }, // optiboot_flash_atmega6450_UART0_115200_16000000L_B7_BIGBOOT.hex

@stefanrueger
Copy link
Collaborator

stefanrueger commented Dec 18, 2022

same hash, even though they are different parts

Hash function clashes are vvv unlikely (1/4bn). The different parts will have the same signature, and therefore the bootloaders will be identical. Here one example:

$ grep 0xee9f5b33 /tmp/hash-list
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega169_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega169p_UART0_115200_16000000L_B5.hex
    {  512, 0, 0x2afe013b, 0xee9f5b33 }, // optiboot_flash_atmega165_UART0_115200_16000000L_B5.hex

My bet is that the bootloaders for these three parts are identical, and in particular that the signatures are the same. Your list has 480 different hashes. (And I very much predict your 542-strong bootloader list has only 480 unique ones.) You get the 57 hashes that occur multiple times by

$ cut -f4 -d, /tmp/hash-list  | sort | uniq -c | grep -v " 1 " | sort -n

It makes sense to keep only one representative of bootoaders that are identical (though there is no harm in having identical hashes in the list: the algorithm copes).

@stefanrueger
Copy link
Collaborator

The more important question is: which of these bootloaders have EEPROM support and which don't. The script uses the heuristic(!) that all bootloaders that have bigboot or BIGBOOT in its names cope with EEPROM (ie, get a 1 in the second column).

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 18, 2022

My bet is that the bootloaders for these three parts are identical, and in particular that the signatures are the same. Your list has 480 different hashes. (And I very much predict your 542-strong bootloader list has only 480 unique ones.) You get the 57 hashes that occur multiple times by

I realize now that I should have built these bootloaders for ATmega165A and ATmega169A instead of the non-A models. There seems to be a bug in the avr-libc version I used where the non-A parts incorrectly has the same signature values in their io.h file. I should fix this, re-build the bootloader and update the hash table

The more important question is: which of these bootloaders have EEPROM support and which don't. The script uses the heuristic(!) that all bootloaders that have bigboot or BIGBOOT in its names cope with EEPROM (ie, get a 1 in the second column).

All bootloaders that have BIGBOOT in their name support EEPROM read/write, so the script is correct.

@stefanrueger
Copy link
Collaborator

| I should fix this, re-build the bootloader and update the hash table

We had the discussion before: signatures are no good indicator for the part. So, this cannot be fixed!

Unless you switch to urboot that is. 😀

And for good measure, signatures can be different between avr-libc and avrdude.

@stefanrueger
Copy link
Collaborator

@MCUdude I've been wondering why your (8 MHz, 57600 baud) bootloaders are different from (16 MHz, 115200 baud) bootloaders, but I now suspect that optiboot flashes the LED for a while with a certain frequency - and that therefore the code will be different for these two bootloader versions. For the comms alone the code would be identical.

@stefanrueger stefanrueger changed the title Behavior of Optiboot firmware without EEPROM capability when reading eeprom Optiboot without EEPROM support returns flash on EEPROM request Dec 19, 2022
@stefanrueger stefanrueger added wontfix This will not be worked on and removed question Further information is requested labels Dec 19, 2022
@mcuee
Copy link
Collaborator Author

mcuee commented Dec 19, 2022

I agree with change the lable to wontfix. We can keep this issue open for a while and then close it.

We can even create a FAQ Wiki page to include information like this one.

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 19, 2022

This is a well-known optiboot bug. It returns flash for EEPROM if optiboot has been compiled to not handle EEPROM. This bug has been around for a long time (and possibly still is today but defo was 2016 when I last looked closely at optiboot).

I can confirm the issue is still there with latest optiboot git.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c urclock -P COM4 -p m328p -xbootsize=512 -xshowall

avrdude: AVR device initialized and ready to accept instructions
0 2022-06-10 21.21 Blink.ino.standard.hex 924 store 31298 meta 34 boot 512 o8.3 -?s-?-r-- vector 0 (RESET) ATmega328P

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c arduino -P COM4 -p m328p -qqt
avrdude> dump eeprom 0 0x10
0000  0c 94 5c 00 0c 94 6e 00  0c 94 6e 00 0c 94 6e 00  | .\. .n. .n. .n.|

avrdude>
avrdude>
PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c usbasp -p m328p -qqt
avrdude> dump eeprom 0 0x10
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude>
avrdude>

I consider this as a serious bug of optiboot. The only saving grace is that writing to EEPROM will fail.

PS C:\work\avr\avrdude_test\avrdude_bin> echo "write eeprom 0 0xaa 0x55" | .\avrdude -c arduino -P COM4 -p m328p -qqt
avrdude> write eeprom 0 0xaa 0x55
avrdude>
avrdude> avrdude error: programmer is not responding
(CTRL-C to exit)

PS C:\work\avr\avrdude_test\avrdude_bin> echo "dump eeprom 0 0x10" | .\avrdude -c usbasp -p m328p -qqt
avrdude> dump eeprom 0 0x10
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude>
avrdude>

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 19, 2022

@WestfW
Just wondering if you have any intentions to fix this paticular optiboot bug. Thanks.

@MCUdude and @SpenceKonde
Just wondering if you know this bug or not. I consider it as a serious bug.

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 19, 2022

We had the discussion before: #1091 (comment). So, this cannot be fixed!

Signatures aren't the best, I agree. Atmel is to blame here for their inconsistency. However, in my case, uploading to an ATmega169A will fail, because the signature hardcoded into the device differs from the one in the bootloader. I'll ditch the non-A parts for now. I'm doing this because I want a last "known-good" MegaCore release before migrating everything to Urboot.

Just wondering if you know this bug or not. I consider it as a serious bug.

I wasn't aware of it, but since Arduino IDE doesn't support uploading directly to EEPROM, it has never really been an issue. If I'm going to switch to Urboot later, I don't think I'll bother fixing it and compiling all new hex files.

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 19, 2022

I wasn't aware of it, but since Arduino IDE doesn't support uploading directly to EEPROM, it has never really been an issue.

Ah, that explains why this issue was not noticed for so long.

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 20, 2022

Optiboot/optiboot#357 raised against Optiboot.

@mcuee mcuee closed this as completed Dec 20, 2022
@mcuee
Copy link
Collaborator Author

mcuee commented Dec 20, 2022

Re-open this issue so that we can continue which hash to be included in avrdude.

@mcuee mcuee reopened this Dec 20, 2022
@SpenceKonde
Copy link

@MCUdude: What is this "Urboot" thing"?

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 20, 2022

@SpenceKonde
It is here.
https://github.com/stefanrueger/urboot

I am thinking it may be useful for your ATTinyCore.

In paticular, it may be the ultimate fix for the issue you raised against Optiboot.

But @stefanrueger and @MCUdude may be able to give you better perspectives about switching from Optiboot to urboot.

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 20, 2022

@SpenceKonde It's a new bootloader written together with the Avrdude implementation of the protocol. It has all the bells and whistles you might dream of (Only for classic AVRs for now), and it occupies very little flash space. The virtual bootloaders are very interesting and are impossible to brick as long as you don't wipe or modify the flash contents with an ISP programmer.

It lets you:

  • Read and write to flash and EEPROM using -U flash or -U eeprom
  • Read and write single bytes to flash and EEPROM in Avrdude terminal mode -t
  • Stores metadata of your program, like flashing date, program name, and size.
  • For virtual bootloaders, Avrdude uploads a patched version of the user program to ensure there always is a reset vector present
  • Supports auto baud, with no upper limit other than the AVR clock speed.
  • Option to make it backward compatible with -c arduino
  • plus more

More about the Urboot bootloader here: https://github.com/stefanrueger/urboot/blob/b068ad0a16ac6e11690a72172c43ef689c8b8425/src/urboot.c#L1-L709

More about the Avrdude protocol implementation (Urclock) and what it supports here:
#1171

The Avrdude docs (avrdude.texi and avrdude.1) also contain lots of information.

Bottom line: It's an incredibly feature-rich and packed bootloader designed around a custom protocol specifically for bootloader usage. It's an impressive piece of software, and I'm planning to migrate all my Arduino cores to use Urboot and ditch Optiboot completely. And for ATtinyCore where lots of parts use virtual bootloaders, It's a no-brainer.

@MCUdude
Copy link
Collaborator

MCUdude commented Dec 20, 2022

From urboot.c:

* Feature-rich bootloader that is fast and small
 *  - Tight code: most bootloaders fit into 256 bytes
 *  - Highly modular feature set:
 *     + Dedicated protocol between programmer and bootloader (urprotocol)
 *     + EEPROM read/write support
 *     + Vector bootloader for devices without a boot section or to save space on devices with one
 *     + Software UART: no hardware UART required, but also useful when the chip's CPU frequency
 *       and the bootloader's desired baud rate are incompatible (eg, 8 MHz and 115,200 baud)
 *     + Subroutine pgm_write_page(sram, progmem) for applications so they can change themselves:
 *       on many MCUs the SPM write flash only works when called from the bootloader section
 *     + Dual programming from external SPI flash memory for over-the-air programming
 *     + Template bootloader with nops that will be replaced "on the fly" with code to manipulate
 *       the right LED/TX/RX/CS pins at bootloader-burning time (see accompanying urloader sketch)
 *     + Saves the reset flags in R2 for inspection by the application via the .init0 section
 *     + Bootloader protects itself from overwriting
 *     + Automatic host baud rate detection
 *     + Chip erase in bootloader (faster than -c urclock emulation)
 *
* How the bootloader works
 *   In common with bootloaders, it runs after every reset and tries to communicate with an
 *   external uploader program via a serial interface using a variant of the STK500v1 protocol.
 *   Hence, only the serial I/O needs to be connected from a Raspberry Pi/PC/laptop host to the
 *   board with the to-be-programmed MCU on it. After every reset the bootloader code determines
 *   its cause: if that was an external reset as opposed to power-up reset or watchdog timeout
 *   (WDT) it waits a small time for protocol initialisation bytes from an uploader program. If
 *   there was was a valid handshake, the bootloader carries out one of several possible tasks
 *   driven by the host's uploader such as receiving and burning a new sketch, downloading an
 *   existing sketch on the MCU, and, if compiled for it, reading or writing the EEPROM on the MCU.
 *   The bootloader finishes this part typically through a watchdog timeout reset that kicks in
 *   when initially no valid handshake could be detected, when a serial hardware or protocol error
 *   occurred during burning/verification or when the bootloader finished its task successfully.
 *   Watchdog timeout resets the MCU just like an external reset. When the bootloader is entered
 *   under this condition, though, it then normally jumps directly to the application. However,
 *   when the bootloader was compiled with dual-boot support, it first checks external SPI flash
 *   memory to see it contains a new sketch, in which case a copy of it is burned from external
 *   memory onto internal flash. The idea is that the application sketch could have been written to
 *   receive a new version via a radio and have placed it onto the external SPI flash memory before
 *   issuing a WDT reset. Hence, this dual-boot property is also called over the air programming,
 *   although one could conceivably also plug a new external SPI flash into a board for
 *   programming.
 *
 *
 * Assumptions, limitations and caveats of *any* bootloader
 *
 *   - Establishing communication invariably causes some small startup delay on external reset.
 *
 *   - For bootloaders on ISP MCUs there is no need for a physical programmer, though in order to
 *     burn the bootloader itself onto the MCU, an SPI header and an SPI programmer is needed at
 *     least once in the beginning. Burning the bootloader using SPI necessitates the MCU be in
 *     reset mode: all chip select lines of attached SPI hardware (external flash memory, radios
 *     etc) need therefore be pulled high through resistors to ensure all external SPI devices are
 *     inactive during SPI programming of the bootloader.
 *
 *   - In most cases the connection from the PC for uploading sketches via the bootloader will be
 *     through USB, which necessitates a USB to serial converter cable if the destination board
 *     does not have USB. Some PCs (most notably, the Raspberry Pi) have a native serial connection
 *     that also could be used for connecting to a board without USB.
 *
 *   - The bootloader sets the TX line of the UART or the designated TX pin of the software serial
 *     communication to output after every reset. If the bootloader is compiled to blink an LED, to
 *     output a square wave for debugging or to communicate via SPI with external memory for dual
 *     programming, there will be other lines that are set to output shortly after each reset. Not
 *     all projects can deal gracefully with these short flares of output activity on some of the
 *     pins. If you use a bootloader for production settings it is best to carefully consider the
 *     hardware implications on the circuit.
 *
 *   - As with all bootloaders they work best when the host has a way to reset the board, which is
 *     typically done via DTR/RTS lines of the host's serial port. Avrdude -c [arduino|urclock]
 *     does this automatically. The board needs to have hardware to facilitate the DTR/RTS
 *     connection for reset. Most boards do. If not, sometimes running a small dedicated reset
 *     program on the host just before running avrdude helps. This reset program somehow needs to
 *     pull the board's reset line low for a short time; on a Raspberry Pi external GPIO pins can
 *     be used for that. If that is not possible either, then setting the watchdog timeout to a
 *     long time (see the WDTO option below) may be helpful, so one can manually reset the board
 *     before calling avrdude. The default for the timeout is 500 ms. Only with the urclock
 *     programmer can smaller timeouts down to 128 ms be reliably utilised.
 *
 *
 * Assumptions, limitations, caveats, tips and tricks for *this* bootloader
 *
 *   - The uploading program is assumed to be avrdude with either the arduino or urclock
 *     programmer: call avrdude -c [arduino|urclock] for this. I have not tested other uploaders.
 *     The tightest bootloader code (see URPROTOCOL=1 option below) requires avrdude's urclock
 *     programmer as this forgoes some get/put parameter calls that arduino issues unnecessarily
 *     and uses its own leaner protocol.
 *
 *   - A bootloader with dual-boot support needs to know which port pin is assigned to the chip
 *     select of the SPI flash memory, which pin drives a blinking LED (if wanted), where the tx/rx
 *     lines are for serial communication, how long the watchdog timeout should be etc. This
 *     explodes the option space for this bootloader. Using the accompanying urloader sketch for
 *     burning this bootloader onto a board mitigates this somewhat by the use of "template"
 *     bootloaders (see TEMPLATE option). Urloader lets you interactively set at bootloader burn
 *     time which pins it should set/clear for LED, chip select, and RX/TX (for software serial
 *     I/O). Urloader knows some common boards and offers the right bootloaders for them.
 *
 *   - Remember that dual-boot bootloaders communicate with the SPI flash memory at all external
 *     and WDT resets. Therefore, all other attached SPI devices need their chip select pulled
 *     high. While in theory urboot.c could be changed so that it uses software pullup for these
 *     additional devices, this could cost additional code and will complicate the already too big
 *     option space. It is better practice to use hardware pullups in the board design.
 *
 *   - A dual-boot bootloader deals gracefully with a board that has no external SPI flash memory:
 *     it simply reads 0xff values and decides there is nothing interesting there. However, this
 *     causes unnecessary delay at each external reset and each WDT reset, and it toggles the SPI
 *     and chip select lines (see above); it is therefore not recommended to burn the most-feature
 *     rich urboot bootloader onto all your boards. Carefully determine what you actually need.
 *
 *   - When using external SPI memory on a board with a dual-boot bootloader, remember to reserve
 *     the first FLASHEND+1 bytes exclusively for sketches to be burned onto the MCU. These are
 *     recognised by the second byte being indicative of an rjmp or a jmp opcode. Placing  some
 *     random data in that area risks the MCU being programmed with just these random data.
 *
 *   - Vector bootloaders are great for devices with no dedicated boot section. They assume
 *       + the vector table of the MCU, and therefore the reset vector, resides at address zero
 *       + the compiler puts either a jmp or an rjmp at address zero
 *       + the compiler does not zap/shorten the vector table if no or few interrupts are used
 *       + the compiler does not utilise unused interrupt vectors to place code there
 *
 *     This should be the case with all regular sketches produced by avr-gcc. Vector bootloaders
 *     are also useful for devices with boot section support to allow them to use less space than
 *     the smallest offered hardware-supported boot section. In this case ensure that the fuses are
 *     set to make the processor jump to the reset vector as opposed to the bootloader. And ensure
 *     that the protection bits in the lock byte actually allow code be written into the bootloader
 *     section with SPM instructions. Otherwise the extra space in the boot section that is freed
 *     by smaller vector bootloaders cannot be used. The urloader sketch sets fuses and lock bits
 *     appropriately when burning a vector bootloader onto your board. More on VBLs below.
 *
 *   - The code makes several assumptions that reduce the code size (eg, no interrupts can occur,
 *     SP points to RAMEND). They are true after a hardware reset, but will not necessarily be true
 *     if the bootloader is called directly. So don't.

@mcuee
Copy link
Collaborator Author

mcuee commented Dec 21, 2022

Re-open this issue so that we can continue which hash to be included in avrdude.

That has been addressed in PR #1226.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

4 participants