Using the IMX Bootlader Builder to Create Secure Bootloader Images

This tutorial describes how to use the IMX Booloader Builder tool in a container. It supports Secure Boot to add that functionality to your NXP i.MX8, i.MX8+, or i.MX93 SoC image.

Before You Begin

  • You must have Docker Engine installed on your Linux development host

  • You must have sudo privileges

  • To deploy the bootloader image to a raw system image file, you will need the image file.

  • You must have an account at www.nxp.com to download the Code Signing Tool (CST), which is required for Secure Boot Images

  • For Secure Boot images, you must download and extract the IMX Code Signing Tool (CST).

    Warning

    Third-party license and agreements apply. We strongly recommend to consult with legal counsel as required.

    For details on implementing Secure Boot, refer to the README_IMX.md file.

Build the Bootloader Builder Container

  1. Clone the bootloader-builder.git repository.

    $ git clone --branch elxr/aria https://gitlab.com/elxr/tools/bootloader-builder.git
    
  2. Build the bootloader builder container.

    $ cd bootloader-builder/docker
    $ sudo docker build -t bootloader-builder:latest .
    
    [+] Building 22.4s (15/15) FINISHED                                                                 docker:default
     => [internal] load build definition from Dockerfile                                                          0.0s
     => => transferring dockerfile: 641B                                                                          0.0s
     => [internal] load metadata for docker.io/elxrlinux/elxr:latest                                              2.2s
     => [internal] load .dockerignore                                                                             0.0s
     => => transferring context: 2B                                                                               0.0s
     => [ 1/10] FROM docker.io/elxrlinux/elxr:latest@sha256:d416414575978016d501966bc91a95c342b5619aff42242a96e7  5.7s
     => => resolve docker.io/elxrlinux/elxr:latest@sha256:d416414575978016d501966bc91a95c342b5619aff42242a96e7d7  0.0s
     => => sha256:d416414575978016d501966bc91a95c342b5619aff42242a96e7d732c3dff055 770B / 770B                    0.0s
     => => sha256:f1784971e3781c981e228244d3ef4ba189c3abcc6391ca721c1436048fa019ff 528B / 528B                    0.0s
     => => sha256:375aaf4b97fd9e5ed5f466a68f98a8dbb5b06b8a9baa3921f3a25f0cf16ae632 891B / 891B                    0.0s
     => => sha256:c5c5d68a8fbeefeedf6c5f7208ec6a701dc4a360c12beb654b41d6221c3221d3 93.45MB / 93.45MB              3.7s
     => => extracting sha256:c5c5d68a8fbeefeedf6c5f7208ec6a701dc4a360c12beb654b41d6221c3221d3                     1.8s
     => [internal] load build context                                                                             0.0s
     => => transferring context: 2.87kB                                                                           0.0s
     => [ 2/10] RUN apt-get update                                                                                1.5s
     => [ 3/10] RUN DEBCONF_NOWARNINGS=yes apt-get install -qy apt-utils man wget bzip2 make binutils device-tre  3.9s
     => [ 4/10] RUN dpkg --add-architecture arm64                                                                 0.2s
     => [ 5/10] COPY files/eLxr-base.asc /etc/apt/trusted.gpg.d/eLxr-base.asc                                     0.0s
     => [ 6/10] RUN apt-get update                                                                                1.6s
     => [ 7/10] RUN DEBIAN_FRONTEND=noninteractive apt-get install -qy --allow-unauthenticated arm-trusted-firmw  4.8s
     => [ 8/10] RUN DEBIAN_FRONTEND=noninteractive apt-get install imx-bootloader-builder                         1.8s
     => [ 9/10] RUN mkdir -p /root/bootloader-builder                                                             0.2s
     => [10/10] WORKDIR /root/bootloader-builder                                                                  0.0s
     => exporting to image                                                                                        0.2s
     => => exporting layers                                                                                       0.2s
     => => writing image sha256:e5546e6661c61a976907c7183e2b87c3b28d2806085d04a6b39a9feb439914af                  0.0s
     => => naming to docker.io/library/bootloader-builder:latest
    
  3. Run the bootloader builder container. Note that the command prompt will change to indicate the container is running

    $ sudo docker run -it -v <path-to cst-app-folder>/:/tmp bootloader-builder:latest /bin/bash
    
      root@68661f08ca1a:~/bootloader-builder#
    

    To simplify instructions, a # will represent the container shell.

  4. Optionally review the help (-h) options for the imx-bootloader-builder command.

    # imx-bootloader-builder -h
      Usage: imx-bootloader-builder [ arguments ]:
         -t SoC Type
                          Supported SoC Type:
                           - iMX8M
                           - iMX8MP
                           - iMX9
         -d [imx dtb]: IMX SoC dtb file used to build imx bootloader image,
                                     default dtb is from u-boot-imx
         -b [build-dir]: Path used to store the imx bootloader image
                                     default path is /root/bootloader-builder.
         -i [bootloader image name]: The name of imx bootloader image
                                     defalt name is <SoC Type>-bootloader-image.bin
         -n: build bootloader image without optee
         -s: build bootloader image with secure boot feature
         -p: code signing tool path
         -h: help
    

    From the command above, you will need to specify the SoC type (-t), the build directory (-b), and bootloader image name (-i).

    To include Secure Boot, you must also include the -s and -p options, and specify the location of the CST tool directory.

Build the Bootloader Image

  1. Build the bootloader image. An example command with options is as follows.

    # imx-bootloader-builder -t <socName> -b buildDir -i <socName>-bootloader.bin -s -p <code signing tool path>
    

    When you run the command, you will need to accept the license and EULA agreements to continue with the build. Press SPACE to reach the end, then type q and then y and ENTER to accept the agreement.

    For the iMX8M platform

    #  imx-bootloader-builder -t iMX8M -b build-imx-bootloader -i imx8m-bootloader.bin -s -p /tmp
    

    For the iMX8M Plus platform

    #  imx-bootloader-builder -t iMX8MP -b build-imx-bootloader -i imx8mp-bootloader.bin -s -p /tmp
    

    For the iMX93 platform

    #  imx-bootloader-builder -t iMX9 -b build-imx-bootloader -i imx9-bootloader.bin -s -p /tmp
    
  2. Verify the bootloader.bin and signed-bootloader.bin file is available. After the build completes, you will find the bootloader files in the specified build (-b) directory. The following example is for an iMX8M image built with Secure Boot.

    # ls build-imx-bootloader
    
    Makefile        csf_image0.txt  csf_image2.bin     firmware.sh           mkimage_imx8
    csf.cfg         csf_image1.bin  csf_image2.txt     iMX8M                 scripts
    csf_image0.bin  csf_image1.txt  firmware-imx-8.23  imx8m-bootloader.bin  signed-imx8m-bootloader.bin
    
  3. Copy the image to your build host. The following command will copy the image to your CST application directory.

    # cp build-imx-bootloader/<bootloader-image-name.bin> /tmp
    

Prepare the Bootloader Image for Deployment

You have two options to prepare the bootloader image:

  • SD card

  • add to a raw image, created by an assembler

Deploy to SD card

  1. Determine the designation of your SD card. In this example, the designation is sda.

    # lsblk
      -- results removed for example --
    sda           8:0    1   1.9G  0 disk
    └─sda1        8:1    1   1.9G  0 part /media/wruser/<drive-ID>
    
  2. Copy the bootloader image bin file to the SD card.

    $ sudo dd if=<bootloader image bin> of=/dev/sda bs=1k seek=33 conv=fsync,notrunc
    

Deploy to raw image fle

You will need the path to the raw image file to run the following command:

$ sudo dd if=<bootloader image bin> of=<path to raw image> bs=1k seek=33 conv=fsync,notrunc

Deploy the Image

To deploy the image and perform an installation on hardware, see Installing eLxr on a Hardware Device.