Optiboot / optiboot

Small and Fast Bootloader for Arduino and other Atmel AVR chips
Other
1.08k stars 396 forks source link

The jump destination of the patched reset vector is off one word. #275

Closed ngkz closed 4 years ago

ngkz commented 4 years ago

RJMP k means jump to PC + 1 + k, not PC + k. You forgot to subtract one from operand when patching reset vector. Because of this, the first instruction of main() won't execute when flash size is <8K and using virtual boot partition.

WestfW commented 4 years ago

Huh. You mean main() of optiboot itself, right?

ngkz commented 4 years ago

Huh. You mean main() of optiboot itself, right?

Yes

WestfW commented 4 years ago

Confirmed. :-( This plays out differently than I expected. With a current Optiboot, there are vectors at the beginning of the bootload to implement either the "normal" bootloader function, or to implement the do_spm functionality. I was expecting that the reset would send the code in do_spm instead of the bootloader, which would have given you a chip that wouldn't bootload at all.

However, there is a 2nd bug - the kludged vectors are computed (incorrectly, as noted here) based on the address of main() in the bootloader, which is AFTER the bootloader vectors, when it should be computer (now) based on premain() (or perhaps on the section start address.) This means that after reset we'll vector to main+1, rather than to the very start of the bootloader.

The first instruction (that will be skipped) is currently the zeroing of R1. R1 is USUALLY zero anyway (if you're running an Arduino sketch), so USUALLY an upload will work correctly in spite of skipping the instruction. But this means the return of https://github.com/Optiboot/optiboot/issues/26 (where if you have a running sketch that does a lot of multiplies, uploads will fail.)

WestfW commented 4 years ago

Testing welcome... Version bumped to 8.1

ngkz commented 4 years ago

I confirmed that the bug fixed. (Tested with ATTiny85)

       0:       df ce           rjmp    .-578           ;  0x1dc0
    1dc0:       01 c0           rjmp    .+2             ;  0x1dc4
    1dc2:       0d c1           rjmp    .+538           ;  0x1fde
    1dc4:       11 24           eor     r1, r1