Optiboot Issue - avrdude: ERROR: address 0x8010 out of range

I'm posting this just as a PSA since I spent a few hours tracking down this issue. I compiled the Optiboot bootloader that came with the v1.8.9 Arduino distribution using the internal compiler and toolchain. When I tried to load the bootloader via avrdude, I got the following error:

avrdude: ERROR: address 0x8010 out of range ...

The problem is a combination of Optiboot requiring more space and the makefile not changing to accomodate this. In the makefile, when you create a board, you will have this line:

NAMEOFYOURBOARD: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe

In the linker directive, the .text is allocated space between 0x7e00 and 0x7ffe. If it doesn't fit (and it didn't), you will get the out of range error. In this case, the code compiled and went up to 0x8010. The fix is to change the .text start location in the linker directive:

NAMEOFYOURBOARD: LDSECTIONS = -Wl,--section-start=.text=0x7d00 -Wl,--section-start=.version=0x7ffe

In this case, I gave it an extra 0x100 or 256 bytes. With this modification, everything fits in it's allocated space and avrdude is happy.

Hope this helps anyone else that runs into this issue.
Cheers.
Akiba
FreakLabs

Also I'm posting it here because I'm sure I'll inevitably run into the same problem 6 months from now and google how to solve it. So it's the past me telling the future me how to fix this problem :slight_smile:

it is better to use the current version of Optiboot, which fits into 512 kB.

Agreed. You should always get things from the source. But if you use the Arduino distro and are scratching your head on why the compiled boot loader doesn’t work? There’s your answer.

Your fix is insufficient; it doesn’t change the boot start address fuses.

Yes, that's correct and thanks for pointing that out. Actually the boot start address is dependent on the boot flash section size. The Arduino Uno is set to a default of 256 words bytes which means the bootloader flash start address starts at word address 0x3F00 or byte address 0x7E00. Hence that's where that address comes from in the makefile. Setting the bootloader size for anything larger than 256 words bytes and then modifying the makefile's bootloader's section-start directive to match would be fine. So to amend my previous post, the correct way to modify it would be to select the bootloader size setting. Anything above 256 words would do.
Here's a quick reference:

  • For 512 words, the section start would be 0x7C00 (0x3E00 x 2)
  • For 1024 words, the section start would be 0x7800 (0x3C00 x 2)
  • For 2048 words, the section start would be 0x7000 (0x3800 x 2)

And the table from the datasheet for reference.

That modification would allow you to fit the default Arduino optiboot, as well as if you need to add anything additional to the bootloader.
Thanks for the tip, westfw.

Akiba
FreakLabs

256 words. A famous ambiguity between the Atmel data sheets and the Gnu toolchains (and common usage.)

Updated. Thanks for that.

so you would loose 512 bytes of flash. get Optiboot 8, with MiniCore or from the Optiboot GitHub repo. there is no reason to deal with that old version.

In addition to fitting in 512 bytes even with the current compilers, the newer versions of Optiboot have new options, new targets, and a new makefile structure that makes it a lot easier to build customized versions from the source. For example, you can say things like:

make mega2560 UART=3 BAUD_RATE=1000000