Booting Tools
Note
To see the exact sequence of steps in which applications and secondary bootloader (SBL) are converted from compiler generated .out files to boot images, see the makefile makefile_ccs_bootimage_gen that is included in every example and secondary bootloader (SBL) CCS project.
Note
If you are using makefile based build, then see the file named makefile in the example folder.
Introduction
This section describes the various tools that are used to create boot images for all the SDK applications
Important files and folders
| Folder/Files | Description |
|---|---|
| ${SDK_INSTALL_PATH}/tools/boot/ | |
| multicoreImageGen/ | Tool to combine multiple RPRC into a single binary |
| out2rprc/ | Tool to convert compiler generated ELF .out for a CPU to a compact and loadable binary representation, called RPRC. |
| sbl_prebuilt/ | Pre-built secondary bootloader (SBL) images and flash configuration files for different supported EVMs |
| signing/ | Security signing scripts need to create boot images that can be booted by ROM bootloader (RBL) |
| xipGen/ | Tool to split a RPRC file generated from out2rprc into two files containing non-XIP and XIP sections.
|
| uart_bootloader.py | Python script used to send the SBL and appimage binaries over UART using XMODEM protocol in UART boot mode |
| uart_uniflash.py | Python script used to flash SBL and applications to EVM flash using UART. See Flashing Tools for more details. |
| genimage.py | Python script used to generate multicore elf image from individual core elf images. |
MCELF Image Gen
This tool takes individual core ELF files as input and combines their segments to create a single ELF file.
Shown below is the file format for an mcelf image file and its metacontent as seen by
readelf
Segment data from each input ELF file is extracted and appended together to form a single list of segments.
The program header table fields are then re-calculated and the header table is regenerated using information from this new segment list.
Once that is done, from the updated program header, the ELF header is regenerated.
The first segment is the note segment. It can be customized to store information according to your application. By default the note segment contains vendor information, segment to core mapping and entry points.
The segment sizes can be manipulated using appropriate arguments.
Argument
Description
--core-imgPath to individual binaries of each core. It is a mandatory argument. Input is given in this format:
--core-img=0:<core0_binary.out> --core-img=1:<core1_binary.out>--outputThe output file name. It is a mandatory argument.
--output=<file_name>.mcelf--merge-segmentsEnable merging segments based on a tolerance limit. Default value is false.
--tolerance-limitThe maximum difference (in bytes) between the end address of previous segment and start address of current segment for merging the segments. Default value is zero.
--ignore-contextEnable merging of segments that are of different cores. Default value is false.
--xipXIP section’s start and end address seperated by a colon. It creates a new file
<filename>.mcelf_xip. Default value is ‘none’ (XIP is disabled). To enable XIP creation:--xip=0x60100000:0x60200000--max_segment_sizeMaximum allowed size of a loadable segment. This feature can only be used with merge_segments disabled. Default value is 8192 bytes.
--xlatSOC specific Address Translation. (Under development, reserved for future use)
--ssoShared static objects. (Under development, reserved for future use)
The input for arguments 3-7 are defined in {MCU_SDK_PATH}/devconfig/devconfig.mak file.
Given below are the structs used in the bootloader library to parse a 32 bit MCELF binary
#define E_IDENT 16
/* ELF HEADER */
typedef struct Bootloader_ELFH32_s
{
uint8_t e_ident[E_IDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
uint32_t e_entry;
uint32_t e_phoff;
uint32_t e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
} Bootloader_ELFH32;
/* PROGRAM HEADER */
typedef struct Bootloader_ELFPH32_s
{
uint32_t type;
uint32_t offset;
uint32_t vaddr;
uint32_t paddr;
uint32_t filesz;
uint32_t memsz;
uint32_t flags;
uint32_t align;
} Bootloader_ELFPH32;
/* NOTE SEGMENT */
typedef struct Bootloader_ELFNote_s
{
uint32_t namesz;
uint32_t descsz;
uint32_t type;
} Bootloader_ELFNote;
Use the following command to invoke this script to generate a basic
.mcelfimage from input.outfiles without any segment manipulations
$ cd tools/boot/multicoreELFImageGen
$ {PYTHON} genimage.py --core-img={CORE_0_ID}:{core0_app.out} --core-img={CORE_1_ID}:{core1_app.out} --core-img={CORE_2_ID}:{core2_app.out} --core-img={CORE_3_ID}:{core3_app.out} --output={application.mcelf}
The various core ID to be used are as below.
CORE |
CORE ID |
|---|---|
wkup-r5fss0-0 |
0 |
r5fss0-0 |
1 |
r5fss0-1 |
2 |
r5fss1-0 |
3 |
r5fss1-1 |
4 |
c75ss0-0 |
5 |
c75ss1-0 |
6 |
HSM MCELF Image Generator Tool
Note
Change DEVICE_TYPE to HS in ${SDK_INSTALL_PATH}/devconfig/devconfig.mak and then generate HSM MCELF image for HS-SE device.
This tool generates a HSM MCELF image by taking the HSM binary (.bin file) as input and wraps it into a MCELF image that can be booted by the SBL.
The input file location can be mentioned in the
config.makfile located at ${SDK_INSTALL_PATH}/tools/boot/HSMMCELFImageGen/board/am275x-evmThe input file name for HSM bin file can be mentioned in the
config.makfile.#Input binary nameHSM_BINARY_NAME = HSM_min_sample.bin
Note
If HSM_BINARY_NAME is changed, the entry point label in board/{{ VAR_BOARD_NAME_LOWER }}/linker.cmd must also be updated. The label is derived from the binary file path by replacing path separators and dots with underscores and prefixing with _binary_. For example, board/am275x-evm/HSM_min_sample.bin maps to _binary_board_am275x_evm_HSM_min_sample_bin_start.
The output MCELF image name can be mentioned in the
config.makfile.#Output appimage nameHSM_APPIMAGE_NAME=hsm.mcelf
The HSM core boot ID and load address used by the tool are defined in the
config.makfile.BOOTIMAGE_CORE_ID_HSM = 7HSM_LOAD_ADDR=0x43C00000
Run the makefile at ${SDK_INSTALL_PATH}/tools/boot/HSMMCELFImageGen to generate the HSM MCELF image
For Windows
cd ${SDK_INSTALL_PATH}/tools/boot/HSMMCELFImageGen gmake -s BOARD={{ VAR_BOARD_NAME_LOWER }} allFor Linux
cd ${SDK_INSTALL_PATH}/tools/boot/HSMMCELFImageGen make -s BOARD={{ VAR_BOARD_NAME_LOWER }} all
The HSM MCELF image will be generated at ${SDK_INSTALL_PATH}/tools/boot/HSMMCELFImageGen/board/am275x-evm after running the makefile
For GP device:
hsm.mcelfandhsm.mcelf.hs_fsFor HS device:
hsm.mcelf.hs
Signing Scripts
To run these scripts, one needs
opensslinstalled as mentioned here, OpenSSL
Signing scripts are a collection of scripts needed to sign ROM images (image booted by ROM - mostly the SBL) and application images (image booted by the SBL)
The RBL requires the boot image (mostly SBL), to be signed always, even if we are not using secure boot.
We follow a combined boot method for ROM images. Here the ROM Bootloader (RBL) boots the SBL, SYSFW and BOARDCFG together. The boot image would be a binary concatenation of x509 Certificate, SBL, SYSFW, BOARDCFG (and the SYSFW inner certificate in case of HS device) binary blobs. We use a python script to generate this final boot image. This script has a dependency on
opensslas mentioned before, so make sure you’ve installed it. To generate a combined boot image, one can do as below:
For GP devices
cd ${SDK_INSTALL_PATH}/tools/boot/signing ${PYTHON} rom_image_gen.py --swrv 1 --sbl-bin <path-to-sbl-binary> --sysfw-bin <path-to-sysfw-binary> --boardcfg-blob <path-to-boardcfg-binary-blob> --boardcfg-sbldata-blob <path-to-boardcfg-sbldata-blob> --sbl-loadaddr ${SBL_RUN_ADDRESS} --sysfw-loadaddr ${SYSFW_LOAD_ADDR} --bcfg-loadaddr ${BOARDCFG_LOAD_ADDR} --bcfg-sbldata-loadaddr ${BOARDCFG_SBLDATA_LOAD_ADDR} --key ${BOOTIMAGE_CERT_KEY} --rom-image <path-to-output-image> --enable-sbldata yes --keyversion $(VERSION)
For HS devices, we have to pass the HS SYSFW binaries and also the SYSFW inner certificate to the signing script.
cd ${SDK_INSTALL_PATH}/tools/boot/signing ${PYTHON} rom_image_gen.py --swrv 1 --sbl-bin <path-to-sbl-binary> --sysfw-bin <path-to-sysfw-binary> --sysfw-inner-cert <path-to-sysfw-inner-cert-binary> --boardcfg-blob <path-to-boardcfg-binary-blob> --boardcfg-sbldata-blob <path-to-boardcfg-sbldata-blob> --sbl-loadaddr ${SBL_RUN_ADDRESS} --sysfw-loadaddr ${SYSFW_LOAD_ADDR} --bcfg-loadaddr ${BOARDCFG_LOAD_ADDR} --bcfg-sbldata-loadaddr ${BOARDCFG_SBLDATA_LOAD_ADDR} --key ${BOOTIMAGE_CERT_KEY} --rom-image <path-to-output-image> --enable-sbldata yes --keyversion $(VERSION)
For examples which is loaded by SBL, we use a different signing script. This is solely because of the x509 certificate template differences between ROM and SYSFW. In GP devices appimages are not signed. The signing happens only in HS devices. The script usage is:
cd ${SDK_INSTALL_PATH}/tools/boot/signing $(PYTHON) appimage_x509_cert_gen.py --bin <path-to-the-binary> --authtype 0 --loadaddr 84000000 --key <signing-key-derived-from-devconfig> --output <output-image-name> --keyversion $(VERSION)In the case of encryption, two extra options are also passed to the script like so:
cd ${SDK_INSTALL_PATH}/tools/boot/signing $(PYTHON) appimage_x509_cert_gen.py --bin <path-to-the-binary> --authtype 0 --loadaddr 84000000 --key <signing-key-derived-from-devconfig> --enc y --enckey <encryption-key-derived-from-devconfig> --output <output-image-name> --keyversion $(VERSION)
These scripts are invoked in makefiles, and the image generation happens automatically along with the example build. So mostly these scripts need not be manually run.
Here,
SBL_RUN_ADDRESSis0x43C00000
In the case of GP device,
BOOTIMAGE_CERT_KEYisapp_degenerateKey.pem
In the case of HS device,
BOOTIMAGE_CERT_KEYis custMpk.pem.
These scripts are invoked in makefiles, and the image generation happens automatically along with the example build. So mostly these scripts need not be manually run. If the user build-system is different from TI’s makefile system, it needs to be ensured that the same is followed as part of the post build steps.
The devconfig has ENC_SBL_ENABLED=yes and that is why for HS-SE devices, the SBL image is encrypted by default.
Make sure the UART port used for terminal is identified as mentioned in Setup UART Terminal
Make sure you have the EVM power cable and UART cable connected as shown in Cable Connections
To boot applications using this script, POWER OFF the EVM
Switch to UART BOOT MODE.
POWER ON the EVM
To confirm that the board is in UART boot mode, open the UART terminal and confirm that you see the character ‘C’ getting printed on the console every 2-3 seconds.
Now close the terminal. This is important as the script won’t be able to function properly if the UART terminal is open.
Update the appimage path on sbl_prebuilt/{board}/default_sbl_uart_hs_fs.cfg file
Note
For HS-SE device, use default_sbl_uart_hs.cfg as the cfg file.
Open a command prompt and run the below command to send the SBL and application binary to the EVM
on Linux
cd ${SDK_INSTALL_PATH}/tools/boot python uart_bootloader.py -p /dev/ttyUSB0 –cfg=sbl_prebuilt/{board}/default_sbl_uart_hs_fs.cfgon Windows cd ${SDK_INSTALL_PATH}/tools/boot python uart_bootloader.py -p -p COM
–cfg=sbl_prebuilt/{board}/default_sbl_uart_hs_fs.cfg
When you execute this, the script first sends the uart bootloader, and then the multicore appimage
After the multicore appimage is successfully parsed, the uart bootloader sends an acknowledgment to the script and waits for 5 seconds before running the application binary
Upon receiving the ack, the script will exit successfully
Connect to the UART terminal within 5 seconds to see logs from the application
Below are the logs of the script after all the files have been sent Sending the UART bootloader sbl_prebuilt/{board}/sbl_uart.release.tiimage … Sent bootloader sbl_prebuilt/{board}/sbl_uart.release.tiimage of size 243975 bytes in 23.94s.
Sending the application ../../examples/drivers/udma/udma_memcpy_polling/{board}/r5fss0-0_nortos/ti-arm-clang/udma_memcpy_polling.release.appimage … Sent application ../../examples/drivers/udma/udma_memcpy_polling/{board}/r5fss0-0_nortos/ti-arm-clang/udma_memcpy_polling.release.appimage of size 99580 bytes in 11.74s. [STATUS] Application load SUCCESS !!! Connect to UART in 5 seconds to see logs from UART !!!
The input file location can be mentioned in the
config.makfile located at {SDK_INSTALL_PATH}/tools/boot/linuxAppimageGen/board/am275x-evmPSDK_LINUX_PATH mentions the path of Processor-SDK-Linux installer.
The output appimage name can be mentioned in the
config.makfile.#Output appimage name\nLINUX_BOOTIMAGE_NAME=linux.appimage\n
Run the makefile at {SDK_INSTALL_PATH}/tools/boot/linuxAppimageGen to generate the Linux appimage
For Windows
cd ${SDK_INSTALL_PATH}/tools/boot/linuxAppimageGen gmake -s BOARD={{ VAR_BOARD_NAME_LOWER }} allFor Linux
cd ${SDK_INSTALL_PATH}/tools/boot/linuxAppimageGen make -s BOARD={{ VAR_BOARD_NAME_LOWER }} all
The Linux appimage wil be generated at {SDK_INSTALL_PATH}/tools/boot/linuxAppimageGen/board/am275x-evm after running the makefile
Out2RPRC
This tool converts the application executable (.out) into custom TI RPRC (.rprc) image - an image loadable by the secondary bootloader (SBL).
This tool strips out the initialized sections from the executable file (*.out) and places them in a compact format that the SBL can understand.
The output RPRC file is typically much smaller than the original executable (*.out) file.
The RPRC files are intermediate files in a format that is consumed by
MulticoreImageGentool that generates the final binary that is flashed (*.appimage)The RPRC file format contains header to various sections in the executable like section run address, size and a overall header which mentions the number of sections and the start offset to the first section.
The RPRC magic word is
0x43525052- which is ASCII equivalent forRPRCShown below is the file header and section format for RPRC files.

This tool is provided as a minified JS script. To convert the application executable into RPRC image file, it can be used as
cd ${SDK_INSTALL_PATH}/tools/boot/out2rprc ${NODE} elf2rprc.js {input application executable file (.out)}
Multi-core Image Gen
This tool converts the RPRC files created for each CPU into a single combined multicore application image that can be booted by the secondary bootloader (SBL)
Shown below is the file format for multicore image files.

The number of meta headers present is equal to the number of cores included.
The meta header magic word is
0x5254534D- which is ASCII equivalent forMSTRIn Windows or Linux, use the following command to convert RPRC images into a multicore
.appimagefilecd ${SDK_INSTALL_PATH}/tools/boot/multicoreImageGen ${NODE} multicoreImageGen.js --devID {DEV_ID} --out {Output image file (.appimage)} {core 1 rprc file}@{core 1 id} [ {core n rprc file}@{core n id} ... ]
UART Bootloader Python Script
This script is used in UART boot mode for sending the SBL and appimage binaries to the EVM via UART using XMODEM protocol
Make sure that python3 and its dependent modules are installed in the host machine as mentioned in Python3
Booting via UART is slow, but is useful if application loading via CCS or OSPI boot is not an option
Linux Appimage Generator Tool
Note
Change DEVICE_TYPE to HS in ${SDK_INSTALL_PATH}/devconfig/devconfig.mak and then generate Linux Appimage for HS-SE device.
This tool generates a Linux Appimage by taking the Linux binaries (ATF, OPTEE, SPL) as input and generates a Linux appimage containing the input Linux binaries.
HSM Appimage Generator Tool
Note
Change DEVICE_TYPE to HS in ${SDK_INSTALL_PATH}/devconfig/devconfig.mak and then generate Linux Appimage for HS-SE device.
This tool generates a HSM Appimage by taking the HSM binaries (.bin file) as input and generates an appimage containing the input HSM binary.
The input file location can be mentioned in the
config.makfile located at {SDK_INSTALL_PATH}/tools/boot/HSMAppimageGen/board/am275x-evmThe input file name for HSM bin file can be mentioned in the
config.makfile.#Input binary name\nHSM_BINARY_NAME = HSM_min_sample.bin\n
The output appimage name can be mentioned in the
config.makfile.#Output appimage name\nHSM_APPIMAGE_NAME=hsm.appimage\n
Run the makefile at {SDK_INSTALL_PATH}/tools/boot/HSMAppimageGen to generate the HSM appimage
For Windows
cd ${SDK_INSTALL_PATH}/tools/boot/HSMAppimageGen gmake -s BOARD={{ VAR_BOARD_NAME_LOWER }} allFor Linux
cd ${SDK_INSTALL_PATH}/tools/boot/HSMAppimageGen make -s BOARD={{ VAR_BOARD_NAME_LOWER }} all
The HSM appimage wil be generated at {SDK_INSTALL_PATH}/tools/boot/HSMAppimageGen/board/am275x-evm after running the makefile