1.9.2 Bootloader Application Verification Method - checksum16
Overview
In the "Checksum" verification method, a 16-bit checksum is calculated over a user specified range of memory addresses and is compared to a signature value stored in memory. If the calculated checksum value matches the stored checksum value, the application is allowed to launch.
This form of verification is decent at detecting errors in communication and if the memory has been accidentally erased/overwritten. A checksum is good at detecting gross errors and even down to single bit errors. A checksum is not able to protect very well against intentional manipulation of the memory by an attacker. A checksum verification is also rather quick to calculate allowing the application to be verified and launched rather quickly.
- Implementation Details
-
Memory Formating and Addressing
16-bit devices have 3 bytes of instruction address per every 2 PC addresses. A 4th "phantom" byte is added with a 0x00 value. Below is an example of what the memory might look like:PC Address
Opcode
Operation
0x1000
0x0007FFDF
rcall 0x14AE
0x1002
0x00060000
return
Note the 0x00 that precedes each of the opcodes. This is the phantom byte. This doesn't actually exist in memory but is returned when a read of the memory is done of the instruction from firmware. Also note that between the two example instructions, the PC address only incremented by 2 addresses. With only 2 PC addresses for every 4 bytes, not every byte is addressable.
Since not every byte is addressable directly either a new addressing scheme has to be used (as is done in the .hex files) or limitations have to be put on the addressability of the memory. This implementation was chosen to keep the addresses so they match the hardware PC addresses. This implementation is thus limited to only allowing checksums on complete instructions (all 4 bytes, including the phantom byte). Thus odd addresses are not allowed. All checksums must be calculated on full instructions.
The example calculation of the 2 instructions above would look like the following:
Checksum = 0xFFDF + 0x0007 + 0x0000 + 0x0006 = 0xFFEC
Application Image Header
The bootloader needs a known good value against which to compare the calculated checksum. An application image header is created at the start of the application image that stores all of the information required to verify the application image. For this implementation, the format of the Application Image Header is as follows:
Offset
Length
Item
Description
0
2
Checksum
The expected 16-bit checksum value of the application image
2
4
Checksum Start Address
The PC instruction address where the checksum should start. It is highly recommended that this is the start address point to itself so that everything after the checksum is included in the checksum, including the "Checksum Start Address" field itself. This address is configured in the application image so that an application can selectively decide to exclude some memory for checking for data that might not be common across all devices (e.g. - calibration data, serial numbers, emulated EEPROM, etc.)
6
4
Checksum End Address
The last PC instruction included in the checksum. Every byte of the instruction addressed in this field will be included in the checksum, including the phantom byte. This address is configured in the application image so that an application can selectively decide to exclude some memory for checking for data that might not be common across all devices (e.g. - calibration data, serial numbers, emulated EEPROM, etc.)
So if a device has a valid application memory partition from 0x3000-0x7FFF inclusive, then this is what the application image header might look like on that device:Address
Length
Item
Value
0x3000
2
Checksum
(Calculated - e.g. 0x41FB)
0x3002
4
Checksum Start Address
0x00003002
0x3006
4
Checksum End Address
0x7FFE (last PC instruction address in memory range to be checked).
0x300A
0x4FF6
Firmware Image
Firmware Image Opcodes
A few key items to note from this example:-
The checksum start address can not include the checksum.
-
The checksum start address is recommended to include itself (thus set to 0x3002 in this example).
-
The checksum end address is the last valid PC instruction address in the memory (0x7FFE is the last valid instruction address in the application memory range).
-