1 Module Documentation
1.1 16-bit Bootloader:Application Home Page
- 16-Bit Bootloader:Application Overview
-
An overview of the bootloader:application infrastructure.
- Application Verification
-
The Application Verification describes the different methods used to verify the application binary before the bootloader executes the application binary.
- Merging Bootloader and Application Hex Files For Production
-
How to merge the Bootloader and Application hex files into a single hex file for production.
1.2 User Interface
-
Configure the memory space settings to match the ones defined in the original bootloader project. This includes the start address of the application and the start address of the Application Remapped Interrupt Table.
-
Verify that the configuration bits of the application match the bootloader.
-
Copy the interrupt settings over from the bootloader so the application project knows which interrupts will use the independent interrupt vectors and which will use the default settings. In addition it will define and place the interrupt vectors are the correct location in the Remapped Interrupt Vector Table.
The 16-bit Bootloader: Application Builder screen is shown below. Much of the data on this form is pulled from the bootloader configuration and is automatically used in the application to ensure they match. This includes the memory map, interrupt configuration and chip configuration data from the bootloader project. The user needs to browse to the location of the bootloader project being used. Once selected, MCC will go to the directory within the selected project containing the contract file that the application builder should use. Once the project file is loaded, the application builder will use it to set the memory addresses and check to make sure the current project has the same configuration settings and interrupt sources. If it finds a conflict it will display what the conflicts which needs to be fixed.
If a verification method was selected in the bootloader that requires input data from the application developer, some additional fields might appear for the required data. For more information about these verification fields, Refer to the section that corresponds to the verification method in use.
Over the life of the project, the user may have changed some of the configuration bits by updating different modules. These setting will now be in conflict with the ones in the bootloader. This will be an issue when the user switches to booting the device using the bootloader instead of the configuration bits in this standalone project. So it's highly recommended that this screen be opened during the development of the project and at the end the of the project. When the user re-visits this MCC screen, it will re-verify the configuration settings in this standalone project with the configuration settings in the bootloader. If a difference is found, the user has two options. Either revert the changes in the application to match the bootloader or go back to the bootloader and change the settings there to match the application. While some configuration bits can be overridden at run time, it can be an extremely difficult procedure if it's even possible since most config settings can not be over-ridden at run time.
The MCC Bootloader:Application builder below is responsible for importing the memory map and other settings from the bootloader project and using them to configure the bootloader features of the application FW. It does this by asking the user for the location of the bootloader project. After entering the location of the project, MCC will scan the project directory for the memory map, the interrupt configuration, and chip configuration settings. It will then apply those settings to the application project. This includes moving the location of the application to the application space defined in the bootloader.
Also during this time the MCC will compare the bootloader and application configuration bits for each project. If they are not the same it will prompt the user with the values that are different and ask the user to change them. It's imperative that the configuration bits match between the bootloader and application projects. They they don't then the user will see random failures in their code.
If the bootloader is required to do any type of verification of the application image other than application being non-blank, the bootloader will need to compute the application's CRC/Checksum/ECDSA signature and compare the computed value against the expected value stored in the application image. The expected signature of the application is calculated and inserted into the application's hex file by running the PostBuild.bat script as the last part of the application build process. The user will need to add the command below to run this script to the post build step in the application's project file. The instructions to do this are included in every application project that MCC builds and are listed below along with a picture of application project settings dialog.
-
Right click on your project, and click 'Properties'.
-
Select the 'Building' left navigation node.
-
Check the box next to 'Execute this line after the build'.
-
In the text field below,
-
add "cd mcc_generated_files/boot && postBuild.bat $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName)" (without quotes) if you are on a Windows machine.
-
add "cd mcc_generated_files/boot && ./postBuild.sh $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName)" (without quotes) if you are on a Linux/Unix/Mac machine.
-
Merging Bootloader and Application Hex Files For Production
How to merge the Bootloader and Application hex files into a single hex file for production.
For all other help, go to the 16-bit Bootloader: Bootloader help section.
1.3 Application Verification
1.3.1 Application Verification Overview
Before the bootloader launches an application, it can verify that there is a valid application image loaded into memory. This verification takes many different forms. This section discusses each of the various verification methods implemented in this bootloader solution, how each works, and some of the engineering considerations when selecting a verification method. Refer to each sub-section for the discussion of each verification method.
The overall flow could look something like this:
The verification method in use is selected using the drop-down menu provided in the Bootloader : Bootloader configuration window. The method in use is transferred to the target application project so it can generate the required application header for verification.
There is an application image application header that is placed at the start of each application image. For some verification methods this might be 0 bytes (no data added). Other verification methods might require several fields in order to verify the application image. Refer to verification method's sub-topic to review that methods application header format.
There are two main API that are used regardless of the verification method in use:
Function |
Description | |
---|---|---|
bool BOOT_Verify(void) |
Returns true if the image was verified based on the verification method selected during the bootloader configuration. Returns false if the image is not present or invalid. | |
void BOOT_StartApplication(void) |
This function transfers control from the bootloader to the application. Care should be taken to tear down the bootloader resources to their default state before calling this function. This includes, but is not limited to, interrupts and peripherals. Once this function is called the application code will start to run. |
If the bootloader is required to do any type of verification of the application image other than application being non-blank, the bootloader will need to compute the application's CRC/Checksum/ECDSA signature and compare against the expected value stored in the application image. The expected signature of the application is calculated and inserted into the application's hex file by running the PostBuild.bat script as the last part of the application build process. The user will need to add the command to run this script to the post build step in the application's project file. The instructions to do this are included in every application project that MCC builds and are listed below along with a picture of application project settings dialog.
-
Right click on your project, and click 'Properties'.
-
Select the 'Building' left navigation node.
-
Check the box next to 'Execute this line after the build'.
-
In the text field below,
-
add "cd mcc_generated_files/boot && postBuild.bat $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName)" (without quotes) if you are on a Windows machine.
-
add "cd mcc_generated_files/boot && ./postBuild.sh $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName)" (without quotes) if you are on a Linux/Unix/Mac machine.
-
1.3.2 Bootloader Application Verification Method - Not Blank
In the "Not Blank" verification method, the bootloader will verify that the application image space is completely unprogrammed. This does not check the validity of the application image. It only verifies that something has been programmed into the application space. It does not check for any types of errors in flash memory.
This form of verification is very quick and results in very fast entry to the application from the bootloader. It does not provide any error detection capability. It can't detect if an invalid firmware image was loaded or if the memory has corrupted since being programmed.
In the implementation provided only the application reset address is checked to make sure that it is not still in the erased state.
To strengthen this verification a bit more, the Unified Bootloader Host Application (UBHA) software package was updated for the 16-bit devices to program this address last of all the program memory. This way if a firmware image is partially loaded but gets interrupted before it completes, the reset address will not be programmed and the bootloader will refuse to jump to the application. If a new host application is created for use with this firmware and this verification method is used, it is suggested that a similar approach is implemented.
1.3.3 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. A 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).
-
1.3.4 Bootloader Application Verification Method - CRC32
Overview
In the CRC32 verification method, a 32-bit CRC-32Q signature is calculated over a user specified range of memory addresses and is compared to a signature value stored in a application image header at the start of the application image. If the calculated signature matches the signature stored in the application image header, the application is allowed to launch.This form of verification is good at detecting errors or if the memory has been accidentally erased/overwritten and good at detecting gross errors and even down to single bit errors. A CRC is not able to protect very well against intentional manipulation of the memory by an attacker. A CRC verification is not nearly as quick as a checksum, but provides better protection. It is faster than a hash algorithm, but less secure in terms of memory protection.
- 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 pre 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 has chosen to keep the addresses so they match the hardware PC addresses. This implementation is thus limited to only allowing CRC calculations on complete instructions (all 4 bytes, including the phantom byte). Thus odd addresses are not allowed.
Application Image Header
The bootloader needs a known good value against which to compare the calculated CRC value. A application image header is created towards the start of the application image that stores all of the information required to verify the application image. Notice that these address may include the computed CRC32 itself. To avoid the obvious issue here of including the computed CRC32 in the signature space, when computing or verifying the CRC32 the values of these located will be zero during the computation or of the CRC32. For this implementation, the format of the application image header is as follows:Offset
Length
Item
Description
0
4
CRC value
The expected 32-bit CRC value of the application image
4
4
Start Address
The first PC instruction included in the CRC calcuation. It is highly recommended that this is the start address point to itself so that it is included in the calculation. 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.)
8
4
End Address
The last PC instruction included in the CRC calculation. Every byte of the instruction addressed in this field will be included in the CRC calculation, 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
4
CRC-32Q signature value
(Calculated - e.g. 0x41FB310D)
0x3004
4
Start Address - first address to be checked. Recommended to include itself (but not the signature) so 0x3004 in this example.
0x00003004
0x3008
4
End Address
0x7FFE (last PC instruction address in memory range to be checked).
The application firmware image then immediately follows the application image header.
A few key items to note from this example:-
The CRC start address can not include the CRC.
-
The CRC start address is recommended to include itself (thus set to 0x3004 in this example).
-
The CRC end address is the last valid PC instruction address in the memory (0x7FFE is the last valid instruction address in the application memory range).
-
1.3.5 Bootloader Application Verification Method - SHA-256
Overview
In the SHA-256 verification method, a hash is calculated over a user specified range of memory addresses and is compared to a signature value stored in memory. If the calculated hash value matches the stored hash value, the application is allowed to launch.
This form of verification is very good at detecting any change in the data. The SHA-256 calculation is very computationally intensive and can take quite a long time depending on the amount of data being processed. This verification scheme is suggested only on parts running at rather high speeds (70MIPS+). At slower speeds (like 16MIPS of the PIC24F products), this computation on an entire device memory could take several seconds. The current implementation requires approximately 150 cycles per byte of program memory checked. So a 128KB part running 100MIPS would take around 200ms to verify using this method. A 128KB part running at 16MIPS would take 1.1 seconds to verify.
Implementation Details
Memory Formatting 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 is 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 has chosen to keep the addresses so they match the hardware PC addresses. This implementation is thus limited to only allowing hashes on complete instructions (all 4 bytes, including the phantom byte). Thus odd addresses are not allowed. All hashes must be calculated on full instructions.
Application Image Header
The bootloader needs a known good value against which to compare the calculated hash. 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 |
32 |
Hash |
The expected SHA-256 hash value of the application image (32 bytes). This data is stored using only the lower 16-bits of each instruction. The 4th byte of every instruction is a phantom byte and can't be used for data storage and using just the 3rd byte makes the code to process/store the hash more complex, thus only the lower 16-bits of each instruction are used. | |
32 |
4 |
Start Address |
The PC instruction address where the hash should start. It is recommended that the start address points to the first byte of information after the hash value such that even the "Start Address" field is included in the hash. 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.) | |
36 |
4 |
End Address |
The last PC instruction included in the hash. Every byte of the instruction addressed in this field will be included in the hash, 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.) |
Address |
Length |
Item |
Value | |
---|---|---|---|---|
0x3000 |
32 |
Hash |
(Calculated - e.g. 0x41FB45F204381DEFCA204829619FCA34DBEEE982125792FA4E6091E1EAB3E160) | |
0x3020 |
4 |
Start Address |
0x00003020 - The first address to be checked in the hash. It is recommended that the start address points to itself, 0x00003020 in this example. | |
0x3024 |
4 |
End Address |
0x00007FFE (last PC instruction address in memory range to be checked). |
This would be immediately followed by the firmware image of the application.
-
The start address cannot include the hash.
-
The start address is recommended to include itself (thus set to 0x3020 in this example).
-
The end address is the last valid PC instruction address in the memory (0x7FFE is the last valid instruction address in the application memory range).
1.3.6 Bootloader Application Verification Method - ECDSA
To verify that the application image has not been tampered with and that the application image comes from the expected source, ECDSA signing is often used. The details of this process is beyond the scope of this document and here will just focus on the execution details. ECDSA verification requires the generation of a ECDSA Private/Public key pair, adding the public key and verification code to the bootloader source and having the application project use the private key to sign the final application hex file and finally using all of this information to generate a pass/fail after the application has been verified. This diverse set of operations also requires an equally diverse set of tools and scripts. The bootloader MCC module will setup this infrastructure for the user to enable a quick development time and also provide example scripts for the more expert user.
Overview
The specific details of the ECDSA verification process is beyond the scope of this document. For this project we use the Microchip's ATECC608 device to speed up the ECDSA verification of the image. While the ECDSA verification can be done purely in software, doing it on 100Mhz CPU will take about 1 second. This same verification using the ATECC608 takes about 10ms. The ECDSA verification uses the 3 pieces of information below to verify that the application image is valid and comes from the expected source.
-
The ECDSA signature stored in the application image header.
-
The public key stored in the bootloader
-
The SHA256 hash of the application computed by the bootloader.
The ATECC608 takes these three pieces of information and computes a pass/fail result which is then used by the bootloader to determine if it should allow control of the system to be passed to the application code.
ECDSA Flow
Below shows the basic user flow to build both the bootloader and the application. The basic flow is the same bootloader flow that is described in the bootloader documentation doc_how_to_build_a_bootloader. But in this case we will also need to generate public/private keys and enable communication to the ATECC608.
Bootloader Generation
The user starts by first creating a project for the device and adding the MCC module for 16-bit bootloader:bootloader to the project as described here doc_how_to_build_a_bootloader. During this process the verification method is selected and is shown below. The picture may vary depending on the device selected and its capabilities and is discussed in details in the bootloader section doc_how_to_build_a_bootloader. For ECDSA verification, the user must select ECSDA Verification from the Verification Scheme drop down box shown below.
Once ECDSA Verification has been chosen, the user will be prompted to select where the public key is or if the user wants to just generate a matching set of Private/Public keys as shown below. For this example, the keys will be auto generated. Pressing "Generate Example Key Pair Files" will prompt the user where to store the generated keys. This information will also be stored and used by the MCC Bootloader:Application later on.
ATECC608 I2C Interrupt Selection.
It's mandatory that one of the two following I2C interrupt modes are chosen and configured by the user. If the user does not, communication with the ATECC608 will fail.
- Polling Mode
-
By default, the PIC24/dsPIC controller communicates with the ATECC608 using a I2C driver with interrupts enabled even though interrupts are not mandatory. Unfortunately, some PIC24/dsPIC devices and bootloader configurations have only a single interrupt table and the interrupts may not be shareable between bootloader and application. Other PIC24/dsPIC devices and configurations have two independent interrupt tables and do not need to share the interrupt. If this device/configuration only supports a single interrupt table and the user wants the I2C interrupt used in the application, the user will need to disable the I2C interrupts for the bootloader. To do this, the user will disable the I2C interrupts in the MCC->System->Interrupt Module as shown below. By doing this, the bootloader I2C driver generated will operate in a pure polling mode and for those devices/configurations that have only a single interrupt table, it would allow the application to use the I2C interrupts.
- Interrupt Mode
-
If the user wants to use I2C interrupts in the bootloader, depending on the device/configuration the user needs to inform the bootloader driver that the I2C interrupts need to be sent to the bootloader and not the application. If redirection is required, the user will see a Interrupt Vector Table Remapping window shown below. In this window, the user needs to move the Master/Slave I2C interrupts for the device they are using from "Remap to Application" -> "Keep In Bootloader". If the user does not see the Interrupt Vector Table Remapping window below, that means the device/configuration supports dual interrupt tables and interrupts are shareable between Bootloader mode and Application mode.
- Compiler/Linker Settings
-
To limit the size of the code the user may need to update the compiler/linker settings shown below. To access both of these settings at the same time, select Project->XC16 and select "Isolate each function in a section" and "Removed unused sections". Select both of these shown below. If this is not done the bootloader code will still function but will require 2K-3K more program space and the user will get a large number of linker errors until either the below options are selected or the bootloader size is increased.
- Generating the bootloader
-
At this point, the user can generate the bootloader using the instructions found at doc_how_to_build_a_bootloader
- Adding ECDSA Verification to the Application
-
Once the bootloader has been built, building the application is quite simple. Start by building the application as shown in doc_how_to_build_a_bootloader. This will read the configuration data from the bootloader and configure the application to use the bootloader's private key generated. When looking at the bootloader verification part of the MCC Bootloader:application configuration screen the user should see something that looks similar to the verification window shown below.
- Build Options Update
-
Since the generated hex file needs to be signed with the private key above, a post build step will have to be run. At this time a notification message shown below may be present.
This is providing the user information on how to enable post processing of the hex file, allowing it to be signed. For this step, the user needs to go to the Project->Properties and under Building, the user needs to enable the "Execute this line after build" and copy the line of code from the above message into the build step as shown below. This will cause the signing of the hex file to occur after each compile.
1.3.6.1 Code Signing Options
Signing the Application Image
For the ECDSA verification method to work, the application image must be signed after compilation before the bootloader will allow the application to run. The Bootloader 16 MCC project gives two options for signing the code: Automatic signing on compile and manual signing.
FOR DEMONSTRATION PURPOSES ONLY! |
The default option is "Automatic signing on compile". This is the easiest option for demonstration purposes, but is not secure. Keys used with this signing method should not be used in production. The manual signing option should always be chosen for production.
Private keys should always be generated and stored in a Hardware Security Module (HSM) such that they are never available outside that hardware unit. The HSM should be used to sign production code. Interfacing with the HSM will be device specific and in more secure applications would be located in a secure room so this will require the manual signing flow. When getting started, however, it is easier to be able to automatically sign the image on compile and then move to secure keys for production. It is suggested that customers start with the automatic sign on compile option to develop their bootloader and application and then switch to the manually signing process for production. THE KEYS USED FOR THIS METHOD SHOULD BE DISCARDED AND NOT USED DURING PRODUCTION. The private key used to sign the code is what is securing the firmware update. Anyone with this key can create a malicious firmware update. It is generally recommended that this key is NOT available on developers machines for production keys. That machine could become compromised and the key could be taken. That developer could also intentionally leak that key. It is best limit access to that key as much as possible. If the key is generated in a HSM module in a secure room, access to that key can be limited, controlled, monitored and audited. This is the best option for a production key. For development, however, this type of restriction might be too cumbersome and thus the automatic signing on compile option is nice option FOR DEVELOPMENT PURPOSES ONLY.In the manual signing workflow, the application code is converted to a binary file automatically on compile. This binary file needs to be manually signed by the developer using their own signing process. The signature file needs to be provided to the "injectSignature.bat/.sh" script file. This script will read out the signature value from the signature file and inject it into the application header in the correct location. A proper signature is required before the bootloader will allow the application code to run.
This workflow is suggested for production so that the private keys can be secured in an appropriate Hardware Security Module (HSM). This workflow, however, can be difficult to setup at first. For demonstration and initial development, the automatic signing on compile option is suggested.1.3.7 Application Header Details
- Extended Application Header Overview
-
At the beginning of each application binary is an Extended Application Header containing a variety of information about the application. The Extended Application Header has two basic sections. The first section contains the Application Header which contains just the basic information about the image.
-
The Checksum/CRC32/SHA256 or other signature of the application image used during verification.
-
The application Start and End addresses the code the signature checks.
-
A branch instruction that allows linking the bootloader code to the application
The second part of the Extended Application Header is the Application Details Header which contains other detailed information about the image such as version information of the image.
Application Header
The format of the Application Header is shown belowOffset
Length
Description
0
4
CRC32 of the image(Size of this field varies with verification method)
4
4
Start Address (inclusive - PC addresses)
8
4
End Address (inclusive - PC addresses)
12
4
Branch command to entry point of the Firmware Image
-
- Application Details Header
-
The second part of the Application Header is the Application Details Section. This section is designed to be expandable and allow the customer to add their own header types. In the current implementation, only two types of headers are defined. The first is the generic Application Details Header and the Application Version Header. These are defined below.
Start of Application Details Section Indicator – Header ID Value - 0
Offset
Length
Description
N
2
Start of Application Details Section Indicator ID (0x0000)
N+2
4
Start of Application Details Section Indicator Data Length (2 - always 2 bytes)
N+6
4
Count of Application Details in the section (Includes this one)
- Application Version Number Header
-
The second Application Details header is the Application Version Number header. This header provides a place for the version number of this application image and is defined below
Application Version Number Header - ID Value - 2
Offset
Length
Description
N
2
Version Number Header ID (0x0002)
N+2
4
Version Number Data Length (4)
N+6
4
Version Number in format of 0x00:major:minor:patch each major/minor/patch will be 0-255 limited.
- CRC32 Extended Application Header Example
-
A detailed example of a complete Application header is shown below. The verification types is CRC32 which computes a 32 bit CRC of the image within the space give. The details are shown below.
The below examples go through the and example CRC32 header.
-
The application CRC32 is 0x24E3_722A
-
The application image starts at 0x0000_1C00
-
The application image ends at 0x0002_A7FE
-
The application version number is 0x010203
Offset
Length
Description
0
4
CRC32 0x24E3_722A
4
4
0x0000_1C00
8
4
0x0002_A7FE
12
4
Branch command to entry point of the Firmware Image
16
2
Start of Application Details Section Indicator ID (0x0000)
18
4
Start of Application Details Section Indicator Data Length (2 - always 2 bytes)
22
4
Count of Application Details in the section (2 In this example. Includes this one)
26
2
Version Number Header ID (0x0002)
28
4
Version Number Data Length (4)
32
4
Version Number in format of 0x00:major:minor:patch (0x010203).
-
1.4 Compiler and Linker Options
Compiler, Linker and Post Build Options
Since the bootloader often requires specialized build features, extra build options are often required. These settings are automatically enabled in the most recent version and are documented here incase the user has questions.
- Code Protect / Code Guard settings
-
When the user selected code protect, the device is configured to use Codeguard. This feature requires special linker options to place the code in the correct place. Below are the linker settings for both the bootloader and applications.
Bootloader Linker Settings
–add-flags-code=boot,–add-flags-const=boot,-D__USE_BFA
The steps needed to change this are shown below.-
Goto Project Properties
-
Goto XC16->xc16-ld
-
Under additional options add the following: –add-flags-code=boot,–add-flags-const=boot,-D__USE_BFA
Application Linker Settings
Application Linker Settings
-D__USE_BFA-
Goto Project Properties
-
Goto XC16->xc16-ld
-
Under additional options add the following: -D__USE_BFA
-
- ECDSA Verification with Code Protect / Code Guard settings
-
When the user selected code protect, the device is configured to use Codeguard. This feature requires special linker options to place the code in the correct place. Below are the linker settings for both the bootloader and applications.
Bootloader Linker Settings
–add-flags-code=boot,–add-flags-const=boot,-D__USE_BFA
The steps needed to change this are shown below.-
Goto Project Properties
-
Goto XC16->xc16-ld
-
Under additional options add the following: –add-flags-code=boot,–add-flags-const=boot,-D__USE_BFA
Application Linker Settings
Application Linker Settings
-D__USE_BFA
-
Goto Project Properties
-
Goto XC16->xc16-ld
-
Under additional options add the following: -D__USE_BFA
Application Post Build Settings
As the final part of the build process, the application code needs to be signed and converted to a hex format to download. The following command needs to be added to the Post Build process.
Windows Post Build Command
cd mcc_generated_files/boot && postBuild.bat $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName) $(IsDebug)
Linux Post Build Command
cd mcc_generated_files/boot && ./postBuild.sh $(MP_CC_DIR) $(ProjectDir) $(ImageDir) $(ImageName) $(IsDebug)
-
Goto Project Properties
-
Select the 'Building' left navigation node.
-
Check the box next to 'Execute this line after the build'.
-
Goto Project Properties
-
Goto XC16->xc16-ld
-
Under additional options add the following: -D__USE_BFA
-
1.5 Merging Bootloader and Application Hex Files For Production
When going to production it is often beneficial to merge the bootloader with the initial application code. This allows the factory to program just a single hex file and also allows the user to have an operating device out of the box that they can update with the latest application code.
During the Application Project creation process MCC generated two scripts that can be used to merge the bootloader and application hex files into a single hex file. This single hex file can then be used to program the device in the factory thereby removing the extra step of downloading and programming the application separately. The two scripts generated are listed below. One is for a windows system and one for a linux system.
-
"/IOT_APP.X/mcc_generated_files/boot/combineAppAndBootloaderHex.bat" if you are on a Windows machine.
-
"/IOT_APP.X/mcc_generated_files/boot/combineAppAndBootloaderHex.sh" if you are on a Linux/Unix/Mac machine.
These scripts use the config bits from the application so it's imperative that the user has matched the application and bootloader configuration bits in their project. Also if the user is using codeguard and wants to write protect the device, they need to set the write protect bits in the application project and then merge the files.
1.6 Building for Production
-
Select the dropdown next to the 'Build' or 'Clean and Build' button and select 'Build Main Project' or 'Clean and Build Main Project' respectively
-
Right click on the project name in the Projects window and select 'Build' or 'Clean and Build'