Small Serial Bootloader?

Short & Sweet Bootloader?

Somewhat Smaller Bootloader?

I got tired of fiddling with the available bootloaders for the Atmel ATmega8 chip and wrote my own. This bootloader is designed to be small (fit in the smallest configurable boot block) but still support reasonably fast programming over a serial line.

Most other bootloaders seem to be imitating an existing device programmer. SSBL doesn't take that approach; it tries to supply a small set of primitive operations using which the host can program the device. Most of the programming algorithm is therefore carried out by the host instead of by the bootloader.




I've published two versions of this; version two is slightly cleaned up (especially the driver program) but doesn't include precompiled .hex files.
  1. (10329 bytes, sha1 sum 283f394d4869d3880f7a14c3691556da29251bcf)
  2. (10202 bytes, sha1 sum ae9fcf4296d21cb0555cd31041bb043b35aa0c47)

SSBL serial protocol

Subject to change with changing revisions of the bootloader.

Each command is one character, possibly followed by data. Data is sent in hexadecimal. The bootloader responds to unrecognized characters with a question mark. When waiting for a command, the bootloader sends a CR (ascii 0x0D). The exception to this is the 'p' command, which does not send a CR when it finishes.

Hex digits may use either uppercase or lowercase letters. (SSBL always responds with uppercase letters). Whitespace or other characters in hex strings sent to SSBL are not allowed and will cause an error (see below).

When the bootloader starts, it prints 'ok' followed by a CR.

Communication is at 9600 bps, 8N2.

Command 'p' (0x70)
Returns an 's' (0x73), without a trailing CR. This is used to help distinguish an SSBL bootloader from an avr910, butterfly, or the like.
Command 'z' (0x7A)
Followed by four hex digits, loads the Z-register with the specified value.
Command 'R' (0x52)
Followed by two hex digits, which are interpreted as a byte count. Reads program memory starting at the location pointed to by the Z register, and returns contents in hexadecimal. The Z register is advanced by the amount read. A value of 00 will cause 256 bytes to be read.
Command 'W' (0x57)
Writes to program memory. The command character is followed by a word count (not a byte count as in 'R'). That many words are read, and stored into program memory at the location pointed to by the Z register. The Z register is advanced accordingly. This command does not perform a full program sequence. The programmer will need to use the 'P' command to complete the programming operation, and will need to be aware of the page structure of the target chip.
Command 'P' (0x50)
Reads one word into R0:R1, then one byte into SPMCR, then executes an SPM instruction.
Command 'L' (0x52)
Reads one byte into SPMCR, then executes an LPM instruction. (The host will want to set up the Z register beforehand.) The value loaded by LPM is returned to the host.
Command 'Q' (0x51)
Sends some state information back to the host. This might eventually be used to identify the version of SSBL. Sends a 'z', followed by the contents of the Z register; then a 'b', followed by the address of the start of the bootloader.
Command '@' (0x40)
Performs an ICALL, transferring control to the address in the Z register. This is useful for jumping to address 0 to start a loaded program, but could also be used to call a utility routine.
Unrecognized commands, or unexpected (non-hexadecimal) charcters in a command argument, cause SSBL to return a question mark (0x3F), followed by the usual CR and waiting for a new command.


Eventually, the idea is, there will be a couple of #defines which will let you build SSBL as either a minimal bootloader (capable of loading program memory and not much else), or a slightly more full featured boot loader, capable of writing to data EEPROM as well. The minimal boot loader will be able to fit into the smallest configurable boot block on the mega8. The current feature set is approximately what I want from the minimal configuration, but it's just a little too large to fit in the smallest boot block. I need to optimize it a little.

Also, right now the bootloader checks PORTD.4 and if it's pulled low, it jumps directly to 0x0000 in order to imitate a chip whose BOOTRST fuse is not set. This needs to be configurable, I guess.

Python driver

[Talk a little about, the host-side part of the bootloader. (Reads an Intel Hex file and writes it to the target chip.)]
$Header: /home/wiml/www-cvs/wiml/proj/avr/ssbl.html,v 1.6 2011/03/19 05:28:48 wiml Exp $my web pagesmail me