NXP has recently updated their MCIMX8M-EVK Yocto BSP to the Linux 5.4.24 kernel. We have found that some of NXP's Yocto Linux related documentation is stale and 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.
Note this this article is an update to our original article for the L4.14 BSP.
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.24_2.1.0". This was developed using the Yocto Project Zeus (3.0) branch / release.
- Zeus 3.0 was released October 2019.
- 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 Get https://gerrit.googlesource.com/git-repo/clone.bundle Get https://gerrit.googlesource.com/git-repo ... repo has been initialized in /build/imx8 $ ls -a . .. .repo $ repo sync ... Fetching projects: 8% (1/12) fsl-community-bsp-baseremote ... Fetching projects: 16% (2/12) meta-python2remote ... Fetching projects: 25% (3/12) meta-timesysremote ... Fetching projects: 41% (5/12) meta-imxremote ... Fetching projects: 66% (8/12) meta-qt5remote ... Fetching projects: 100% (12/12), done. Checking out projects: 100% (12/12), done. repo sync has finished successfully. $ ls imx-setup-release.sh README README-IMXBSP setup-environment sources
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:cba967414370e195d109353e51510bd829aa86c3" meta-oe meta-multimedia meta-python = "HEAD:9e60d30669a2ad0598e9abf0cd15ee06b523986b" meta-freescale = "HEAD:c2a0d924f6200eea1fb1d1b61e7420ea5da2f8fb" meta-freescale-3rdparty = "HEAD:dbcc686f52c3c84db8cb86aa8973a4e373651b98" meta-freescale-distro = "HEAD:ca27d12e4964d1336e662bcc60184bbff526c857" meta-bsp meta-sdk meta-ml = "HEAD:a083ffbbc3f4d1c02b1542746784d7f641a75b60" meta-browser = "HEAD:5f365ef0f842ba4651efe88787cf9c63bc8b6cb3" meta-rust = "HEAD:a012a1027defe28495f06ed522a7a82bdd59a610" meta-gnome meta-networking meta-filesystems = "HEAD:9e60d30669a2ad0598e9abf0cd15ee06b523986b" meta-qt5 = "HEAD:b8bcf8cb576d072f435a0177375e54424f67d1c9" meta-python2 = "HEAD:231c3d74cfcf734c3415e86ea8dd97f73ddced9d"
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 *.sdcard 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 the most robust solution since dd sometimes fails to work as we expect.
We also decompress the *sdcard.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.sdcard.bz2 imx-image-multimedia-imx8mqevk.sdcard.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-<date>.rootfs.sdcard.bz2 $ file imx-image-multimedia-imx8mqevk-<date>.rootfs.sdcard ...: 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, 6252502 sectors
Note that the resulting *.sdcard image is ~3GB, but we expect this to grow significantly once we add a toolchain and other packages. Also note that we get good results using a SanDisk 16GB Ultra microSDHC.
We transfer the resulting "*.sdcard" image to Windows 10 and burn the SD Card using Etcher. 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 :::::::::::::: imx-image-multimedia-imx8mqevk.manifest :::::::::::::: acl aarch64 2.2.52 acl-dev aarch64 2.2.52 adwaita-icon-theme-symbolic noarch 3.32.0 alsa-conf aarch64_mx8m 1.1.9 alsa-plugins-pulseaudio-conf aarch64_mx8m 1.1.9 alsa-state imx8mqevk 0.2.0 alsa-states imx8mqevk 0.2.0 alsa-tools aarch64_mx8m 1.1.7 ...
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.24-2.1.0+gbabac008e5cf #1 SMP PREEMPT Sat Aug 8 03:43:30 UTC 2020 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: 12 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 25 MB/s | 2.8 MB 00:00 ... 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 imx-image-multimedia-imx8mqevk-<date>.rootfs.manifest autoconf aarch64 2.69 $ grep cmake imx-image-multimedia-imx8mqevk-<date>.rootfs.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 over written doesn't make much sense. We will 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