Skip to main content

Boot process

Overview

The figure below illustrates the boot process on a high level.

Boot process overview

Processor boot firmware

When power is turned on or when a reset signal is received the processor will start to execute its boot firmware (also called boot ROM code). The main purpose of the boot firmware is to load a program and then run it on the application processor. The firmware determines where to load the program from by looking at the state of the boot mode register, fuses, and/or GPIOs (General Purpose Input Output pins).

The boot firmware is on a high level identical between i.MX processors, but can be slightly different on a more detailed level, for example, different processors might support different boot devices. The details can be found in NXP’s user’s manual for the processor you are using. For the i.MX 8M Mini application processor this is described in section 6.1 – System Boot (Rev 2 of the manual).

Boot mode register

The boot firmware begins by checking the state of the boot mode register and will continue its execution based on this state. On Embedded Artists COM boards, a boot control mechanism consisting of the signals BOOT_CTRL and ISP_ENABLE has been implemented to configure the boot mode register. The details of the boot control mechanism can be found in the datasheet of the COM board you are using, but a short summary is available below.

During the development phase you will most often switch between programming the board via the Universal Update Utility (UUU) and booting from eMMC flash. This is handled by the ISP_ENABLE signal and more specifically the J2 jumper on the COM Carrier board. Putting the J2 jumper in a closed state will enable the serial downloader (USB OTG) boot mode which will allow UUU to program the board. Putting J2 in opened state will instead enable internal boot which by default has been setup to boot from eMMC.

If you instead want to boot using fuses you need to put BOOT_CTRL in floating state which is accomplished by setting the J27 jumper in opened state.

GPIO boot

As mentioned in the previous section the default setup for Embedded Artists COM boards is to boot from eMMC. This is accomplished by either using switches or zero-ohm resistors to control pins on the processor so that the boot configuration register is set to select eMMC as boot device. See the datasheet for the COM board for more details.

For the i.MX 8M Mini processor GPIO boot overrides is described in chapter 6.1.3.2 in NXP’s User's Manual (Rev 2). Similar chapters exist for other processors in their respective manual.

Fuses

Embedded Artists COM boards are normally delivered without any programmed fuses so you as a customer have full control of these. In an end product it is common, and NXP recommends, to control the boot process by programming the fuses.

If you want to use fuses you need to set J27 on the COM carrier board in open state. For the i.MX 8M Mini processor you will find more information in chapters 6.1.3.1 – Boot eFuse Descriptions and 6.2 - Fusemap in NXP’s User’s Manual (Rev 2). Similar chapters exist for other processors in their respective manual.

SPL

As described in the Processor boot firmware section a COM board defaults to boot from eMMC flash. The boot firmware will read an Image Vector Table (IVT) from a fixed offset in the selected boot partition of the eMMC flash. The offset can be different for different processors as can be seen in the table below. The user's manual for the processor specifies the offset for different boot devices. For the i.MX 8M Mini processor this is described in chapter 6.1.6.1 – Image Vector Table and Boot data in NXP’s User’s Manual (Rev 2).

Processor familyIVT offset - eMMC
i.MX61 Kbyte
i.MX71 Kbyte
i.MX8M and i.MX8m Mini33 Kbyte
i.MX8M Nano and i.MX930, if the image is in boot partition and 32Kbyte if it is in user partition

Information from the IVT will be used to load the remainder of the image and also where it should be loaded (internal RAM in this case).

For the default setup of an Embedded Artists COM board this image will be SPL (short for Secondary Program Loader). SPL is part of the U-Boot source code and can be seen as a small subset of U-Boot. The U-Boot itself would in normal cases be too big to be loaded to internal RAM and that is why a subset is used. When SPL is built the IVT will also be generated and added at the beginning of the final SPL image.

SPL will be responsible for initializing the external RAM, load the U-Boot to external RAM and then hand over execution to U-Boot.

Board specific SPL code is available in a file called spl.c located in the board directory, see link below for the iMX8M Mini uCOM board.

https://github.com/embeddedartists/uboot-imx/blob/ea_v2018.03/board/embeddedartists/mx8mmeaucom/spl.c

U-Boot

The bootloader used for Embedded Artists COM boards is U-Boot, also known as Universal Boot Loader or Das U-Boot. This is an open-source bootloader commonly used on many different architectures and platforms.

http://www.denx.de/wiki/U-Boot

U-Boot's main responsibility is to load the Linux kernel, select and load the device tree and hand it over the device tree to the kernel. In order to do this the U-Boot has to do some initial hardware initialization such as basic processor (CPU) setup, initialize clocks and timers, initialize console, optionally the display and board specific initialization. The table below highlights some of the functions part of the initialization flow.

FunctionFile(s)Description
_mainarm/lib/crt0.S
arm/lib/crt0_64.S
Main function called by C runtime
board_init_fcommon/board_f.cPrepares the hardware for execution. Will for example call arch_cpu_init to initialize CPU, but also the board specific function board_early_init_f.
board_init_rcommon/board_r.cSDRAM is initialized and global variables are available when this function is called. SDRAM is initialized. It will call functions such as board_init, initr_mmc, console_init_r and finally run_main_loop.
main_loopcommon/main.cIt is in this function U-Boot will start to process commands, such as the commands defined in the U-Boot environment. For auto booting U-Boot will run the command(s) defined in the configuration variable CONFIG_BOOTCOMMAND.

Linux

Linux is the main operating system on Embedded Artists COM boards. It is an open-source kernel widely used on many embedded devices.

The Linux kernel will use the device tree provided by the U-Boot to activate peripherals and load device drivers. Finally, it will mount a root file system and hand over execution to the init process. The init process can be seen as the parent of all other processes in Linux. It will for example start background processes, the console, and optionally a main application. All of this is handled via an initialization manager.

At the time of writing this document the default initialization manager used with Embedded Artists Linux distribution is systemd. Previously it used to be SysV (System V Init).

Initialization manager - systemd

Systemd is a suite of components that is used to initialize and configure a Linux system. There are utility applications used to monitor and control the system and there are init scripts for the different services within the system.

We won't go into any detail of all the aspects of systemd. There are several useful resources available and below are a few of these.

Frequently asked questions

Can I boot from SD/MMC card instead of eMMC?

It depends on what you mean by booting and what you want to put on the SD/MMC card. There are instructions in the Yocto guide that show you how to put the root file system on an SD/MMC card.

You would have to modify the hardware or burn fuses, see the Fuses section if you would like to use something other than eMMC as primary boot device. Our recommendations are however to keep using eMMC as primary boot device.

How do I launch an application at startup?

This is a question related to systemd as described in the Initialization manager section above. You need to create a service file, for example, myapplication.service that you put in /etc/systemd/system. Below is an example how this file could look like.

[Unit]
Description=Launch my application
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/myapplication

[Install]
WantedBy=multi-user.target

Enable the service by using systemctl so that it starts at next boot. You can also start it using systemctl.

systemctl enable myapplication.service
systemctl start myapplication.service