NXP has recently updated their MCIMX8M-EVK Yocto BSP to the Linux L5.4.70 kernel. We have found that some of NXP's Yocto Linux related documentation is confusing, so we have developed this article about how we perform basic development steps with the Yocto Project, Linux kernel, and user space in the context of our i.MX8 EVK.
The steps shown below can be followed to create a working EVK system from source using an Ubuntu 18.04 host as the Yocto build machine (and package server).
Listed below are some of the data points that we need to establish to move forward when building a Yocto image from source for our EVK:
- The NXP i.MX 8MQuad is powered by a quad core 1.5 GHz ARM CORTEX-A53 with an auxiliary ARM M4
- We are working with the NXP release "L5.4.70_2.3.3" patch release. This was developed using the Yocto Project Zeus (3.0) branch / release.
- Zeus 3.0 was released October 2019 and is now EOL for support from the Yocto project.
- We utilize the Wayland graphics back end. XWayland is also supported (Wayland with X11 support) by the BSP.
- Our Yocto Machine: imx8mqevk
- Our Yocto distro: "fsl-imx-wayland"
- There is an EVKB and EVK. We are using the EVKB, and this has an upgrade to the WIFI over the EVK and a later revision of the i.MX8 SoC.
As recommended by NXP, we're using the repo tool, which is a Python script developed by Google to pull all the necessary Git repositories at the correct commits based on NXP's GA release manifest. Refer to NXP's "i.MX Repo Manifest" README for additional details.
Below we install NXP's Yocto Project release in our /build/imx8/ folder:
$ mkdir -p /build/imx8; cd /build/imx8 $ repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-zeus -m imx-5.4.24-2.1.0.xml Downloading Repo source from https://gerrit.googlesource.com/git-repo ... Downloading manifest from https://source.codeaurora.org/external/imx/imx-manifest ... repo has been initialized in /build/imx8 $ ls -a . .. .repo $ repo sync ... repo sync has finished successfully. $ ls imx-setup-release.sh README README-IMXBSP setup-environment sources $ ls sources/ base meta-clang meta-freescale-3rdparty meta-imx meta-openembedded meta-qt5 meta-timesys meta-browser meta-freescale meta-freescale-distro meta-nxp-demo-experience meta-python2 meta-rust poky
Create our Yocto Project build environment under the folder bld-wayland:
$ DISTRO=fsl-imx-wayland MACHINE=imx8mqevk source imx-setup-release.sh -b bld-wayland ... Your build environment has been configured with: MACHINE=imx8mqevk SDKMACHINE=i686 DISTRO=fsl-imx-wayland EULA= BSPDIR= BUILD_DIR=. $ pwd /build/imx8/bld-wayland $ tree . └── conf ├── bblayers.conf ├── bblayers.conf.org ├── local.conf ├── local.conf.org ├── local.conf.sample └── templateconf.cfg
It may be instructive to realize that the Git repositories under sources are not on a branch and may have been modified during the previous setup:
cd /build/imx8/sources/meta-freescale $ git branch * (no branch)
The bitbake command below will build an sdcard image in the deploy folder that we can use to boot our NXP EVK.
$ bitbake imx-image-multimedia ... Build Configuration: BB_VERSION = "1.44.0" BUILD_SYS = "x86_64-linux" NATIVELSBSTRING = "ubuntu-18.04" TARGET_SYS = "aarch64-poky-linux" MACHINE = "imx8mqevk" DISTRO = "fsl-imx-wayland" DISTRO_VERSION = "5.4-zeus" TUNE_FEATURES = "aarch64 cortexa53 crc crypto" TARGET_FPU = "" meta meta-poky = "HEAD:d88d62c20d7d8da85f02edb170dae0280624ad7e" meta-oe meta-multimedia meta-python = "HEAD:2b5dd1eb81cd08bc065bc76125f2856e9383e98b" meta-freescale = "HEAD:14f1a630a47375432f93c556927b879b51d84c4e" meta-freescale-3rdparty = "HEAD:dbcc686f52c3c84db8cb86aa8973a4e373651b98" meta-freescale-distro = "HEAD:ca27d12e4964d1336e662bcc60184bbff526c857" meta-bsp meta-sdk meta-ml meta-v2x = "HEAD:ee68455d735ea9221e57ccbf469233b09ae06334" meta-nxp-demo-experience = "HEAD:c7263d9f3cc7bbf44e7164ffeda494cf283d3dec" meta-browser = "HEAD:ee3be3b5986a4aa0e73df2204a625ae1fe5df37e" meta-rust = "HEAD:53bfa324891966a2daf5d36dc13d4a43725aebed" meta-clang = "HEAD:711e593d5984aad3bf35c51b7ac4482982bc16c7" meta-gnome meta-networking meta-filesystems = "HEAD:2b5dd1eb81cd08bc065bc76125f2856e9383e98b" meta-qt5 = "HEAD:21ce4c124d9a972d9122f87c64ac2773bf04c284" meta-python2 = "HEAD:4400f9155ec193d028208cf0c66aeed2ba2b00ab"
When we want to come back to the build system, we can do the following:
$ cd /build/imx8 $ source sources/poky/oe-init-build-env bld-wayland/ ### Shell environment set up for builds. ### You can now run 'bitbake
' Common targets are: core-image-minimal core-image-sato meta-toolchain meta-ide-support You can also run generated qemu images with a command like 'runqemu qemux86' Other commonly useful commands are: - 'devtool' and 'recipetool' handle common recipe tasks - 'bitbake-layers' handles common layer tasks - 'oe-pkgdata-util' handles common target package tasks $ bitbake imx-image-multimedia
Burning our *.wic image on an SD Card
Let's first take a look at the image file system types we have configured:
$ bitbake imx-image-multimedia -e | grep ^IMAGE_FSTYPES IMAGE_FSTYPES="wic.bmap wic.bz2 tar.bz2" IMAGE_FSTYPES_DEBUGFS="tar.gz"
Most documentation instructs the user to use dd to program an SD Card, but we use the open source tool Etcher on Windows 10. We find that this is a robust solution since dd sometimes fails to work as we expect.
We also decompress the *wic.bz2 file before using Etcher to program our SD Card. We run the following in our Ubuntu shell on our build machine:
$ cd /build/imx8/bld-wayland/tmp/deploy/images/imx8mqevk/ $ ls *.bz2 imx-image-multimedia-imx8mqevk-<date>.rootfs.tar.bz2 imx-image-multimedia-imx8mqevk.tar.bz2 imx-image-multimedia-imx8mqevk-<date>.rootfs.wic.bz2 imx-image-multimedia-imx8mqevk.wic.bz2 $ bunzip2 -vfk imx-image-multimedia-imx8mqevk.wic.bz2 $ file imx-image-multimedia-imx8mqevk.wic imx-image-multimedia-imx8mqevk.wic: DOS/MBR boot sector; partition 1 : ID=0xc, active, start-CHS (0x80,0,1), end-CHS (0x3ff,3,32), startsector 16384, 170392 sectors; partition 2 : ID=0x83, start-CHS (0x3ff,3,32), end-CHS (0x3ff,3,32), startsector 196608, 7106614 sectors
Note that the resulting *.wic image is ~3.5GB, but we expect this to grow significantly once we add a toolchain and other packages.
We transfer the resulting "*.wic" image to Windows 10 and burn the SD Card using a recent release of Etcher that supports *.wic formats. After programming is done, we insert it in the EVK SD Card slot, and the system does indeed boot Yocto Linux.
Note that we can also insert our burned SD Card back into our Ubuntu machine and make changes to the mounted partitions.
Notes on Directories and Source
imx-image-multimedia.bb can be found in sources/meta-imx/meta-sdk/recipes-fsl/images
As you may have noticed, there are several NXP layers under sources. Here's one way to determine where a recipe is located:
$ cd /build/imx8/sources/ $ find . -name 'linux-imx*bb' ./meta-freescale/recipes-kernel/linux/linux-imx_4.14.98.bb ./meta-freescale/recipes-kernel/linux/linux-imx-headers_4.14.98.bb ./meta-freescale/recipes-kernel/linux/linux-imx-mfgtool_4.14.98.bb ./meta-imx/meta-bsp/recipes-kernel/linux/linux-imx-headers_5.4.bb ./meta-imx/meta-bsp/recipes-kernel/linux/linux-imx_5.4.bb
We can see above that the linux-imx_5.4 recipe is located in the meta-imx/meta-bsp layer. This makes sense since NXP tells us that the purpose of this layer is to introduce new features into the Yocto Project build that might not have been availble for the Zeus release.
View the manifest:
$ cd /build/imx8/bld-wayland/tmp/deploy/images/imx8mqevk $ more imx-image-multimedia-imx8mqevk.manifest | more acl aarch64 2.2.52-r0 acl-dev aarch64 2.2.52-r0 adwaita-icon-theme-symbolic all 3.32.0-r0 alsa-conf aarch64 1.1.9-r0 alsa-plugins-pulseaudio-conf aarch64 1.1.9-r0 alsa-state imx8mqevk 0.2.0-r5 alsa-states imx8mqevk 0.2.0-r5 alsa-tools aarch64 1.1.7-r0 alsa-utils aarch64 1.1.9-r0 ...
It can be confusing trying to determine where the source is hosted that is used to build our image. One way of determining this is shown below:
$ cd /build/imx8/bld-wayland/tmp/work/ $ ls aarch64-mx8m-poky-linux aarch64-poky-linux all-poky-linux imx8mqevk-poky-linux x86_64-linux $ grep url imx8mqevk-poky-linux/linux-imx/5.4-r0/git/.git/config url = https://source.codeaurora.org/external/imx/linux-imx.git $ grep url imx8mqevk-poky-linux/u-boot-imx/1_2020.04-r0/git/.git/config url = https://source.codeaurora.org/external/imx/uboot-imx.git
Remote login via SSH
We find that our EVK Linux image supports Ethernet connectivity without requiring customization.
After boot up of our EVK and determination of our EVK's IP address, we add the IP address for the EVK board to /etc/hosts and login remotely:
ssh root@evk The authenticity of host 'evk (192.168.7.230)' can't be established. RSA key fingerprint is SHA256:ZOx862o0VxZf4NOaqEHROt9pU+mb4cN3t0VyvkIxffg. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'evk,<ip address>' (RSA) to the list of known hosts. # uname -a Linux imx8mqevk 5.4.70-2.3.2+g8c73bc625c4d #1 SMP PREEMPT Sat Jun 19 23:10:47 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux # cat /proc/cpuinfo processor : 0 BogoMIPS : 16.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 .. processor : 2 ... processor : 3 ...
DNF and package management
We add DNF package management support to our EVK target and build machine following Yocto documentation and our article "Use DNF Package Manager on a Yocto Linux Development System"
We also make the following customizations to our conf/local.conf file:
Add RPM package management:
IMAGE_FEATURES += "package-management" PACKAGE_CLASSES ?= 'package_rpm'
Comment out Debian Package Management Directives:
# Switch to Debian packaging and include package-management in the image # PACKAGE_CLASSES = "package_deb" # EXTRA_IMAGE_FEATURES += "package-management"
Note that modifying local.conf with the IMAGE change is considered bad form, and we'll eventually create our own custom layer, image recipe, and packagegroup to add our customizations.
After rebuilding, don't forget to run "bitbake package-index" on the build machine. Next, on our EVK, we run:
# dnf makecache timer: config: 11 ms DNF version: 4.2.2 Command: dnf makecache Installroot: / Releasever: zeus cachedir: /var/cache/dnf Base command: makecache Extra commands: ['makecache'] Repository 'oe-packages' is missing name in configuration, using id. Making cache files for all metadata files. oe-packages: has expired and will be refreshed. repo: downloading from remote: oe-packages ... oe-packages: using metadata from Sun Jun 20 14:08:43 2021. Last metadata expiration check: 0:00:04 ago on Sun Jun 20 14:53:21 2021. No module defaults found timer: sack setup: 3798 ms Metadata cache created. Cleaning up.
Adding the GNU Toolchain to our target
We add "tools-sdk" to our IMAGE_FEATURES variable to install a full SDK on our target. After modifying IMAGE_FEATURES, we re-run our build and inspect our updated rootfs:
$ bitbake imx-image-multimedia $ cd /build/imx8/bld-wayland/tmp/work/imx8mqevk-poky-linux/imx-image-multimedia/1.0-r0/rootfs $ find . -name autoconf ./usr/bin/autoconf ./usr/share/autoconf ./usr/share/autoconf/autoconf $ find . -name gcc ./usr/bin/gcc ./usr/lib/gcc ./usr/libexec/gcc
Let's also take a look at the updated manifest after updating the package-index:
$ bitbake package-index $ cd /build/imx8/bld-wayland/tmp/deploy/images/imx8mqevk/ grep autoconf grep autoconf imx-image-multimedia-imx8mqevk.manifest autoconf aarch64 2.69 $ grep cmake imx-image-multimedia-imx8mqevk.manifest
As you can see above, cmake isn't included in the SDK, so let's add it by using dnf as described above:
$ bitbake cmake $ bitbake package-index
# dnf makecache # dnf install cmake ... Installed: cmake-3.15.3-r0.aarch64 Complete! Cleaning up. # cmake --version cmake version 3.15.3 CMake suite maintained and supported by Kitware (kitware.com/cmake).
Obviously, creating customizations to an SD Card partition that will be later overwritten might not be what we want. We may want to move our rootfs off of the SD Card (i.e., use an NFS mount)
In Part 2 of this article we'll discuss topics like building the Linux Kernel outside of Yocto using a Yocto generated SDK and booting our EVK via TFTP and NFS.
References and Resources
Acronyms and Terms
- SRC: i.MX8 System Reset Controller