i.MX8 Boot process and creating a bootable image

Document created by manuelrodriguez Employee on Apr 18, 2019
Version 1Show Document
  • View in full screen mode

This document intends to provide an overview of the i.MX8 Boot process and walk you through the process of creating a bootable image.

 

Boot process

Coming out of a reset state the i.MX8 ROM (firmware that is stored in non-volatile memory of the i.MX8) reads the boot mode pins to determine the boot media/device that will be used.

The i.MX8 can boot out of the following boot devices:

  • eMMC/SD card
  • FlexSPI Flash
  • NAND
  • Serial Download Protocol (USB) - This is used in manufacturing mode to bring-up a board by downloading an image to RAM and then flashing the on-board boot device.

 

The following table indicates the available options on a i.MX8QXP, the i.MX8 reads the boot mode pads and based in the configuration selects the desired boot device.

 

Once the boot device has been identified, ROM configures the boot media and attempts to read the image from a predefined address in the boot device, the following table shows the addresses where the image is expected to be on different boot devices.

ROM loads data from the predefined addresses above (depending on the selected boot device) to the System Controller Unit (SCU) internal memory (tightly coupled memory) and parses it to find the image container. It can also boot by downloading an image through USB.

 

The image container has all the information needed to load all the images to the system, the first images that get loaded are the System Controller Firmware (SCFW) and Security Controller Firmware (SECO).

The SECO FW needs to be loaded to refresh the watchdog timer (kick the dog) in the device, if the SECO FW is not loaded before the watchdog expires the device will reset, this usually happens when the device fails to fetch a valid image from the boot media.

 

Once the SCFW is loaded, ROM jumps to it and starts executing it.

The SCFW then initializes the DDR and starts loading the images for the Cortex-M4 (optional) and the Cortex-A cores (optional).

Once the images are loaded to their destination memory the SCFW boots the cores and sets them in their start address.

 

Creating a bootable image

As a recap a bootable image is comprised of as minimum the System Controller Firmware and the Security Controller Firmware, optionally it can contain images for the Cortex M4 cores (if more than one available as in the case of QM devices) and Cortex A cores.

It is possible to boot an image that only contains the SCFW and SECO FW, this could be useful in the first stages of porting the SCFW to the target board. It is also possible to boot an image with only the Cortex-M4 image (baremetal, FreeRTOS, AutoSAR...), only the Cortex-A image (U-boot or any bootloader) or both Cortex-M4 and Cortex-A images.

 

Mkimage tool

The tool in charge of merging all these images and creating a bootable image for the i.MX8 is called mkimage, and can be obtained in source form in the following repository:

https://source.codeaurora.org/external/imx/imx-mkimage

mkimage is only supported in Linux

So the first step is to clone the mkimage repository into our machine and checkout the latest branch, at the time of writing this document the latest release is 4.14.98_02:

git clone https://source.codeaurora.org/external/imx/imx-mkimage
cd imx-mkimage
git checkout imx_4.14.98_2.0.0_ga

You should now be able to see the following folders:

 

Getting the SCFW

Now that you have the mkimage tool you need some actual images to work with, if you are using a custom board you might need to port the SCFW and DDR configuration files for it (depending on how close it follows NXP's reference board).

 

The following is a compendium of documents on the basics of the SCFW and how to build it from scratch you can go there if you need help getting started with the porting process:

https://community.nxp.com/docs/DOC-342654

 

If you are trying this on one of NXP's reference board you can use a pre-built SCFW binary, this can be obtained through the building process of the Yocto project or by downloading the porting kit and following these steps:

Dowload SCFW binaries for release 4.14.98_02 here.

chmod a+x imx-sc-firmware-1.2.bin
./imx-sc-firmware-1.2.bin

You will prompted to accept a license agreement and after that the binaries will be extracted:

 

Getting the SECO FW

The Security Controller Firmware is only distributed in binary form and can be obtained from the NXP website.

Download SECO FW binaries for release 4.14.98_02 here.

chmod a+x firmware-imx-8.1.bin
./firmware-imx-8.1.bin

You will prompted to accept a license agreement and after that the binaries will be extracted:

The SECO FW is under firmware/seco

  • mx8qm-ahab-container.img -----> SECO FW for QM devices
  • mx8qx-ahab-container.img ------> SECO FW for QXP devices

 

Getting an image for the Cortex-M4

The image for the Cortex-M4 can be generated using the SDK:

https://mcuxpresso.nxp.com/en/select

Just select the device you are working with and click Build MCUXpresso SDK, then you will prompted to select your IDE and host.

Click on Download SDK and a compressed file containing the SDK will be dowloaded to your computer. Now you only need to uncompress the file and follow the steps in the getting started document to generate the image. 

The getting started document includes steps to setup the toolchain and build an image for the M4.

An M4 binary for the QM and QXP MEKs is also attached in this document, the example outputs a hello world message on the M4 terminal.

Getting an image for the Cortex-A 

The bootloader for the Cortex-A cores can be obtained through the Yocto BSP:

The steps on generating the image for the 4.14.98 release can be found here:

https://www.nxp.com/webapp/Download?colCode=imx-yocto-L4.14.98_2.0.0_ga 

 

Some more details on the Yocto BSP can be found here:

https://community.nxp.com/docs/DOC-94849

 

All the required binaries to create a bootable image for the Cortex-A cores on the MEK platforms are attached here.

Building a bootable image

Once all the required pieces have been built/obtained, the bootable image can be created.

The SCFW, SECO FW and respective Cortex-M4/A images need to be copied to the folder for the target device, i.e. if you are building an image for an i.MX8QX variant copy the binaries for that variant to its folder:

 

Here is a list of the required files to build a bootable image:

  • scfw_tcm.bin -------------------------------------------- System Controller Firmware binary for the target board
  • mx8qm(qx)-ahab-container.image ---------------- Security Controller Firmware for the QM or QXP variants
  • bl31.bin --------------------------------------------------- ARM Trusted Firmware binary (Required if using u-boot with ATF) Only needed to create Cortex-A image with u-boot
  • u-boot.bin ------------------------------------------------ U-boot binary (optional)
  • m4_image ----------------------------------------------- M4 binary image, the QM variant has 2 Cortex-M4s and in this case to M4 binaries might be required (optional)

 

Once the required binaries have been copied to the desired variant folder (QXP or QM in this example), you are ready to start building some images.

 

All the targets for building different images are defined on the soc.mak file contained in each folder, this file contains different examples for creating a lot of the supported bootable images.

 

Creating a SCFW only image

The target used to create a SCFW only image is flash_b0_scfw and it is defined under the soc.mak file of each variant.

To invoke this target for QXP from the imx-mkimage directory:

make SOC=iMX8QX flash_b0_scfw

To invoke this target for QM from the imx-mkimage directory:

make SOC=iMX8QM flash_b0_scfw

 

The target definition for flash_b0_scfw can be seen below.

Definition for QXP:

flash_scfw flash_b0_scfw: $(MKIMG) mx8qx-ahab-container.img scfw_tcm.bin
./$(MKIMG) -soc QX -rev B0 -dcd skip -append mx8qx-ahab-container.img -c -scfw scfw_tcm.bin -out flash.bin

Definition for QM:

flash_b0_scfw: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin
./$(MKIMG) -soc QM -rev B0 -dcd skip -append mx8qm-ahab-container.img -c -scfw scfw_tcm.bin -out flash.bin

 

Creating a Cortex-A image only

The target used to create a Cortex-A image only is called flash_b0.

To invoke this target for QXP from the imx-mkimage directory:

make SOC=iMX8QX flash_b0

To invoke this target for QM from the imx-mkimage directory:

make SOC=iMX8QM flash_b0

The target definition for flash_b0 can be seen below.

Definition for QXP:

 

flash flash_b0: $(MKIMG) mx8qx-ahab-container.img scfw_tcm.bin u-boot-atf.bin
./$(MKIMG) -soc QX -rev B0 -append mx8qx-ahab-container.img -c -scfw scfw_tcm.bin -ap u-boot-atf.bin a35 0x80000000 -out flash.bin

Definition for QM:

 

flash_b0: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin u-boot-atf.bin
./$(MKIMG) -soc QM -rev B0 -append mx8qm-ahab-container.img -c -scfw scfw_tcm.bin -ap u-boot-atf.bin a53 0x80000000 -out flash.bin

 

Creating a Cortex-M4 image only

The target used to create a Cortex-m4 image only is called flash_b0_cm4 on QXP and QM has different targets since there are two M4s available in the system.

To invoke this target for QXP from the imx-mkimage directory:

make SOC=iMX8QX flash_b0_cm4

To invoke this target for QM from the imx-mkimage directory:

// For Cortex-M4_0 only
make SOC=iMX8QM flash_b0_cm4_0
// For Cortex-M4_1 only
make SOC=iMX8QM flash_b0_cm4_1
// For both Cortex-M4_0 and Cortex-M4_1
make SOC=iMX8QM flash_b0_m4s_tcm

 

The target definition for flash_b0_cm4 can be seen below.

Definition for QXP:

flash_cm4 flash_b0_cm4: $(MKIMG) mx8qx-ahab-container.img scfw_tcm.bin m4_image.bin
./$(MKIMG) -soc QX -rev B0 -append mx8qx-ahab-container.img -c -scfw scfw_tcm.bin -p1 -m4 m4_image.bin 0 0x34FE0000 -out flash.bin


Definitions for QM:

flash_b0_cm4_0: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin m4_image.bin
./$(MKIMG) -soc QM -rev B0 -dcd skip -append mx8qm-ahab-container.img -c -scfw scfw_tcm.bin -p1 -m4 m4_image.bin 0 0x34FE0000 -out flash.bin

flash_b0_cm4_1: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin m4_image.bin
./$(MKIMG) -soc QM -rev B0 -dcd skip -append mx8qm-ahab-container.img -c -scfw scfw_tcm.bin -p1 -m4 m4_image.bin 1 0x38FE0000 -out flash.bin

flash_b0_m4s_tcm: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin m40_tcm.bin m41_tcm.bin
./$(MKIMG) -soc QM -rev B0 -dcd skip -append mx8qm-ahab-container.img -c -scfw scfw_tcm.bin -p1 -m4 m40_tcm.bin 0 0x34FE0000 -m4 m41_tcm.bin 1 0x38FE0000 -out flash.bin

 

The examples above are for M4 images booting from TCM, the M4 is capable of booting and executing from DDR and it is also able to XIP (execute in place) from SPI memory, for examples on this targets please look at the soc.mak for the desired variant.

Creating an image with both Cortex-A and Cortex-M4 images

The target used to create an image with software for all the cores is called flash_linux_m4.

To invoke this target for QXP from the imx-mkimage directory:

make SOC=iMX8QX flash_linux_m4


To invoke this target for QM from the imx-mkimage directory:

make SOC=iMX8QM flash_linux_m4


The target definition for flash_linux_m4 can be seen below.

Definition for QXP:

flash_linux_m4: $(MKIMG) mx8qx-ahab-container.img scfw_tcm.bin u-boot-atf.bin m4_image.bin
./$(MKIMG) -soc QX -rev B0 -append mx8qx-ahab-container.img -c -flags 0x00200000 -scfw scfw_tcm.bin -ap u-boot-atf.bin a35 0x80000000 -p3 -m4 m4_image.bin 0 0x34FE0000 -out flash.bin

 

Definition for QM:

flash_linux_m4: $(MKIMG) mx8qm-ahab-container.img scfw_tcm.bin u-boot-atf.bin m4_0_image.bin m4_1_image.bin
./$(MKIMG) -soc QM -rev B0 -append mx8qm-ahab-container.img -c -flags 0x00200000 -scfw scfw_tcm.bin -ap u-boot-atf.bin a53 0x80000000 -p3 -m4 m4_0_image.bin 0 0x34FE0000 -p4 -m4 m4_1_image.bin 1 0x38FE0000 -out flash.bin

 

 

Flash image

This will create a bootable image named flash.bin, to flash this image to the SD card and boot it on your MEK simply do:

sudo dd if=iMX8QX/flash.bin of=/dev/mmcblkX bs=1k seek=32

If the desired target is a QM variant change if=iMX8QX... to if=iMX8QM.

Then match your SD card device on "of=/dev/mmcblkX" you can see how your SD card enumerates by typing lsblk on your console before and after inserting your SD card.

Remember from the information above that the i.MX8 will search for the image at 32k on the SD card, that is why we are flashing it there.

For more examples please look at the soc.mak file, it includes examples for different boot media (NAND/QSPI) as well as different configurations and usage.

 

Additional resources

Reference Manual Chapter 5 System Boot

SCFW API and Port document

imx-mkimage README

System Controller Firmware 101 

Attachments

Outcomes