The Arduino bootloader is a small program burnt into the ATmega’s flash memory, which enables sketches to be uploaded without the use of an external programming board. Any new ATmega8/168/328p microprocessor needs to be programmed with a version of the Arduino bootloader firmware before it can be used with the Arduino IDE.
Many places sell ATmega chips with the Arduino bootloader pre-loaded. To actually burn the bootloader yourself, you do need an external programmer. Fear not though – in a previous post, I discovered how to use an Arduino board (together with the mega-isp project) as a make-shift external programmer -> see this post for details.
Putting the Boot-in..
The version of the bootloader that you need to use, depends on the type of hardware that you intend to program. The Arduino IDE supplies versions of the bootloader for a range of ATmega / Arduino combinations .. see the ‘./hardware/bootloaders/’ sub-directory within your arduino installation directory for more info.
There are also custom versions of the bootloader created by third-parties -> ladyada has produced some bootloader hacks and another unified version of the bootloader can be found here.

Atmel's ATmega8 microprocessor
Once you’ve decided which bootloader you want to use, you can use AVRdude to upload the code.
Steps Required to Burn the Bootloader
- Unlock the bootloader segment
- Upload the bootloader code
- Relock the bootloader segment
Step 1: Unlock
First of all, it’s a good idea to make sure that you can communicate with your programmer successfully. To do so, you can issue a simple command via AVRdude, which will give you a nice ‘all clear’ status message as long as everything is set-up correctly.
The parameters that you use might vary according to your system settings and the external programmer you’re using.
avrdude -p m8 -P /dev/ttyUSB0 -c avrisp -b 19200
Briefly, ‘-p’ defines the chip I’m programming, ‘-P’ is the port that my programmer is connected to, ‘-c’ is the programmer type and the baud-rate is specified by ‘-b’. You can run ‘avrdude –help’ to discover the full range of options.
This returned:
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.13s avrdude: Device signature = 0x1e9307 avrdude: safemode: Fuses OK avrdude done. Thank you.
.. which is good. This means that the stage is set for programming and we can begin to set the fuses to unlock the bootloader segment of the AVRdude.
Each ATmega chip has a number of Fuses which can be set. I think of the fuses as configuration bits -> they define the way that the chip is going to function on a very low level. I’ve been using a fuse-calculator to simplify the process, and I’d suggest that you do the same.
avrdude -p m8 -P /dev/ttyUSB0 -c avrisp -b 19200 -e -U lock:w:0x3F:m -U lfuse:w:0xc4:m -U hfuse:w:0xd9:m
The ‘-U lock:w:0x3F:m’ performs the unlock and ‘-U lfuse:w:0xc4:m -U hfuse:w:0xd9:m’ is used to set the chip’s low and high fuse values.
I want to use this particular ATmega chip as a minimal Arduino, so I’ve set the fuses to instruct the chip to use it’s own internal 8 MHz oscillator rather than an external crystal oscillator.
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.13s avrdude: Device signature = 0x1e9307 avrdude: erasing chip avrdude: reading input file "0xc4" avrdude: writing lfuse (1 bytes): Writing | ################################################## | 100% 0.04s avrdude: 1 bytes of lfuse written avrdude: verifying lfuse memory against 0xc4: avrdude: load data lfuse data from input file 0xc4: avrdude: input file 0xc4 contains 1 bytes avrdude: reading on-chip lfuse data: Reading | ################################################## | 100% 0.04s avrdude: verifying ... avrdude: 1 bytes of lfuse verified avrdude: reading input file "0xd9" avrdude: writing hfuse (1 bytes): Writing | ################################################## | 100% 0.04s avrdude: 1 bytes of hfuse written avrdude: verifying hfuse memory against 0xd9: avrdude: load data hfuse data from input file 0xd9: avrdude: input file 0xd9 contains 1 bytes avrdude: reading on-chip hfuse data: Reading | ################################################## | 100% 0.04s avrdude: verifying ... avrdude: 1 bytes of hfuse verified avrdude: safemode: Fuses OK avrdude done. Thank you.
Step 2: The Burn
The chip has now been set up – the next stage involves uploading the new firmware.
avrdude -p m8 -P /dev/ttyUSB0 -c avrisp -b 19200 -D -U flash:w:/opt/arduino/hardware/bootloaders/atmega8/ATmegaBOOT.hex
… which produces …
Step 3: Re-lock
The final stage involves re-setting the lock fuse:
avrdude -p m8 -P /dev/ttyUSB0 -c avrisp -b 19200 -U lock:w:0x0F:m
And that’s it!
2 Comments
None of your commands contain the ‘-U lock:w:0×3F:m’ to unlock the fuses. You mention it, but it’s not on the command line.
@Michael;
Thanks very much for the heads up
I’ve added the parameter to the code block.
One Trackback
[...] http://ntsdt.net/2009/08/22/burning-the-arduino-bootloader/ [...]