Getting Started

Getting Started with i.MX8MM

This guide is intended for first time users of the i.MX8MM Demo Kits and provides help in getting the board up and running. Each demo kit includes an i.MX8MM board and accessories like a power supply and a USB-to-Serial converter.

Connecting Power

Connect the power supply that came with the Demo Kit and plug it into the X1 socket on the board. Do not connect the power supply adapter to the mains yet. The power socket on the board is next to the two USB ports and has only two pins.

The following schematic shows the location of the power connector X1 on the BL i.MX8MM board.

BL i.MX8MM Power Connector Location

The following image shows the power connection done with an actual BL i.MX8MM board.

BL i.MX8MM Power Connector Location

Connecting the Debug Cable

Now take the USB cable from the box and plug the USB-Mini plug into the USB-Mini port, named X3, at the side of the board next to the HDMI port. This connector is not really a USB port, but rather a serial port which allows the user access to UART 3 (Debug Console) and to communicate with the operating system later on without the need for a network setup. The other end of the cable (USB type A) has to be plugged into the USB-to-Serial adapter which came with the Demo Kit. The other end of the USB-to-Serial adapter can now be plugged into a computer.

The following image shows the location of the debug port (X3) on the BL i.MX8MM board.

BL i.MX8MM Serial Debug Console Connector Location

The following image shows the BL i.MX8MM board with the debug cable attached as well as the power cable hooked up.

BL i.MX8MM Serial Debug Console Connector Location

First Start

Before turning on the power for the BL i.MX8MM, make sure the USB-to-Serial adapter is plugged into the computer and that you have a terminal or console program running on the COM port the USB-to-Serial adapter is registered at. In Linux this will usually be a ttyUSB and in Windows a COM port device.

Once this is set up, the board can be powered on and text should appear in the terminal program, which means the operating system is starting. After a short wait the text output should stop and a login prompt is visible. The image below shows an example what should be shown in the terminal program. The login prompt is right at the end of the screen.

BL i.MX8MM Serial Debug Console Connector Location

To log in use the user root and no password is needed. Once logged in there are many things that can be done with the system, but for a start why not try to turn the digital output 1 (DIO1) on and off. The pre-installed system should have the libgpiod library and its service programs already installed, this means we can use a program called gpioset to change the state of DIO1.

For more information on this topic, see the "Main Documentation" here or see section "Using the System" for i.MX8MM based boards.

Configure DIO1 as an output and setting it to 1 (On).

root@kontron-mx8mm:/# gpioset gpiochip0 3=1

The onboard LED for DIO1 should light up and signal that its output is now active. With this one command the DIO1's corresponding GPIO was configured as an output and then set to 1 in one go.

Turning DIO1 off can be done by simply setting it to 0 with the following command:

root@kontron-mx8mm:/# gpioset gpiochip0 3=0

The LED for DIO1 should now be off again, meaning the output is no longer active.

This concludes the getting started guide for the BL i.MX8MM board. As mentioned above, also see other sections of this online documentation to learn more about other connection and communication options and how to setup your own Yocto Linux build system to create your own OS.

Troubleshooting

The BL i.MX8MM board in the Demo Kit should have an OS pre-installed on the internal eMMC memory and is ready to go. If this is not the case, you can still get the board working by making an SD card with a pre-build image from our server.

Download this "image" for example to get a base system. Unpack the file and write the .wic file onto a blank SD card. If you are working under Windows, you might have to rename the file extension from .wic to *.img to be able to use one of the many SD card writing programs available. Insert the SD card into the BL i.MX8MM boards SD card slot and plug in the power supply. The board should now boot from the SD card automatically and the above mentioned text should appear in the terminal program. You should now be able to log in and try the GPIO example above.

Building your own system

If you want to build your own system for the BL i.MX8MM, you have to use the Yocto based build system to create your own system image. Below you will find a short guide on how to create such a system image, but only the very basic steps are shown. For more information on the Yocto Project visit the projects website where you also find the reference manual.

Installing Prerequisites

As you start from scratch, it is necessary to install some prerequisites on the development PC. First update the package index:

sudo apt update

Now install these packages:

sudo apt install git-core gcc g++ python gawk chrpath texinfo libsdl1.2-dev gdb-multiarch gcc-multilib g++-multilib

Also see the official Yocto docs for additional packages, that might be needed.

Cloning the Core Repository (yocto-ktn)

To get started you need to clone the core repository to a local folder on the development PC. This repository includes everything needed to make your own system and system image. The drive where the repository is cloned to needs to have at least 50 GB or more space available for extra files that will be downloaded and created during the build process.

cd ~
git clone https://git.kontron-electronics.de/yocto-ktn/yocto-ktn.git

You should see something like this in your terminal:

yocto_buildsystem_clone_base_repo

Initializing the Build Environment

Before you can use the build system, it has to be initialized with the parameters for the target machine. You have to change the directory to yocto-ktn and then initialize it for the i.MX8MM machine.

cd ~/yocto-ktn
. init-env -m kontron-mx8mm build-ktn-imx

Don't miss the dot (= source command) at the beginning of the second command or the initialization won't work.

During the initialization of the Yocto build system, all needed meta data is downloaded from the community servers and the Kontron server automatically. At the end of the output, the command will list three common targets or system images you can create.

yocto_buildsystem_init_repo_first_time

Building the first System Image

To build your first system image you will use bitbake to build it, but be careful as this can take a long time to complete.

Step 1: Accept the freescale/NXP EULA in the local.conf file

cd conf
nano local.conf

Remove the hash (#) in front of the line ACCEPT_FSL_EULA = "1" and save the change by pressing CTRL+O then Enter and then press CTRL+X to leave the editor. Go one folder up.

cd ..

Step 2: Run bitbake to create the default image image-ktn

Demand of Resources

Please note, that building from scratch can take a long time (several hours!) and needs a lot of disk space and RAM! To build as much as possible even when a recipe fails you can use the -k option.

bitbake image-ktn -k

Now it is time to wait.

yocto_buildsystem_building_first_image

Checking the Build

Once the building process completes, you have to check if there were any error. Usually bitbake prints out information about the build process during and at the end when all steps have been completed. If there is any mention of an error or a failed package that could not be retrieved or compiled, try to run the build process again with the same command as before and see if it completes now.

If there were no errors, you have successfully compiled your first system image.

yocto_buildsystem_building_first_image_done

Booting the System Image

The newly compiled system image can be found in the folder "yocto-ktn/build-ktn-imx/tmp/deploy/images/kontron-mx8mm/". The image file, usually named image-ktn-kontron-mx8mm-ktn-YOCTORELEASE-VERSION-DATE.rootfs.wic.gz, is a compressed Gzip file and needs to be unpacked before it can be written to an SD card. Furthermore, the file type is called .wic which is an SD card image. If you are working under Windows for example, you can rename the file extension to .img which can make handling the file easier. The screenshot below shows the location of the image file.

yocto_buildsystem_finished_systm_image

Once the SD card is inserted into the BL i.MX8MM, you can go to the top of this guide and follow the steps there to see your own system booting off of the SD card.

Modifying the System

After creating a system image for the BL i.MX8MM the next step is to make changes to the BSP. The following steps will show how to create your own layer and how to add it to the BSP so it gets included in the bitbake build process. This new layer will add additional packages to the system image, which will be needed for some examples in later sections.

Of course it is possible to modify the BSP directly and make changes to the files which are already there, but if there is a problem it can be very difficult to get help and if you want to start from scratch all changes are lost. This is why for this guide we utilize Yocto's layering system. For more detailed information about layers and how to create them visit the Yocto documentation.

Creating a new Layer

Using a separate layer you will add Python 3 and other Python 3 modules to the system image, which are needed later for some examples to finish off this guide, but could also be useful in your own projects.

Open a terminal window and go to the yocto-ktn folder. In this folder initialize the build environment if this is not already the case from the previous section.

cd ~/yocto-ktn
. init-env -m kontron-mx8mm build-ktn-imx

Then go back to your home folder.

cd ~

Now create a new folder which will hold your layers and enter the folder.

mkdir mylayers
cd mylayers

Now use bitbake to create a new layer together with a basic layer folder structure.

bitbake-layers create-layer meta-mypython3-layer

Note: The layer name meta-mypython3-layer is just an example, you can give your layer a different name. However the following examples and commands in this guide will use this layer name from here on. If you choose a different name, remember to adapt the shown commands.

In your terminal you should see something similar as shown in the following image:

yocto_buildsystem_create_new_layer

Once the layer has been created, you will find a new folder in your mylayers folder named meta-mypython3-layer which contains a basic layer structure and the needed files to make it work. Feel free to explore the files and the folders inside.

In the next step this new layer is added to the build system and becomes part of your system image. Go back to the build folder and run bitbake again to add your layer like this:

cd ~
cd yocto-ktn/build-ktn-imx/
bitbake-layers add-layer ~/mylayers/meta-mypython3-layer/

The result should look like this:

yocto_buildsystem_add_new_layer_to_buildsystem

You can verify that your layer has been added to the system by issuing this command:

bitbake-layers show-layers

You should now see all active layers. Your layer should be at the bottom of the list, showing it's name and path.

yocto_buildsystem_show_all_layers

To verify that the layer is recognized by the build system, you can build the example recipe which was automatically created alongside the new layer. Run the following command to build the example:

bitbake example

Right now nothing is really build as the example only includes instructions to display text during the build process, but now it is clear the layer works and is included in the build process correctly.

yocto_buildsystem_building_the_example

To get the build system to include Python 3 and other Python 3 modules in the system image, some changes are needed to make this work. Use the following commands to adapt your layer:

cd ~/mylayers/meta-mypython3-layer/
mv recipes-example recipes-core
cd recipes-core/
mv example images
cd images/
mv example_0.1.bb image-ktn.bbappend
nano image-ktn.bbappend

In the nano editor delete everything that is already there and replace it with this:

IMAGE_EXTRA_INSTALL += " python3 \
                         python3-pyserial \
                         python3-can \
                         python3-pip \
                         python3-setuptools \
                         python3-numpy \
                       "

yocto_buildsystem_contents_image-ktn_bbappend_file

Save the changes with CTRL+O and Enter and then leave the editor with CTRL+X.

Explanation: In this Yocto system or BSP, the building of the system image and which packages go into it, is defined in the core recipes named recipes-core/images. The bb file name used is image-ktn.bb and with all the above changes, your layer now extends (appends) this base recipe to also include Python 3 in the final system image.

If you want to include more or other Python 3 modules, visit the OpenEmbedded Layer Index and go to the Recipes tab. If you enter "python3-" into the search bar, all available Python 3 packages will be listed. However note, that you can only include packages which are available for the Dunfell and later releases of the Yocto Project. If a desired recipe requires a newer Yocto version then this recipe cannot be included in the system image at this point.

To check that the changes have been applied correctly, go back to the build folder and run bitbake again like this:

bitbake image-ktn -e | grep IMAGE_EXTRA_INSTALL=

The option -e instructs bitbake to only look at the global environment and which variables are defined. In conjunction with grep only the information for the variable IMAGE_EXTRA_INSTALL is shown. The = sign at the end helps to narrow down the search. You should see something like this:

yocto_buildsystem_checking_included_packages_recipes

Now that everything is ready, you can go ahead and build a new system image. Use bitbake as before:

bitbake image-ktn

The building of the new system image should go fairly fast, as most packages were build in previous steps. You should mainly see Python 3 packages and their dependencies being build. After the build process completes, retrieve the system image file, unpack it and write it to an SD card.

Once the SD card is done and inserted into the BL i.MX8MM, you can go to the top of this guide and follow the steps there to see this new system image booting.

Examples using Python 3

Now that the system image includes Python 3 and some additional modules to work with the BL i.MX8MMs hardware, why not try it out.

Serial Communication

In this example you will use the pySerial module to communicate with a computer. First wire up the RS232 port of the BL i.MX8MM to a computer directly if it has an RS232 port or via a USB-to-Serial adapter. You can find the connector pin-outs of the BL i.MX8MM in the board overview. Remember to switch the Rx and Tx lines when connecting the wires. Once done, turn on the BL i.MX8MM and log in.

Try to run Python 3 and print something to the console:

root@kontron-mx8mm:~# python3
Python 3.8.2 (default, Feb 25 2020, 10:39:28)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello World!")
Hello World!
>>> quit()
root@kontron-mx8mm:~#

Now it's time to create a small Python 3 serial test program. Open the nano editor:

root@kontron-mx8mm:~# nano serial_test.py

and enter the following program code or download a copy of the file serial_test.py

#!/usr/bin/python3

import serial, time
# Configure the serial driver
ser = serial.Serial()
# Communicate via RS232
ser.port = "/dev/ttymxc0"
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE

# Try to open the port
try:
    ser.open()
except Exception as e:
    print ("Error while opening the serial port: " + str(e))
    exit()

# If the port is open, write Hello World and wait
# for a reply which must be terminated by an LF.
if ser.isOpen():
    try:
        # Clear the buffers
        ser.flushInput()
        ser.flushOutput()
        while True:
            # Write to the serial port
            ser.write("Hello World!\n".encode())
            # Write it immediately
            ser.flush()
            print("Write data!")
            try:
                # Now wait for the other side to send something
                myvar = ser.read_until() # Wait for LF
            except:
                # If there was an error during receiving, print an error
                myvar = b'Error receiving!'

            # Display the received data, which must be ASCII characters in this example
            print("Read data! " + myvar.decode('ascii'))
            time.sleep(0.05)
        ser.close()
    except Exception as e1:
        print ("Error while communicating...:" + str(e1))
else:
    print ("Cannot open serial port!")

Save the changes with CTRL+O and Enter and then leave the editor with CTRL+X.

On the computer start a terminal program and open the serial port using these parameters:

  • Baud rate: 115200
  • Data bits: 8
  • Stop bits: 1
  • Parity bit: None

Run the Python 3 program on the BL i.MX8MM with this command:

python3 serial_test.py

The terminal windows on the computer should now display the text:

Hello World!

While on the BL i.MX8MM the Python 3 program printed the text "Write data!" to the console and now waits for the computer to send something. If you now enter a text like "Hello World 2!" in the terminal program on the computer and send it to the BL i.MX8MM, the Python 3 program will print the following to the console:

Read data! Hello World 2!

Note: When sending data from the computer to the BL i.MX8MM the last byte or character has to be a linefeed character, also referred to as LF, \n, ASCII decimal value 10 or hex value A. Some terminal or serial programs on the computer do this automatically, but there are exceptions which do not. If there is no linefeed character in the data sent to the BL i.MX8MM, the Python 3 program will wait indefinitely until the linefeed character arrives, therefore during this wait the program might appear frozen. There are other function in pySerial to receive data which do not wait (block the program), the function read_until was chosen in this example for practical reasons.

If you want to quit or terminate the program, press and hold the key combination CTRL+C until the program has ended. Feel free to modify the program or make your own and experiment with the serial port of the BL i.MX8MM sending and receiving data.

CAN-Bus Communication

This example focuses on the Python 3 pyCan module to communicate with another CAN-Bus node. The other device can be a BL i.MX8MM, one of our Raspberry Pi based products or a PC with a CAN-Bus adapter. The commands shown below are run on a device with Debian Linux and the can-utils package installed. If your setup differs from this, you will have to adapt the procedures below accordingly.

Both devices are wired together so that CAN High (CAN_H) from one device is connected to CAN High on the other device, the same is done with CAN Low (CAN_L) and Ground (GND). For the pin layout of the BL i.MX8MM have a look at the board overview section.

After turning both devices on and letting them boot, you can try to perform a simple CAN-Bus communication test, before moving on to the Python 3 example.

On the second device run the candump command on the connected CAN port, in this example can0, to listen to traffic on the CAN-Bus. Configure the can0 interface with 125000 bps beforehand.

user@linux:~# candump can0

On the BL i.MX8MM configure the can0 interface also with 125000 bps and then run the cansend command to send out a CAN message:

root@kontron-mx8mm: ifconfig can0 down
root@kontron-mx8mm: ip link set can0 type can bitrate 125000
root@kontron-mx8mm: ifconfig can0 up
root@kontron-mx8mm: cansend can0 123#DEADBEEF

On the second device the console should show the received message:

user@linux:~# candump can0
  can0  123   [4]  DE AD BE EF

If you get the same result, the communication works as expected, but you could now swap the commands and send a message from the second device to the BL i.MX8MM to test the reverse direction.

The next step is to build a Python 3 program which receives CAN messages and sends them back like an echo. However the message ID will be changed to make it easier to distinguish between the messages sent from the second device and those the BL i.MX8MM echoed back.

The following Python 3 program uses the pyCan or can module to receive and send messages via the BL i.MX8MM's CAN-Bus interface can0.

Download a copy of the file can_test.py.

This example program sends out one message at the start and then waits for incoming messages which it will then echo back to the CAN-Bus, but changing the message ID to 321h before doing so. To leave the program press CTRL+C while still messages are arriving otherwise simply reboot the device or turn off power. The function "bus.recv()" is a blocking call and waits until a new message arrives.

On the second device run the candump program again, if it is not already running, and configure the CAN interface with 125000 bps:

user@linux:~# candump can0

Configure the can0 interface of the BL i.MX8MM and then run the Python 3 program like this:

root@kontron-mx8mm: ifconfig can0 down
root@kontron-mx8mm: ip link set can0 type can bitrate 125000
root@kontron-mx8mm: ifconfig can0 up
root@kontron-mx8mm: python3 can_test.py
First message sent on socketcan channel 'can0'

The second device should show in the console:

can0  234   [4]  DE AD BE EF

On the same device press CTRL+C to quit the candump program and instead run the cangen program to generate random CAN messages on the CAN-Bus continously. You can run the program like this:

user@linux:~# cangen can0 -g 1000

The parameter -g 1000 means gap or pause for 1000 ms between messages.

The BL i.MX8MM starts to display a new message in the console every second which should look like this:

Message:
Timestamp: 1630326139.336095        ID: 04a6    S                DLC:  3    b5 4d 86                    Channel: can0
Echo message sent on socketcan channel 'can0'
Message:
Timestamp: 1630326140.335648        ID: 00e4    S                DLC:  0                                Channel: can0
Echo message sent on socketcan channel 'can0'
Message:
Timestamp: 1630326141.336454        ID: 0415    S                DLC:  8    dc fd 9c 71 77 d1 25 07     Channel: can0
Echo message sent on socketcan channel 'can0'
Message:
Timestamp: 1630326142.336584        ID: 047d    S                DLC:  8    f7 23 4c 43 20 78 70 0f     Channel: can0
Echo message sent on socketcan channel 'can0'
Message:
Timestamp: 1630326169.304173        ID: 0704    S                DLC:  8    09 18 4d 56 92 20 d2 2f     Channel: can0
Echo message sent on socketcan channel 'can0'
...

If you are connected to the second device via SSH or you are working in a terminal program on a desktop PC, you can open a second terminal window or a second SSH connection and start the candump program again in parallel to the cangen program. This way you can see the replies (echos) from the BL i.MX8MM coming back to the second device.

Example output from candump running in parallel (separate terminal window) to cangen on the second device:

user@linux:~# candump can0
  can0  4E1   [8]  11 61 62 62 76 25 4B 1D
  can0  321   [8]  11 61 62 62 76 25 4B 1D
  can0  1D6   [8]  7B B2 06 67 B5 3E CE 18
  can0  321   [8]  7B B2 06 67 B5 3E CE 18
  can0  06A   [1]  37
  can0  321   [1]  37
  can0  1BA   [8]  1B 34 16 41 46 FD D6 67
  can0  321   [8]  1B 34 16 41 46 FD D6 67
  can0  599   [4]  D8 2A 0B 61
  can0  321   [4]  D8 2A 0B 61
  can0  64A   [7]  A1 03 FB 7B 46 DF A9
  can0  321   [7]  A1 03 FB 7B 46 DF A9
  can0  386   [8]  13 1E A5 10 DF 43 F2 0D
  can0  321   [8]  13 1E A5 10 DF 43 F2 0D
  can0  357   [8]  B2 0B D8 3A 38 F0 06 3F
  can0  321   [8]  B2 0B D8 3A 38 F0 06 3F
...

First comes the CAN-Bus interface, then the message ID followed by the message DLC and the raw data in hex values. Every message always appears twice. The first message is sent by the second device and has a random message ID, for the second message the ID is always 321h. This message was echoed back from the BL i.MX8MM.

Writing the System Image to eMMC Memory

The BL i.MX8MM has an eMMC memory chip on the SoM, which can be used to boot a self made System Image and in the process freeing up the SD card slot which can then be used as data storage for example.

Note: If you received the BL i.MX8MM with a Demo Kit, then you should be good to go and you can go to the top of this guide and follow the steps there to get the device up and running. If you received or bought the BL i.MX8MM standalone, have a look at the next section.

Preparations

To write the System Image to the eMMC memory, a few things have to be prepared.

  • Find and unpack your System Image as described here Booting the System Image further up in this guide.
  • Place the extracted wic file on a FAT (FAT32) formatted USB stick. Consider renaming the file to something shorter, like rootfs.wic. This filename will used instead of the default name.
  • Boot the BL i.MX8MM from SD card and insert the USB stick which contains the System Image (wic) file.
  • The eMMC memory can be accessed through the device /dev/mmcblk0.

Writing the System Image to eMMC Memory

Once the system is running and the USB stick is inserted into a USB port, there should be some text in the console that a USB stick was detected and which device it is.

root@kontron-mx8mm:~# [   87.081061] usb 1-1.4: new high-speed USB device number 4 using ci_hdrc
[   87.385051] usb 1-1.4: device descriptor read/64, error -71
[   87.607943] usb-storage 1-1.4:1.0: USB Mass Storage device detected
[   87.614512] scsi host0: usb-storage 1-1.4:1.0
[   88.638468] scsi 0:0:0:0: Direct-Access     Generic- Multiple Reader  1.07 PQ: 0 ANSI: 4
[   88.648633] scsi 0:0:0:1: Direct-Access     Generic- MicroSD/M2       1.08 PQ: 0 ANSI: 4
[   89.050075] sd 0:0:0:1: [sdb] 31116288 512-byte logical blocks: (15.9 GB/14.8 GiB)
[   89.058307] sd 0:0:0:0: [sda] Attached SCSI removable disk
[   89.061203] sd 0:0:0:1: [sdb] Write Protect is off
[   89.071104] sd 0:0:0:1: [sdb] Write cache: disabled, read cache: disabled, doesn't support DPO or FUA
[   89.113221]  sdb: sdb1
[   89.122718] sd 0:0:0:1: [sdb] Attached SCSI removable disk

If the USB stick was already plugged-in during boot, you can use the command dmesg to see the system messages or try the command lsblk to see if there is a new block device available and if it is already mounted.

root@kontron-mx8mm:~# lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb            8:16   1  14.9G  0 disk
`-sdb1         8:17   1  14.9G  0 part /run/media/sdb1
mtdblock0     31:0    0     2M  0 disk
mmcblk0      179:0    0  29.1G  0 disk
|-mmcblk0p1  179:1    0  83.2M  0 part /run/media/mmcblk0p1
`-mmcblk0p2  179:2    0 664.3M  0 part
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   0     4M  1 disk
mmcblk1      179:96   0  14.9G  0 disk
|-mmcblk1p1  179:97   0  83.2M  0 part /run/media/mmcblk1p1
`-mmcblk1p2  179:98   0   356M  0 part /

In this example the USB stick was detected during boot and the first partition of the media was mounted to "/run/media/sdb1". Navigating in to this folder and listing the available files should show you the System Image (wic) file. If the mount point is different on your device, adjust the following commands accordingly.

root@kontron-mx8mm:~# cd /run/media/sdb1
root@kontron-mx8mm:/run/media/sdb1# ls -la
drwxrwx---    2 root     disk         32768 Jan  1  1970 .
drwxr-xr-x    5 root     root           100 Sep  1 09:08 ..
-rwxrwx---    1 root     disk     465599488 Aug 18 12:20 rootfs.wic

You can now write the System Image to the eMMC memory using the program dd and the device name /dev/mmcblk0:

root@kontron-mx8mm:~# dd if=rootfs.wic of=/dev/mmcblk0 bs=1M conv=sync

Now wait for a few minutes until the complete image has been transferred. Once this is done, dd will print out the amount of blocks read and written and you are back at the command prompt.

Unplug the USB stick and then reboot the BL i.MX8MM from SD card again, there is one more change needed.

root@kontron-mx8mm:~# reboot

After the reboot check with lsblk that the FAT partition of the eMMC memory is mounted at /run/media/mmcblk0p1.

NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mtdblock0     31:0    0     2M  0 disk
mmcblk0      179:0    0  29.1G  0 disk
|-mmcblk0p1  179:1    0  83.2M  0 part /run/media/mmcblk0p1
`-mmcblk0p2  179:2    0 664.3M  0 part
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   0     4M  1 disk
mmcblk1      179:96   0  14.9G  0 disk
|-mmcblk1p1  179:97   0  83.2M  0 part /run/media/mmcblk1p1
`-mmcblk1p2  179:98   0   356M  0 part /

Enter the folder /run/media/mmcblk0p1 and then go into the folder extlinux and edit the file extlinux.conf:

root@kontron-mx8mm:~# cd /run/media/mmcblk0p1
root@kontron-mx8mm:~# cd extlinux
root@kontron-mx8mm:~# nano extlinux.conf

Change all references of mmcblk1 to mmcblk0, there should be 2 places to edit.

edit_extlinux_conf_file

Note: Do not delete the "p2" part from the device name, only change the 1 to 0.

Press CTRL+O and Enter to save the changes and then CTRL+X to leave the editor. Everything is now ready. Power off the BL i.MX8MM and then take out the SD card and power the device back on. It should now boot from the onboard eMMC memory. You can go to the top of this guide and follow the steps there to see your system image booting from eMMC memory.

Troubleshooting:

If nothing happens and the BL i.MX8MM does not boot from eMMC, then probably the SPI NOR flash is not programed with a bootloader or the bootconfiguration fuses do not have the correct settings. Boot the BL i.MX8MM again from SD card and follow the steps from the next section.

Writing the Bootloader to NOR Flash

This section is intended for users who have a single BL i.MX8MM and not the Demo Kit and want to be able to boot the device from eMMC memory instead, freeing up the SD card for other uses. To boot the BL i.MX8MM from eMMC a bootloader stored in the NOR flash of the SoM is needed, like U-Boot. In addition the bootconfig has to include booting from NOR flash, at least as fallback option. More information about the bootconfig can be found on the page Using the System.

First check if any action is needed. The fwinfo command prints out the current system status.

root@kontron-mx8mm:~# fwinfo
Fuses: SOM SerialNo: xxxxxxxx
Fuses: Board SerialNo: xxxxxxx
Fuses: Bootconfig: 0x18001410
Fuses: MAC1: xxxxxxxxxxxx
Fuses: MAC2: xxxxxxxxxxxx
Fuses: Lock: xxxxxxxxxxxx
Version: Firmware Version: xxxxxxxxxxxxxxxxx
Log: Devicetree info: xxxxxxxxxxxxxxx
Linux version xxxxxxxxxxxxxxx
U-Boot SPL xxxxxxxxxxxxx
U-Boot xxxxxxxxxxx

A bootloader is present in the NOR flash, no action is needed and the bootconfig supports booting from NOR flash as well.

Note: If you ordered a custom SL i.MX8MM or BL i.MX8MM, the bootconfig might be different, however you might still be able to boot from eMMC. Check the page "Using the System" to see which setting you have.

If the last 2 lines are missing, then no bootloader is present and needs to be written to the NOR flash for the device to be able to boot from eMMC memory.

root@kontron-mx8mm:~# fwinfo
Fuses: SOM SerialNo: xxxxxxxx
Fuses: Board SerialNo: xxxxxxx
Fuses: Bootconfig: 0x18001410
Fuses: MAC1: xxxxxxxxxxxx
Fuses: MAC2: xxxxxxxxxxxx
Fuses: Lock: xxxxxxxxxxxx
Version: Firmware Version: xxxxxxxxxxxxxxxxx
Log: Devicetree info: xxxxxxxxxxxxxxx
Linux version xxxxxxxxxxxxxxx

Locating needed files

For the U-Boot bootloader to work, 2 files are needed. These files are named flash.bin and uboot.bin. The files are located in the BSP output folder where you also find the system image (wic) file.

The flash.bin file is most likely a symbolic link, follow it or look at the file properties and note the name of the original file or copy it to a save location. The same goes for the uboot.bin, but here the file is named u-boot-kontron-mx8mm.bin, which also is most likely a symbolic link which you have to follow to find the original file. Note it down or copy it also to a save location.

Following are some images from a Ubuntu Linux system showing the files as an example. On your system the files can be named differently, so it is best to double check the files names before coping them.

The flash.bin file symbolic link

bootloader_flash_bin_file_link

File properties window of the flash.bin file revealing the actual file

bootloader_flash_bin_file_properties_windows

The u-boot-kontron-mx8mm.bin symbolic link

bootloader_uboot_bin_file_link

File properties window of the u-boot-kontron-mx8mm.bin file revealing the actual file

bootloader_uboot_bin_file_properties_windows

Preparations

Now that you have the files, a few more steps are need before you can write the files to the NOR flash of the BL i.MX8MM.

  • Insert the SD card you have been using so far to boot the BL i.Mx8MM into a computer using a card reader. You can also create a new SD card, for this have a look at the previous topics further up in this guide first and do not continue with the preparations until you have a booting SD card for the BL i.MX8MM.
  • Copy both files on to the first partition of the SD card. Don't place the files in a folder or subfolder, leave them in the root folder.
  • Rename each file accordingly, in this example the file flash.bin-kontron-mx8mm-2020.01-r0-kontron-mx8mm-2020.01-r0 is renamed to flash.bin.
  • and the U-Boot file, in this case u-boot-kontron-mx8mm-2020.01-r0.bin is renamed to uboot.bin.
  • You can also create an empty text file called mmc1_sd_card.txt for example, so you can identify the SD card later on in the U-Boot bootloader, because the onboard eMMC memory also identifies as an SD card.

The files on the SD card should look something like in the following image:

bootloader_files_on_sd_card

Writing the Bootloader

Everything has been prepared, now you can write the U-Boot files to the NOR flash of the BL i.MX8MM.

  • Insert the SD card into the BL i.MX8MM but have the serial console ready to press the space bar when the 3 second timeout appears. You have to press the space bar within this timeframe to enter the bootloader stored on the SD card.
    • The message in the console will say: Hit any key to stop autoboot
  • Once you are in the bootloader, issue the command fatls mmc 1:1 to list the files of the SD card's first partition. You should see a listing like the one in the image.

bootloader_uboot_list_sd_card_files

  • Now follow the steps from the page Using the System in the section SPI NOR Boot
    • Remark: If it comes to writing to the NOR flash, you will see this term ${filesize} in the commands, this is correct. Do not enter any numbers or anything in its place, use the commands as they are.
  • Once done with the steps enter the command: boot
  • The system still boots from SD card, but now enter the command fwinfo again and see if it says "U-Boot xxxx" at the bottom of the text.
  • If so, power off the device, take out the SD card and power the BL i.MX8MM back on and look at the serial console if the bootloader now gets loaded from the NOR flash and then boots your system image from the eMMC. If you have no system installed in the eMMC memory, take a look at the section Writing the System Image to eMMC Memory.