A Very Basic Question on BootLoaders

Hello again.

I have been a computer trainer and developer for quite a while now and probably this is why I have got myself confused on the concept of BootLoaders. reason being - in computers, a BootLoader for different operating systems is different.

I find that there are Bootloaded ATMEGA 328P available online. Now if someone buys one of these (or even say, I bootload one of those using Arduino UNO), how different will it be for the program written for Nano?

I might sound confusing, so here is an example scenario -

  1. I burn a bootloader on ATMEGA 328P using Arduino UNO v3.
  2. I use Arduino Nano to compile and upload a piece of code onto this chip - because Nano has a few more pins (than UNO) that my program uses.
  3. Then I use this programmed chip in my Project(s).


  1. Will that be all good - I mean, will the program work?
  2. If not, how do you determine what version of BootLoader is installed on those pre-bootloader installed ATMEGA 328Ps.

Thank you people for being around and helping us (beginners and others as well) around.

Stay safe.

in computers, a BootLoader for different operating systems is different.

I don’t see how it’s different. Yeah, the bootloader of ye olde mainframe might have gotten loaded by paper tape or front panel switches, rather than having a special section of non-volatile memory, but the principles are the same.

On the “core” AVR arduinos (Uno, Nano) the bootloader support puts a non-intrustive bootloader at the end of flash memory, and sketches don’t need to be aware that it’s there at all. (theoretically. There are still bootloaders “in the wild” that can interfere with the use of the watchdog timer.) That means that you can upload Uno code to a Nano, or Nano code to an Uno, even if they’re running different bootloaders.

On many newer chips (SAMD, atmega4809, avrNNNdaXXX) the bootloader is located at the beginning of memory instead of the end, and the application needs to be compiled to locate itself AFTER the space occupied by the bootloader. Which I find annoying, but is not a huge deal. The application still doesn’t need to know WHICH bootloader is there; it just needs to know where the bootloader expects it to be. (and the upload program needs to know what communications protocols it runs.)

how do you determine what version of BootLoader is installed on those pre-bootloader installed ATMEGA 328Ps.

Hopefully, the vendor tells you. Ha ha.

There are essentially two bootloaders common use in the Arduino community for ATmega328, each of which has several versions floating around.

  • “ATmegaBoot” - the original (pre-Uno) bootloader, used until recently on most Nano and “Pro mini” type systems. This occupies 2k and runs the UART at 57600bps. There are a couple of modifications floating around - the Adafruit “fast start” code, WDT fixes or breakage, etc.
  • “Optiboot” - initially appearing on the Arduino Uno, this occupies 512 bytes and runs the UART at 115200bps. Recently, this has been installed on (official) Nanos as well. This actually returns a version number that will show up in verbose logging:
avrdude: Version 6.3-20190619
         Firmware Version: 8.1

Arduino is still using version 4.4, but you can get “additional features” by installing a new version from one of the 3rd party cores (MCUDude’s “Minicore”, for m328p.) Most of the changes are internal, allowing optiboot to support additional chips, build options, or newer compilers. But recent “relevant” features include:

  • passing startup cause to the application (several iterations of this!)
  • allowing access to a flash programming “service” - if you need this, you really need it.
  • cause EEPROM writes to fail, rather than doing “the wrong thing.”

See https://github.com/Optiboot/optiboot

The Chinese Arduinos seem to be especially likely to be running a “mysterious” version of the bootloader. Presumably some .hex file from some Arduino distribution, cloned and shared till no one knows where it originated.

A device programmer can read the fuses to determine what size bootloader is supposed to be loaded, and then it can read the actual bootloader code, which can be compared against “known” binaries. Theoretically, anyway.

Thanks westfw,

I enjoyed reading your brief summary of bootloader development. It puts everything in context. I didn't know much about Optiboot and its relationship to the ATmegaBoot.