Skip to main content
Version: BSP 7.x.y

Build U-Boot for NXP i.MX 8/8X-based SoMs

Introductionโ€‹

This article guides you on how to build from source and deploy U-Boot for Toradex's NXP i.MX 8/8X-based System on Modules (SoMs).

Install Tools and Dependenciesโ€‹

Run the command below to install the dependencies necessary to build U-Boot from source:

$ sudo apt-get install bc build-essential git wget libncurses5-dev lzop perl libssl-dev bison flex swig libyaml-dev pkg-config python3-dev python3-venv xz-utils xxd device-tree-compiler u-boot-tools

Prepare the Environment for Cross-Compilationโ€‹

info

You can use versions 9.2 or higher of the Arm releases binary toolchains to cross-compile software for Toradex modules. The instructions below reference version 12.3, which is the version used in Toradex build environments.

To install the toolchain on your host machine, download and unpack the .tar.xz file with the command below. Alternatively, you can obtain the toolchain directly from the Arm website.

$ cd ~
$ wget -O arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz?rev=cf8baa0ef2e54e9286f0409cdda4f66c&hash=4E1BA6BFC2C09EA04DBD36C393C9DD3A"
$ tar xvf arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz && rm arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
$ ln -s arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu gcc-linaro-aarch64

U-Boot and Linux Makefiles use environment variables such as ARCH and CROSS_COMPILE to configure and call the appropriate compiler. Therefore, you must set these variables in the current shell when compiling the Kernel or U-Boot.

To facilitate this process, create an export-compiler-64 setup file with the commands below.

export-compiler-64
export ARCH=arm64
export PATH=${HOME}/gcc-linaro-aarch64/bin/:${PATH}
export DTC_FLAGS='-@'
export CROSS_COMPILE=aarch64-none-linux-gnu-
tip

Please note that creating the setup file is not mandatory, it serves only to simplify executing the commands above. You could also run each command individually on every new shell, or create a different environment setup file during the build process.

Source the setup file. Note that you will also need to source it every time you open a new shell to build the Kernel/U-Boot.

$ source ~/export-compiler-64

Get the Sourcesโ€‹

Create a directory to store the build files and repositories:

$ mkdir -p ~/workdir
$ cd ~/workdir

The following steps are intended to be run from the ~/workdir directory, created previously.

Get the U-Boot source code: For the AM62x based modules, clone U-Boot from Toradex's Downstream source, on the branch toradex_imx_lf_v2024.04.

$ git clone -b toradex_imx_lf_v2024.04 https://git.toradex.com/u-boot-toradex.git
SoCU-Boot Git BranchU-Boot ConfigurationU-Boot Binary
i.MX 8/8Xtoradex_imx_lf_v2024.04apalis-imx8_defconfig
colibri-imx8x_defconfig
imx-boot

Build U-Bootโ€‹

The NXP i.MX 8QuadMax / i.MX 8QuadXPlus boots using a Cortex-M4 boot CPU called System Controller Unit (SCU). The SCU firmware (SCFW) is in large part provided by NXP, but Toradex has slightly altered it for the Apalis iMX8/Apalis iMX8X and Colibri iMX8X. The firmware also loads an intermediate firmware running on the Cortex-A class CPUs: The ARM-trusted firmware (ATF). The ARM-trusted firmware then hands over control to U-Boot, which then can boot Linux.

To learn more about SCFW, see the Build Custom i.MX 8/8X System Controller Firmware (SCFW) article.

The DDR memory timings, the SCU firmware, the ATF and U-Boot, and any potential Cortex-M4 auxiliary firmware are all stored in a single boot container. This boot container is read by the boot ROM from the boot device, starting at a specific offset (33kB for V1.0A modules booting from SD cards).

Compile U-Bootโ€‹

  1. The appropriate build configuration for your module with the commands below:

    $ cd ~/workdir/u-boot-toradex
    $ make mrproper
    $ make colibri-imx8x_defconfig
  2. Compile U-Boot:

    $ make -j$(nproc) 2>&1 | tee build.log

Obtain the Security Controller (SECO) Firmwareโ€‹

BSP VersionNXP BSP VersionNXP Firmware File NameNXP Firmware Path
7.5.0L6.6.52_2.2.2imx-seco-5.9.4.binimx-seco-5.9.4/firmware/seco/<SoC>-ahab-container.img

Replace <SoC> for one of the following:

  • Apalis iMX8: mx8qmb0
  • Colibri iMX8X V1.0B and earlier: mx8qxb0
  • Colibri iMX8X V1.0C and later: mx8qxc0

You can use wget for download, and extract the firmware. For example:

$ cd ~/workdir
$ wget -c https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-seco-5.9.4.bin
$ chmod u+x imx-seco-5.9.4.bin
$ ./imx-seco-5.9.4.bin
$ ls imx-seco-5.9.4/firmware/seco/

NXP provides the SECO firmware in binary form. You will need to accept the NXP End-User License Agreement (EULA) as part of the unpacking process.

Build the SCU Firmware (SCFW)โ€‹

Toradex customers rarely need to rebuild SCFW. Therefore, in the following instructions, we will show how you can download the SCFW firmware. If you, for any reason, need to customize SCFW, see the Build Custom i.MX 8/8X System Controller Firmware (SCFW) article.

The SCU firmwares for Apalis iMX8/Apalis iMX8X and Colibri iMX8X are available in our i.MX-System-Controller-Firmware GitHub repository.

BSP VersionNXP BSP VersionSCFW Version
7.5.0L6.6.52_2.2.21.17.0

You can clone the SFCW repository from Toradex Github:

$ mkdir -p ~/workdir/scfw-bin && cd ~/workdir/scfw-bin
$ git clone https://github.com/toradex/i.MX-System-Controller-Firmware.git
$ mv ./i.MX-System-Controller-Firmware/src/scfw_export_<mx8qm-or-mx8qx>_b0/build_<mx8qm-or-mx8qx>_b0/mx8qm-apalis-scfw-tcm.bin ./scfw_tcm.bin

If you need to, you can use wget to download a specific version. For example:

$ wget https://github.com/toradex/i.MX-System-Controller-Firmware/raw/d8d7320aec228cd73c4512a92d55c900786873e0/src/scfw_export_mx8qx_b0/build_mx8qx_b0/mx8qx-colibri-scfw-tcm.bin -O scfw-tcm.bin

The file scfw_tcm.bin is necessary for the final container.

Build the ARM-Trusted Firmware (ATF/TF-A)โ€‹

For the i.MX 8/8X and i.MX 8MM/8MP based modules, the ATF/TF-A Branch is lf_v2.6 and the binary is always the following form:

  • build/<Platform>/release/bl31.bin

Replace <Platform> with one of the platforms indicated below.

  • Apalis iMX8: imx8qm
  • Colibri iMX8X: imx8qx
  • Verdin iMX8M Mini: imx8mm
  • Verdin iMX8M Plus: imx8mp

On top of it, OpenEmbedded applies the following patch, necessary for the system to behave as expected:

The patch can be found at: files ยป imx-atf ยป recipes-bsp - meta-toradex-nxp.git and you can apply it manually using git am or git apply.

ATF / TF-A can be obtained from NXP git servers:

$ cd ~/workdir
$ git clone https://github.com/nxp-imx/imx-atf.git -b lf_v2.6

After cloning the repository, you can use git apply to apply the patches previously mentioned. To be able to build the ATF firmware, first you'll need to download and setup the GNU Toolchain for Hard Float Calling Convention. When the toolchain is installed and you have the CROSS_COMPILE, ARCH and PATH correctly pointing to it, you can proceed to build the firmware directly:

$ cd imx-atf
$ make PLAT=<Platform> bl31

The resulting binary file bl31.bin created in build/<Platform>/release/ is necessary for the final container.

Assemble the Boot Containerโ€‹

Finally, to assembly the boot container, you need to obtain the imx-mkimage utility.

SoCBranch
i.MX 8/8xlf-6.6.23-2.0.0
i.MX 8MM/8MPlf-6.6.23-2.0.0

Git clone it from the repository:

$ cd ~/workdir
$ git clone -b <Branch> https://github.com/nxp-imx/imx-mkimage.git

Replace <Branch> with the Branch for your specific configuration as indicated in the above table.

The binary u-boot.bin is necessary for the final boot container. Make sure you have followed the previous instructions on how to build U-Boot.

Copy all the binaries to the corresponding SoC directory inside imx-mkimage. For Apalis iMX8QM, for example

$ cd ~/workdir/imx-mkimage
$ cp ~/workdir/scfw-bin/scfw_tcm.bin iMX8QM
$ cp ~/workdir/imx-atf/build/imx8qm/release/bl31.bin iMX8QM
$ cp ~/workdir/u-boot-toradex/u-boot.bin iMX8QM
$ cp ~/workdir/imx-seco-5.9.4/firmware/seco/<SECO Firmware File> iMX8QM

Finally, use make to build the boot container:

$ make SOC=iMX8QM flash_b0
$ ls iMX8QM/flash.bin

Replace <SECO Firmware File> with the SECO Firmware File for your specific configuration as indicated before and rename the file flash.bin to imx-boot so it will be suitable for a Toradex Easy Installer Image. Make sure to remove REV=C0 if you are building for B0 or older silicon versions.

$ mv iMX8<QM-or-QX>/flash.bin iMX8<QM-or-QX>/imx-boot

Deploy the U-Boot Binary to an Imageโ€‹

To deploy your custom U-Boot binary to an image, follow the steps described below:

  1. Start from an existing sample image: Download and extract one of the Toradex prebuilt images appropriate image for your SoM.

  2. Integrate artifacts: Replace the bootloader binary by the one you built. You can find the name of the u-boot binary in the content/rawfiles/filename field of the image.json file. The following snippet shows, as an example, the image.json file for the Verdin iMX8M Plus.

    image.json
    "name": "mmcblk0boot0",
    "erase": true,
    "content": {
    "filesystem_type": "raw",
    "rawfiles": [
    {
    "filename": "imx-boot",
    "dd_options": "seek=2"
    }
    ]
    }
  3. Adjust image.json: If you change the name of the U-Boot binary, change the name of the content/rawfiles/filename field on image.json

  4. Deploy the Toradex Easy Installer image: Deploy the modified Toradex Easy Installer package with Toradex Easy Installer.

Send Feedback!