Appendix

Plugin boot application

The plugin boot application is usually used to enable boot features that are not natively supported by Boot ROM, for example,

  • Boot from USB disk

  • Boot from Ethernet,

  • DDR/SDRAM configuration

  • Redundant boot/reliable boot

The prototype of plugin boot application is:

bool (*plugin_download)(void **start, size_t *bytes, uint32_t *ivt_offset);

Principles for Plugin boot application design

The Boot ROM needs to jump between Plugin boot image and the normal boot image that is loaded by the plugin boot application. To avoid any impact on the ROM boot flow, here are some recommended principles for plugin boot application design.

  1. The plugin boot application must not use the memory that is currently reserved for ROM use

  2. The plugin boot application should use minimum stack spaces to avoid the possibility of stack overflow caused by plugin boot application

  3. The plugin boot application must consider Watchdog service, if the WDOG enable bit is enabled in the Fuse block

Parent topic:Plugin boot application

Boot Flow of Plugin boot application

The boot flow for Plugin boot application is as follows

  1. Boot ROM loads the XIP plugin boot image, does authentication and execution and then jump to plugin boot application

  2. The plugin boot application loads the signed Non-XIP image from address 0x60008000 and jumps back to Boot ROM

  3. Boot ROM does authentication/decryption based on the parameters output by plugin boot application and jumps to the non-XIP boot image after authenticating successfully

Parent topic:Plugin boot application

Example Plugin boot application to enable non-XIP boot on FlexSPI NOR

The Non-XIP boot case is not natively supported by some i.MX RT Boot ROM devices. In this case, a simple plugin boot image can be created to enable non-XIP boot case for these boot devices.

The basic flow of how Plugin boot works is as follows:

Here are the example codes for plugin boot application for RT10xx FlexSPI NOR boot.

#define BOOT_IMAGE_LOAD_BASE 0x60008000
enum
{
    kTag_HAB_IVT = 0xd1,
};
typedef struct _hab_hdr
{
    uint8_t tag;
    uint8_t len[2];
    uint8_t version;
} hab_hdr_t;
typedef struct _hab_ivt
{
    hab_hdr_t hdr;
    uint32_t entry;
    uint32_t reserved1;
    uint32_t dcd;
    uint32_t boot_data;
    uint32_t self;
    uint32_t csf;
    uint32_t reserved2;
} hab_ivt_t;
//!@brief Boot data structure
typedef struct _boot_data
{
    uint32_t start;
    uint32_t length;
    uint32_t plugin;
    uint32_t reserved;
} boot_data_t;
//!@brief Boot Image header, including both IVT and BOOT_DATA
typedef struct _boot_image_hdr
{
    hab_ivt_t ivt;
    boot_data_t boot_data;
} boot_image_hdr_t;
/*!@brief Plugin Download function
 *
 * This function is used to copy non-xip boot image from Flash to RAM
 *
 */
bool plugin_download(void **start, size_t *bytes, uint32_t *ivt_offset)
{
    bool result = false;
    const boot_image_hdr_t *boot_hdr;
    //Search IVT
    uint32_t ivt_offset_list[3] = {0, 0x400, 0x1000};
    uint32_t search_index = 0;
    while (search_index < sizeof(ivt_offset_list) / sizeof(ivt_offset_list[0]))
    {
        boot_hdr = (const boot_image_hdr_t *)(ivt_offset_list[search_index] +
                                              BOOT_IMAGE_LOAD_BASE);
        if (boot_hdr->ivt.hdr.tag != kTag_HAB_IVT)
        {
            search_index++;
            continue;
        }
        *start = (void *)boot_hdr->boot_data.start;
        *bytes = boot_hdr->boot_data.length;
        *ivt_offset = boot_hdr->ivt.self - boot_hdr->boot_data.start;
        uint32_t *dst = (uint32_t *)boot_hdr->boot_data.start;
        uint32_t *src = (uint32_t *)((uint32_t)boot_hdr - *ivt_offset);
        size_t remaining_length = ((*byte + 3) & ~0x03) / 4;
        while (remaining_length--)
        {
            *dst++ = *src++;
        }
        result = true;
        break;
    }
    return result;
}

Parent topic:Plugin boot application

Images loaded by plugin boot application

The image loaded by Plugin boot application can be either XIP image or the non-XIP image. Refer to Chapter 4, Generate i.MX RT bootable image for more details.

Parent topic:Plugin boot application

Parent topic:Appendix

Example of complete manufacturing flow

Using a pre-compiled led-demo as an example, a quick start guide is provided in this section to demonstrate the complete manufacturing flow for FlexSPI NOR boot based on MIMXRT1020-EVK board.

Manufacturing process in Development phase

In development phase, generally the image is unsigned and is used for functional testing.

Create i.MX RT bootable image

Using Chapter 4, Generate i.MX RT botable image, based on the memory map assigned for RT102x SoC, here are the steps to generate i.MX RT bootable image using elftosb utility.

  1. Generate the BD file for boot image generation. The BD file content is showed as follows.

    options {
        flags = 0x00;
        startAddress = 0x60000000;
        ivtOffset = 0x1000;
        initialLoadSize = 0x2000;
    }
    sources {
        elfFile = extern(0);
    }
    section (0)
    {
    }
    
  2. Generate the i.MX RT bootable image using elftosb utility.

    Here is the example command:

    Example command to generate FlexSPI NOR boot image

    • ivt_flexspi_nor_xip.bin

    • ivt_flexspi_nor_xip_nopadding.bin

    The ivt_flexspi_nor_xip_nopadding.bin will be used to generate SB file for HyperFlash programming in a subsequent section.

Parent topic:Manufacturing process in Development phase

Create SB file for HyperFlash programming

An example to generate the SB file for HyperFlash programming programming for RT1020-EVK board is shown as follows.

# The source block assign file name to identifiers
sources {
 myBinFile = extern (0);
}
constants {
    kAbsAddr_Start= 0x60000000;
    kAbsAddr_Ivt = 0x60001000;
    kAbsAddr_App = 0x60002000;
}
# The section block specifies the sequence of boot commands to be written to the SB file
section (0) {
    #1. Prepare Flash option
    # 0xc0233007 is the tag for Serial NOR parameter selection
    # bit [31:28] Tag fixed to 0x0C
    # bit [27:24] Option size fixed to 0
    # bit [23:20] Flash type option
    #             0 - QuadSPI SDR NOR
    #             1 - QUadSPI DDR NOR
    #             2 - HyperFLASH 1V8
    #             3 - HyperFLASH 3V
    #             4 - Macronix Octal DDR
    #             6 - Micron Octal DDR
    #             8 - Adesto EcoXIP DDR
    # bit [19:16] Query pads (Pads used for query Flash Parameters)
    #             0 - 1
    #             2 - 4
    #             3 - 8
    # bit [15:12] CMD pads (Pads used for command)
    #             0 - 1
    #             2 - 4
    #             3 - 8
    # bit [11: 08] fixed to 0
    # bit [07: 04] fixed to 0
    \# bit \[03: 00\] Flash Frequency, device specific
    #
  0xc0233007
    load 0xc0233007 > 0x2000;
    # Configure HyperFLASH using option a address 0x2000
    enable flexspinor 0x2000;
    #2 Erase flash as needed.(Here only 1MBytes are erased)
    erase 0x60000000..0x60100000;
    #3. Program config block
    # 0xf000000f is the tag to notify Flashloader to program FlexSPI NOR config block to the start of device
    load 0xf000000f > 0x3000;
    # Notify Flashloader to response the option at address 0x3000
    enable flexspinor 0x3000;
    #5. Program image
    load myBinFile > kAbsAddr_Ivt;
}

After the BD file is ready, the next step is to generate the boot_image.sb file that is for MfgTool use later. Here is the example command:

Example command to generate SB file for FlexSPI NOR programming

After performing above command, the boot_image.sb is generated in elftosb utility folder.

Parent topic:Manufacturing process in Development phase

Program Image to Flash using MfgTool

Use the following steps to program a boot image into a flash device

  1. Copy the boot_image.sb file to “<mfgtool_root_dir>/Profiles/device_name/OS Firmware” folder.

  2. Change the “name” under “[List]” to MXRT102x-SecureBoot in cfg.ini file in <mfgtool_root_dir> folder.

  3. Put the device_name-EVK board to Serial Downloader mode by setting SW7 to “1-OFF, 2-ON, 3-OFF, 4-ON” .

  4. Power up device_name-EVK board and insert USB cable to J9.

  5. Open MfgTool, it will show as the detected device like the one shown in Figure 19 .

  6. Click “Start”, MfgTool will do manufacturing process. After completion, it will show the status as success as shown in Figure 20 . Click “Stop” and close the MfgTool.

  7. Put the device_name-EVK board to internal boot mode and select HyperFlash as boot device by setting SW7 to “1-OFF, 2-ON, 3-ON, 4-OFF”. Then reset the device to start running application.

Parent topic:Manufacturing process in Development phase

Parent topic:Example of complete manufacturing flow

Manufacturing process in Production phase

In production phase, the image requires to be signed and possibly encrypted. In this case, the device must be configured to HAB closed mode.

Assuming the PKI tree is ready for cst use, copy “ca”, “crts”, and “keys” folder and cst executable to the folder that holds the elftosb utility executable, as shown below

Copy required key and certificates for signed image generation

Generate signed i.MX RT bootable image

To generate a bootable image for a specific memory, users need the memory map of the i.MX RT device SoC. Chapter 4, Generate i.MX RT bootable image, provides details for generating a bootable image. Here are the steps to generate signed i.MX RT bootable image using the elftosb utility.

  1. Generate the BD file for boot image generation. The BD file content is showed in the figure below. It is also available in the release package in folder.

options {
    flags = 0x08;
    startAddress = 0x0000000;
    ivtOffset = 0x1000;
    initialLoadSize = 0x2000;
    //DCDFilePath = "dcd.bin";
    # Note: This is required if the cst and elftsb are not in the same folder
    //cstFolderPath = "path/CSTFolder";
    # Note: This is required if the default entrypoint is not the Reset_Handler
    # Please set the entryPointAddress to base address of Vector table
    //entryPointAddress = 0x0002000;
}
sources {
    elfFile = extern(0);
}
constants {
    SEC_CSF_HEADER = 20;
    SEC_CSF_INSTALL_SRK = 21;
    SEC_CSF_INSTALL_CSFK = 22;
    SEC_CSF_INSTALL_NOCAK = 23;
    SEC_CSF_AUTHENTICATE_CSF = 24;
    SEC_CSF_INSTALL_KEY = 25;
    SEC_CSF_AUTHENTICATE_DATA = 26;
    SEC_CSF_INSTALL_SECRET_KEY = 27;
    SEC_CSF_DECRYPT_DATA = 28;
    SEC_NOP = 29;
    SEC_SET_MID = 30;
    SEC_SET_ENGINE = 31;
    SEC_INIT = 32;
    SEC_UNLOCK = 33;
}
section (SEC_CSF_HEADER;
    Header_Version="4.2",
    Header_HashAlgorithm="sha256",
    Header_Engine="DCP",
    Header_EngineConfiguration=0,
    Header_CertificateFormat="x509",
    Header_SignatureFormat="CMS")
{
}
section (SEC_CSF_INSTALL_SRK;
    InstallSRK_Table="keys/SRK_1_2_3_4_table.bin", // "valid file path"
    InstallSRK_SourceIndex=0)
{
}
section (SEC_CSF_INSTALL_CSFK;
    InstallCSFK_File="crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem", // "valid file path"
    InstallCSFK_CertificateFormat="x509") // "x509"
{
}
section (SEC_CSF_AUTHENTICATE_CSF)
{
}
section (SEC_CSF_INSTALL_KEY;
    InstallKey_File="crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem",
    InstallKey_VerificationIndex=0, // Accepts integer or string
    InstallKey_TargetIndex=2) // Accepts integer or string
{
}
section (SEC_CSF_AUTHENTICATE_DATA;
    AuthenticateData_VerificationIndex=2,
    AuthenticateData_Engine="DCP",
    AuthenticateData_EngineConfiguration=0)
{
}
section (SEC_SET_ENGINE;
    SetEngine_HashAlgorithm = "sha256", // "sha1", "Sha256", "sha512"
    SetEngine_Engine = "DCP", // "ANY", "SAHARA", "RTIC", "DCP", "CAAM" and "SW"
    SetEngine_EngineConfiguration = "0") // "valid engine configuration values"
{
}
section (SEC_UNLOCK;
    Unlock_Engine = "SNVS, OCOTP", // "SRTC", "CAAM", SNVS and OCOTP
    Unlock_features = "ZMK WRITE, SRK REVOKE")
{
}
  1. Generate the i.MX RT bootable image using the elftosb utility file.

Here is the example command:

After the above command, two bootable images are generated:

  • ivt_flexspi_nor_xip_signed.bin

  • ivt_flexspi_nor_xip_signed_nopadding.bin

The ivt_flexspi_nor_xip_signed_nopadding.bin will be used to generate SB file for HyperFlash programming in a subsequent section.

Parent topic:Manufacturing process in Production phase

Create SB file for Fuse programming

In the keys folder, there is a file named “SRK_1_2_3_4_fuse.bin”. This is the HASH table for SRK authentication during boot. It must be programmed to fuses to enable secure boot mode.

Below is an example file

Example SRK_1_2_3_4_fuse.bin file

Below is an example BD file which shows the procedure to program fuses. The fuse field is a 32-bit long word data. It will be programmed into the fuses by Flashloader in little-endian mode.

# The source block assign file name to identifiers
sources {
}
constants {
}
# The section block specifies the sequence of boot commands to be written to the SB file
# Note: this is just a template, please update it to actual values in users' project
section (0) {
    # Program SRK table
    load fuse 0xD132E7F1 > 0x18;
    load fuse 0x63CD795E > 0x19;
    load fuse 0x8FF38102 > 0x1A;
    load fuse 0x22A78E77 > 0x1B;
    load fuse 0x01019c82 > 0x1C;
    load fuse 0xFC3AC699 > 0x1D;
    load fuse 0xF2C327A3 > 0x1E;
    load fuse 0xDAC9214E > 0x1F;
    # Program SEC_CONFIG to enable HAB closed mode
    load fuse 0x00000002 > 0x06;
}

The last command in above BD file is used to enable HAB closed mode by setting SEC_CONFIG [1] bit in the fuse to 1.

After BD file is ready, the next step is to create SB file for Fuse programming to enable HAB closed mode.

An example command is shown below:

Example command to generate SB file for Fuse programming

After the command “enable_hab.bd -o enable_hab.sb” in the figure above is executed, a file named “enable_hab.sb” gets generated. It is required in MfgTool for Secure Boot solution.

Parent topic:Manufacturing process in Production phase

Create SB file for Image encryption and programming for Flash

Following chapter 5, here is an example to generate the SB file for image encryption and programming on Flash for MIMXRT1020-EVK board.

Refer to the BD file in Section 5.1.3, Generate SB file for FlexSPI NOR Image encryption and programming.

After the BD file is ready, the next step is to generate the SB file. Refer below for an example command.

After the command “program_flexspinor_image_encrypt.bd -o boot_image.sb ivt_flexspi_nor_xip_signed_nopadding.bin” in the figure above , a file named “boot_image.sb” is generated in the folder that contains the elftosb utility executable.

Parent topic:Manufacturing process in Production phase

Create signed Flashloader image

The BD file for signed Flashloader image generation is similar as the one in Section 7.1.2.1 Generate signed i.MX RT bootable image.

The only difference is that the startAddress is 0x20208000 and IVTOffset is 0x400.

After the BD file is ready, the next step is to generate i.MX boot image using the elftosb utility. The example command is as below:

Example command for Signed Flashloader image generation

After the command “imx-dtcm-signed.bd -o ivt_flashloader_signed.bin flashloader.srec” in the figure above, two bootable images are generated:

  • ivt_flashloader_signed.bin

  • ivt_flashloader_signed_nopadding.bin

The first one is required by MfgTool for Secure Boot.

Parent topic:Manufacturing process in Production phase

Program Image to Flash using MfgTool

Here are the steps to program boot image into Flash device

  1. Copy the boot_image.sb file, ivt_flashloader_signed.bin and enable_hab.sb to “<mfgtool_root_dir>/Profiles/device_name/OS Firmware” folder.

  2. Change the “name” under “[List]” to device_name-SecureBoot in cfg.ini file in <mfgtool_root_dir> folder.

  3. Put the device_name-EVK board to Serial Downloader mode by setting SW7 to “1-OFF, 2-ON, 3-OFF, 4-ON”.

  4. Power up device_name-EVK board, and insert USB cable to J9.

  5. Open MfgTool, it will show the detected device like the one shown in Figure 19.

  6. Click “Start”, MfgTool will do manufacturing process and after completion, it will show the status as success as shown in Figure 20 . Click “Stop” and close the MfgTool.

  7. Put the device_name-EVK board to internal boot mode and select HyperFlash as boot device by setting SW7 to “1-OFF, 2-ON, 3-ON, 4-OFF”. Then reset the device to start running the application.

Parent topic:Manufacturing process in Production phase

Parent topic:Example of complete manufacturing flow

Parent topic:Appendix

Generate KeyBlob manually

Users may need to generate the KeyBlob manually in some cases. The Flashloader supports such usage with blhost.

The KeyBlob must be generated when the device works under HAB closed mode with signed Flashloader application.

Assuming the dek.bin is ready (generated by the elftosb utility during encrypted image generation). Here is an example command to generate KeyBlob block.

Generate KeyBlob using the Flashloader

After the command, “blhost.exe -u –generate-key-blob dek.bin keyblob.bin” in figure above is executed, a “keyblob.bin” file gets generated.

Example KeyBlob

With the encrypted image generated by the elftosb utility and keyblob.bin generated by the Flashloader, it is also feasible to combine the encrypted image and keyblob.bin. Then create a complete encrypted boot image with a Hex Editor. In this example, the KeyBlob offset is 0x18000 in the boot image.

The figure below is an example piece of encrypted image combined by Hex Editor.

Create complete encrypted image using Hex editor

Parent topic:Appendix