Search by Tags

Build Apalis iMX8/Colibri iMX8X Boot Image/Linux from Scratch


Article updated at 27 Sep 2019
Compare with Revision

Subscribe for this article updates

Attention: this content is obsolete in the context of Toradex BSPs and kept only for archiving purposes. Moving forward we provide (or will provide) support in our Embedded Linux BSP and Torizon. To build from source, please check our regular articles OpenEmbedded (core) and Build U-Boot and Linux Kernel from Source Code.

Note: What's described on this page is automated as part of Build Apalis iMX8/Colibri iMX8X OpenEmbedded/Yocto Project Bring-up Image. This page is useful for U-Boot or Linux kernel development where one wants to avoid the much longer development cycle times if one uses an OpenEmbedded setup for this.

The NXP i.MX 8QuadMax / i.MX 8QuadXPlus SoC boot process is a bit more involved than the typical SoC used by Toradex. This article describes how to build the boot container (including required integration of firmware and boot loader) and Linux manually.


The NXP i.MX 8QuadMax / i.MX 8QuadXPlus boots using a Cortex-M4 boot CPU called System Controller Unit (SCU). The SCU firmware is to a large part provided by NXP, but has been slightly altered by Toradex for the Apalis iMX8QM/Colibri iMX8QXP. 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 is able to boot Linux.

The DDR memory timings, the SCU firmware, the ATF and U-Boot as well as 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).

Prepare Cross Compiler

The Linaro cross-toolchain for AArch64 is required to build the Bootloaders/Linux from scratch. The toolchain can be found at The latest aarch64-linux-gnu toolchain should work fine. At Toradex we tested the 2017.11 release which comes with GCC 7.2.1.

Make sure you extract the toolchain and setup the environment accordingly:

cd ~/
tar xJf gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
export ARCH=arm64
export PATH=~/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/bin/:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-

Build the Boot Container

Note that if you already built an image with OpenEmbedded you already have the needed artefacts to assemble the final bootcontainer. They can be found in deploy/images/.

Obtain SECO

This is only needed for Apalis iMX8QM V1.0B and Colibri iMX8QXP V1.0B.

The SECO Firmware is provided by NXP in binary form. You will need to accept the NXP License Agreement as part of the unpacking process. The files are called mx8qm-ahab-container.img and mx8qx-ahab-container.img respectively.

E.g. use wget for download, and extract the firmware:

chmod u+x firmware-imx-8.0.bin
ls firmware-imx-8.0/firmware/seco/

Obtain SCU

Currently, the SCU Firmware for Apalis iMX8QM and Colibri iMX8QXP is stored in the Bring-up BSP layer.

E.g. use wget for download:


The relevant file renamed to scfw_tcm.bin will be used in the final container.

Build ARM Trusted Firmware

Currently, there are no changes necessary for ARM Trusted Firmware. Hence ATF can be built directly from sources provided by NXP:

Module ATF Branch Platform Binary File
Apalis iMX8QM V1.0A imx_4.9.51_imx8_beta2 imx8qm build/imx8qm/release/bl31.bin
Apalis iMX8QM V1.0B imx_4.14.78_1.0.0_ga imx8qm build/imx8qm/release/bl31.bin
Colibri iMX8QXP V1.0A imx_4.9.123_imx8mm_ga imx8qxp build/imx8qxp/release/bl31.bin
Colibri iMX8QXP V1.0B imx_4.14.78_1.0.0_ga imx8qxp build/imx8qxp/release/bl31.bin
git clone
cd imx-atf
git checkout <ATF Branch>

Build the firmware:

make PLAT=<Platform> bl31

The resulting binary file bl31.bin created in build/<Platform>/release/ will be used in the final container.

Build U-Boot

Module U-Boot Git Branch U-Boot Configuration
Apalis iMX8QM V1.0A toradex_imx_v2017.03_4.9.51_imx8_beta2-bring_up apalis-imx8_defconfig
Apalis iMX8QM V1.0B toradex_imx_v2018.03_4.14.78_1.0.0_ga-bringup apalis-imx8_defconfig
Colibri iMX8QXP V1.0A toradex_imx_v2017.03_4.9.123_imx8mm_ga-bring_up colibri-imx8qxp_defconfig
Colibri iMX8QXP V1.0B toradex_imx_v2018.03_4.14.78_1.0.0_ga-bringup colibri-imx8qxp_defconfig

Toradex uses a customized version of the U-Boot boot loader provided by the NXP BSP. It can be found on our git server in the u-boot-toradex repository.

git clone
cd u-boot-toradex
git checkout <U-Boot Git Branch>
make <U-Boot Configuration>
make -j 4

The binary u-boot.bin will be used in the final container.

Provide the imx-mkimage Utility

The utility imx-mkimage allows building the boot container.

For the V1.0A modules it needs small modifications which are available as patches from the Bring-up BSP layer. The patches do not hurt when building for V1.0B modules so we apply them here unconditionally.

Module imx-mkimage Git Branch
Apalis iMX8QM V1.0A imx_4.9.123_imx8mm_ga
Apalis iMX8QM V1.0B imx_4.14.78_1.0.0_ga
Colibri iMX8QXP V1.0A imx_4.9.123_imx8mm_ga
Colibri iMX8QXP V1.0B imx_4.14.78_1.0.0_ga
git clone
cd imx-mkimage
git checkout <imx-mkimage Git Branch>
curl | patch -p 1
curl | patch -p 1
curl | patch -p 1
curl | patch -p 1

Assemble the Boot Container

Copy all binaries SCU Firmware, ARM Trusted Firmware, U-Boot and for V1.0B modules the SECO Firmware into a SoC specific directory, iMX8QM for Apalis iMX8QM, iMX8QX for Colibri iMX8QXP. Rename the SCU Firmware to scfw_tcm.bin while copying. Then use make to build the boot container and deploy flash.bin to the module's boot device.

You either need to install your distributions devel package for linking against a static libc or remove '-static' from the CFLAGS in the Makefile.

Assemble Apalis iMX8QM V1.0A
Assemble Apalis iMX8QM V1.0B
Assemble Colibri iMX8QXP V1.0A
Assemble Colibri iMX8QXP V1.0B

Build Linux

Module Kernel Git Branch Kernel Configuration Device Tree Kernel Binary
Apalis iMX8QM V1.0A toradex_imx_4.9.51_imx8_beta2-bring_up defconfig arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis.dtb arch/arm64/boot/Image
Apalis iMX8QM V1.0B toradex_imx_4.14.78_1.0.0_ga-bring_up defconfig arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis.dtb arch/arm64/boot/Image
Colibri iMX8QXP V1.0A toradex_imx_4.9.123_imx8mm_ga-bring_up defconfig arch/arm64/boot/dts/freescale/fsl-imx8qxp-colibri-eval-v3.dtb arch/arm64/boot/Image
Colibri iMX8QXP V1.0B toradex_imx_4.14.78_1.0.0_ga-bring_up defconfig arch/arm64/boot/dts/freescale/fsl-imx8qxp-colibri-eval-v3.dtb arch/arm64/boot/Image
git clone
cd linux-toradex
git checkout <Kernel Git Branch>
make defconfig
make -j 4

By default, the U-Boot boot scripts try to load the Linux kernel and device tree from the first FAT partition of the eMMC (resp. SD card on V1.0A modules). Check Build U-Boot and Linux Kernel from Source Code on how to deploy kernel modules.