LUFA Library - Mass Storage Class Bootloader
Mass Storage Class USB AVR Bootloader

Demo Compatibility:

The following list indicates what microcontrollers are compatible with this demo.

USB Information:

The following table gives a rundown of the USB utilization of this demo.

USB Mode: Device
USB Class: Mass Storage Device
USB Subclass: Bulk-Only Transport
Relevant Standards: USBIF Mass Storage Standard
USB Bulk-Only Transport Standard
SCSI Primary Commands Specification
SCSI Block Commands Specification
Supported USB Speeds: Full Speed Mode

Project Description:

This bootloader enumerates to the host as a Mass Storage device, capable of reading and writing a new binary firmware image file, to load firmware onto the AVR.

Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit into 6KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.

When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the bootloader from the normal user application.

Warning
THIS BOOTLOADER IS NOT SECURE. Malicious entities can recover written data, even if the device lockbits are set.

Driver Installation

This bootloader uses the Mass Storage drivers inbuilt into all modern operating systems, thus no additional drivers need to be supplied for correct operation.

Host Controller Application

This bootloader is compatible with all operating systems that support the FAT12 file system format. To reprogram the device, overwrite a file stored on the virtual FAT filesystem with a new binary (BIN format) image. Remember to safely remove your device from the host using the host OS's ejection APIs, to ensure all data is correctly flushed to the bootloader's virtual filesystem and not cached in the OS's file system driver.

The current device firmware can be read from the device by reading a file from the virtual FAT filesystem.

Warning
This bootloader is currently incompatible with the Apple MacOS X OS Finder GUI, due to the large amount of meta files this OS attempts to write to the disk along with the new binaries. On this platform, firmwares must be copied to the disk via the Terminal application only to prevent firmware corruption.

User Application API

Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, allowing the user application to call into the bootloader at runtime to read and write FLASH data.

By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the following layout:

#define BOOTLOADER_API_TABLE_SIZE 32
#define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
#define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
#define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
#define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
#define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
#define BOOTLOADER_MASS_STORAGE_SIGNATURE 0xDF30
#define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
#define BOOTLOADER_ADDRESS_LENGTH 4

From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader can be determined by reading the FLASH memory bytes located at address BOOTLOADER_CLASS_SIGNATURE_START and comparing them to the value BOOTLOADER_MASS_STORAGE_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH memory starting from address BOOTLOADER_ADDRESS_START.

Auxiliary Bootloader Section

To make the bootloader function on smaller devices (those with a physical bootloader section of smaller than 6KB) a second section of memory (called the Auxiliary Bootloader Section) is added before the start of the real bootloader section, and is filled with a portion of the bootloader code. This allows smaller devices to run the bootloader, at the cost of an additional portion of the device's FLASH (the bootloader section size in KB subtracted from the 6KB total size). A small trampoline is inserted at the start of the auxiliary section so that the bootloader will run normally in the case of a blank application section.

On devices supporting a 8KB bootloader section size, the AUX section is not created in the final binary.

Device Memory Map

The following illustration indicates the final memory map of the device when loaded with the bootloader.

*  +----------------------------+ 0x0000
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |      User Application      |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE
*  | Booloader Start Trampoline |
*  | (Not User App. Accessible) |
*  +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + 4
*  |                            |
*  |     Auxiliary Bootloader   |
*  |  Space for Smaller Devices |
*  | (Not User App. Accessible) |
*  |                            |
*  +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
*  |                            |
*  |   Bootloader Application   |
*  | (Not User App. Accessible) |
*  |                            |
*  +----------------------------+ FLASHEND - 96
*  |   API Table Trampolines    |
*  | (Not User App. Accessible) |
*  +----------------------------+ FLASHEND - 32
*  |    Bootloader API Table    |
*  |   (User App. Accessible)   |
*  +----------------------------+ FLASHEND - 8
*  |   Bootloader ID Constants  |
*  |   (User App. Accessible)   |
*  +----------------------------+ FLASHEND
*  

Known Issues:

In some cases, the application is not fully loaded into the device.
Write-caching on some operating systems may interfere with the normal operation of the bootloader. Write caching should be disabled when using the Mass Storage bootloader, or the file system synced via an appropriate command (such as the OS's normal disk ejection command) before disconnecting the device.
After loading an application, it is not run automatically on startup.
Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader to run automatically when the device is reset. In most cases, the BOOTRST fuse should be disabled and the HWBE fuse used instead to run the bootloader when needed.

Project Options

The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.

Define Name: Location: Description:
NO_APP_START_ON_EJECT AppConfig.h Define to disable automatic start of the loaded application when the virtual Mass Storage disk is ejected on the host.