We are documenting how we build a Yocto Linux image with the NXP MCIMX8M-EVK evaluation kit for the i.MX 8MQuad processor.

Overview

This article has been updated for NXP's L5.4.24_2.1.0 release. It can be found here.

We just recently began working with the NXP MCIMX8M-EVK evaluation kit for the i.MX 8MQuad processor. It's certainly an amazing system, and there is plenty of documentation. However, we found some of the Yocto Linux related documentation stale and confusing, so we are posting 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 system.

Note that this article is a rough draft, but the basic steps 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).

We also anticipate referring to this article in posts on the Yocto mailing lists and the NXP Community site as we work to develop various custom software components for the i.MX8.

The Yocto Project has fantastic documentation, and there is a lot of it! If you're new to Yocto Project, then start with the Quick Build Guide. And don't overlook What I Wish I'd Known.

Listed below are some of the data points that we need to establish to move forward when building an EVK Yocto image from source:

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 "L4.14.98-2.0.0_ga". This was developed using Yocto Project 2.5 (Sumo).

Sumo was released April 2018. Yocto Project is currently developing a 3.0 release.

The very important meta-fsl-bsp-release Git repo is hosted at https://source.codeaurora.org/external/imx/meta-fsl-bsp-release. This is referred to as the "i.MX release layer" and "i.MX BSP release layer".

i.MX8 only uses the wayland graphics back end

The Yocto Machine (for conf files): imx8mqevk

There is an EVKB and EVK. We are using the EVKB, and this has an upgrade to the WIFI over the EVK. The PCB design files currently posted on nxp.com are not for our EVKB.

NXP MCIMX8M-EVK

Initial Steps

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 Sumo README for some additional details.

Below we install NXP's Yocto Project release in our /opt/nxp folder:

$ mkdir -p /opt/nxp; cd /opt/nxp $ repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-sumo -m imx-4.14.98-2.0.0_ga.xml Get https://gerrit.googlesource.com/git-repo/clone.bundle Get https://gerrit.googlesource.com/git-repo ... Get https://source.codeaurora.org/external/imx/imx-manifest ... repo has been initialized in /opt/nxp_clean $ ls -a . .. .repo $ repo sync ... Fetching project meta-freescale-distro Fetching project meta-openembedded ... Syncing work tree: 100% (9/9), done. $ ls fsl-setup-release.sh README README-IMXBSP setup-environment sources

Create our Yocto Project build environment under the folder bld-wayland:

$ MACHINE=imx8mqevk DISTRO=fsl-imx-wayland source ./fsl-setup-release.sh -b bld-wayland $ pwd /opt/nxp/bld-wayland $ tree . ├── bblayers.conf ├── bblayers.conf.org ├── local.conf ├── local.conf.org ├── local.conf.sample ├── sanity_info └── templateconf.cfg

It may be instructive to realize that the repos / layers under sources are not on a branch and may have been modified during the previous setup:

$ cd /opt/nxp/sources/meta-freescale $ git status Not currently on any branch. ... deleted: conf/machine/imx7ulpevk.conf deleted: conf/machine/include/imx-base.inc

The bitbake command below will build an sdcard image in the deploy folder that we can use to boot our NXP EVK.

$ bitbake fsl-image-qt5-validation-imx

When we want to come back to the build system, we can do the following (or we can use NXP's script):

$ cd /opt/nxp $ source sources/poky/oe-init-build-env bld-wayland/ $ bitbake fsl-image-qt5-validation-imx

Burning our *.sdcard image on an SD Card

Let's first take a look at the image file system types we have configured:

$ bitbake fsl-image-qt5-validation-imx -e | grep ^IMAGE_FSTYPES IMAGE_FSTYPES="tar.bz2 ext4 sdcard.bz2"

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 /opt/nxp/bld-wayland/tmp/deploy/images/imx8mqevk/ $ bunzip2 -vfk fsl-image-qt5-validation-imx-imx8mqevk-<date>.rootfs.sdcard.bz2 $ file fsl-image-qt5-validation-imx-imx8mqevk-<date>.rootfs.sdcard ...: DOS/MBR boot sector; partition 1 : ID=0xc, start-CHS (0x80,0,1), end-CHS (0x3ff,3,32), startsector 16384, 131072 sectors; partition 2 : ID=0x83, start-CHS (0x3ff,3,32), end-CHS (0x3ff,3,32), startsector 147456, 5111808 sectors

If you're curious as to how the sdcard image is created, then take a look in imx8mqevk-poky-linux/fsl-image-qt5-validation-imx/1.0-r0/temp for the "run.do_image_sdcard" and "log.do_image_sdcard" files.

Note that the resulting *.sdcard image is less than 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.

Regarding SD Card size, NXP documentation states that the max rootfs partiton size is 4GB, so we'll have to deal with this soon:

$ ls -lh *.ext4 -rw-r--r-- 2 <user> <group> 2.1G Oct 19 19:03 fsl-image-qt5-validation-imx-imx8mqevk-<date>.rootfs.ext4 ...

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

fsl-image-qt5-validation-imx.bb can be found in meta-fsl-bsp-release/imx/meta-sdk/dynamic-layers/qt5-layer/recipes-fsl/images/

fsl-image-validation-imx.bb can be found in meta-fsl-bsp-release/imx/meta-sdk/recipes-fsl/images/

As you may have noticed, there are now several NXP layers under sources. Here's one way to determine where a recipe is located:

$ cd /opt/nxp/sources $ find . -name 'linux-imx*bb' ./meta-freescale/recipes-kernel/linux/linux-imx_4.9.88.bb ./meta-freescale/recipes-kernel/linux/linux-imx-mfgtool_4.9.88.bb ./meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/linux-imx-headers_4.14.98.bb ./meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/linux-imx_4.14.98.bb

We can see above that the linux-imx_4.14.98.bb recipe is located in the meta-fsl-bsp-release 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 Sumo release.

View the manifest:

$ cd /opt/nxp/bld-wayland/tmp/deploy/images/imx8mqevk $ vi fsl-image-qt5-validation-imx-imx8mqevk.manifest

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 /opt/nxp/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/4.14.98-r0/git/.git/config url = https://source.codeaurora.org/external/imx/linux-imx.git $ grep url imx8mqevk-poky-linux/u-boot-imx/2018.03-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 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 (<ip address>)' can't be established. RSA key fingerprint is SHA256:2VH9IPUxMgCiY4+oxaouDibH7pU3hwJGiKLwt1rUaWo. +---[RSA 2048]----+ | . ...o=.o | |.. . . .. =.o| |= . + . . o.| |+o. o.+. o . .| |. ++o.+.S . | | o++ = . | |o+o E + . | |*o = o o | |=++ | +----[SHA256]-----+ 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 4.14.98-imx_4.14.98_2.0.0_ga+g5d6cbeafb80c #1 SMP PREEMPT Fri Oct 18 01:51:27 UTC 2019 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"

Add package management to our conf/local.conf file:

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.

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: 2.7.5 Command: dnf makecache Installroot: / Releasever: sumo 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, _Handle: metalnk: None, mlist: None, urls ['http://192.168.3.36']. oe-packages 32 MB/s | 2.6 MB 00:00 not found deltainfo for: oe-packages not found updateinfo for: oe-packages oe-packages: using metadata from Sat Oct 19 02:17:31 2019. Last metadata expiration check: 0:00:03 ago on Sat Oct 19 02:18:50 2019. timer: sack setup: 3188 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 validation image and inspect our updated rootfs:

$ bitbake fsl-image-qt5-validation-imx $ cd /opt/nxp/bld-wayland/tmp/work/imx8mqevk-poky-linux/fsl-image-qt5-validation-imx/1.0-r0/rootfs $ find . -name autoconf ./usr/bin/autoconf ./usr/share/autoconf ./usr/share/autoconf/autoconf $ find . -name gcc ./usr/libexec/gcc ./usr/bin/gcc ./usr/lib/gcc

Let's also take a look at the updated manifest after updating the package-index:

$ bitbake package-index $ cd /opt/nxp/bld-wayland/tmp/deploy/images/imx8mqevk/ $ grep autoconf fsl-image-qt5-validation-imx-imx8mqevk.manifest autoconf aarch64 2.69 $ grep cmake fsl-image-qt5-validation-imx-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:

build server:

$ bitbake cmake $ bitbake package-index

imx shell:

# dnf install cmake ... Installed: cmake.aarch64 3.10.3-r0 # cmake --version cmake version 3.10.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 need to move our rootfs off of the SD Card, and we'll address this soon...

imx-boot and u-boot

The imx-boot includes includes SPL, U-Boot, Arm Trusted Firmware, DDR firmware, and HDMI firmware. We will add a section on this once we better understand it.

The following is copied verbatim from the "i.MX Linux User's Guide":

On i.MX 8, the U-Boot cannot boot the device by itself. The i.MX 8 pre-built images or Yocto Project default bootloader is imx-boot for the SD card, which is created by the imx-mkimage. The imx-boot binary includes the Uboot, ARM trusted firmware, DCD file (8QuadMax/8QuadXPlus), system controller firmware (8QuadMax/8QuadXPlus), SPL (8M Quad and 8M Mini), DDR firmware (8M Quad), and HDMI firmware (8M Quad), and SECO firmware for B0 (8QXP/8QuadMax).

On i.MX 8M Quad and 8M Mini, the second program loader (SPL) is enabled in U-Boot. SPL is implemented as the firstlevel bootloader running on TCML (due to OCRAM size limitation). It is used to initialize DDR and load U-Boot, U-Boot DTB, Arm trusted firmware, and TEE OS (optional) from the boot device into the memory. After SPL completes loading the images, it jumps to the Arm trusted firmware BL31 directly. The BL31 starts the optional BL32 (TEE OS) and BL33 (u-boot) for continue booting kernel.

In imx-boot, the SPL is packed with DDR Firmware together, so that ROM can load them into Arm Cortex-M4 TCML. The U-Boot, U-Boot DTB, Arm Trusted firmware, and TEE OS (optional) are packed into a FIT image, which is finally built into imx-boot.

Below we show the U-Boot welcome screen after a reboot via the NXP UART / USB:

U-Boot 2018.03-imx_v2018.03_4.14.98_2.0.0_ga+g87a19df5e4 (Oct 18 2019 - 03:28:59 +0000) CPU: Freescale i.MX8MQ rev2.1 1500 MHz (running at 1000 MHz) CPU: Commercial temperature grade (0C to 95C) at 44C Reset cause: POR Model: Freescale i.MX8MQ EVK DRAM: 3 GiB TCPC: Vendor ID [0x1fc9], Product ID [0x5110], Addr [I2C0 0x50] MMC: FSL_SDHC: 0, FSL_SDHC: 1 ... Display: HDMI (1280x720) ... BuildInfo: - ATF 1cb68fa - U-Boot 2018.03-imx_v2018.03_4.14.98_2.0.0_ga+g87a19df5e4 ...

Let's take a look at our U-Boot environment:

u-boot=> printenv baudrate=115200 boot_fdt=try bootcmd=mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else booti ${loadaddr} - ${fdt_addr}; fi bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else booti ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi; bootdelay=2 bootscript=echo Running bootscript from mmc ...; source console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200 emmc_dev=0 ethaddr=00:04:9f:06:12:fc ethprime=FEC fastboot_dev=mmc1 fdt_addr=0x43000000 fdt_file=fsl-imx8mq-evk.dtb fdt_high=0xffffffffffffffff fdtcontroladdr=fc8fee60 image=Image initrd_addr=0x43800000 initrd_high=0xffffffffffffffff jh_clk= jh_mmcboot=setenv fdt_file fsl-imx8mq-evk-root.dtb; setenv jh_clk clk_ignore_unused; if run loadimage; then run mmcboot; else run jh_netboot; fi; jh_netboot=setenv fdt_file fsl-imx8mq-evk-root.dtb; setenv jh_clk clk_ignore_unused; run netboot; kboot=booti loadaddr=0x40480000 loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}; loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file} loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image} mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused mmcargs=setenv bootargs ${jh_clk} console=${console} root=${mmcroot} mmcautodetect=yes mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else echo wait for boot; fi; mmcdev=1 mmcpart=1 mmcroot=/dev/mmcblk1p2 rootwait rw netargs=setenv bootargs ${jh_clk} console=${console} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${loadaddr} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else booti; fi; script=boot.scr sd_dev=1 soc_type=imx8mq

We'll come back to this when we show NFS boot working.

Customizing the linux-imx kernel

To Be Added...

Customizing the linux-imx device tree

To Be Added...

Building from the Yocto Master Branch

To Be Added...

Kernel Debugging via JTAG

To Be Added...

MIPI CSI-2

One of our use cases for our NXP EVK is to work with custom cameras / imagers via the CSI-2 interface.

We perform some introspection of our live system below:

# dmesg | grep CSI ... [ 2.464352] CSI: Registered sensor subdevice: mxc-mipi-csi2.0 [ 2.494285] CSI: Registered sensor subdevice: mxc-mipi-csi2.1

Let's take a look at the default kernel configuration in our work's linux-imx folder:

excerpt of defconfig:

... CONFIG_VIDEO_V4L2_SUBDEV_API=y ... CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_MXC_CAPTURE=y CONFIG_VIDEO_MX8_CAPTURE=y CONFIG_GMSL_MAX9286=y CONFIG_VIDEO_MXC_CSI_CAMERA=y CONFIG_MXC_MIPI_CSI=y CONFIG_MXC_CAMERA_OV5640_MIPI_V2=y CONFIG_V4L_MEM2MEM_DRIVERS=y ...

Next, we take a look at the kernel's menuconfig to get a feeling on how the MIPI CSI-2 driver support is structured within the source:

$ bitbake linux-imx -c menuconfig

The figure below is a screen shot from our menuconfig window showing us support for the OV5640 camera:

linux-imx menuconfig

Enabling MXC_CAMERA_OV5640_MIPI_V2 pulls in ov5640_mipi_v2.o to our build

Enabling MXC_CAMERA_OV5640_MIPI_V3 pulls in ov5640_mipi_v3.o to our build

Let's check the kernel log:

# dmesg | grep -i mipi [ 2.359569] ov5640_mipi 0-003c: No sensor reset pin available [ 2.365374] ov5640_mipi 0-003c: 0-003c supply DOVDD not found, using dummy regulator [ 2.373231] ov5640_mipi 0-003c: 0-003c supply DVDD not found, using dummy regulator [ 2.380954] ov5640_mipi 0-003c: 0-003c supply AVDD not found, using dummy regulator [ 2.400170] ov5640_mipi 0-003c: Read reg error: reg=300a [ 2.405497] ov5640_mipi 0-003c: Camera is not found [ 2.411174] ov5640_mipi 1-003c: No sensor reset pin available [ 2.417093] ov5640_mipi 1-003c: 1-003c supply DOVDD not found, using dummy regulator [ 2.424956] ov5640_mipi 1-003c: 1-003c supply DVDD not found, using dummy regulator [ 2.432658] ov5640_mipi 1-003c: 1-003c supply AVDD not found, using dummy regulator [ 3.681495] ov5640_mipi 1-003c: Camera is found [ 3.687312] mxc-mipi-csi2_yav 30a70000.mipi_csi1: mipi_csi2_probe [ 3.693526] CSI: Registered sensor subdevice: mxc-mipi-csi2.0 [ 3.699380] mxc-mipi-csi2_yav 30a70000.mipi_csi: Remote device at /mipi_csi1@30a70000/port/endpoint1 XXX found [ 3.709397] mxc-mipi-csi2_yav 30a70000.mipi_csi: Registered sensor subdevice: ov5640_mipi 1-003c [ 3.718258] mxc-mipi-csi2_yav 30a70000.mipi_csi1: lanes: 2, name: mxc-mipi-csi2.0 [ 3.726038] mxc-mipi-csi2_yav 30b60000.mipi_csi2: mipi_csi2_probe [ 3.732263] CSI: Registered sensor subdevice: mxc-mipi-csi2.1 [ 3.738034] mxc-mipi-csi2_yav 30b60000.mipi_csi: Remote device at /mipi_csi2@30b60000/port/endpoint1 XXX found [ 3.748110] mxc-mipi-csi2_yav 30b60000.mipi_csi2: lanes: 2, name: mxc-mipi-csi2.1 [ 129.298745] ov5640_mipi 1-003c: s_stream: 1

The ov5640_mipi device is instantiated from drivers/media/platform/mxc/capture/ov5640_mipi_v2.c.

The mxc-mipi-csi2_yav device is instantiated from drivers/media/platform/imx8/mxc-mipi-csi2_yav.c.

Note that the i.MX8 Reference Manual states MIPI_CSI1 Host Controller (Chapter 13.7) starts at 0x30A7_0000

Let's run gst-launch for the NXP MINISASTOCSI Camera that uses the OV5640 camera. Note that we'll end the pipeline with autovideosink.

# gst-launch-1.0 -v v4l2src ! ‘video/x-raw,width=1920,height=1080’ ! autovideosink

ssh into the iMX and run the following script that we'll call timer.sh:

!/bin/sh cat /proc/interrupts | grep csi sleep 10 cat /proc/interrupts | grep csi

# ./timer.sh 23: 16230 0 0 0 GPC-PSCI 42 Edge csi 24: 0 0 0 0 GPC-PSCI 43 Edge csi 23: 16830 0 0 0 GPC-PSCI 42 Edge csi 24: 0 0 0 0 GPC-PSCI 43 Edge csi

600 interrupts in 10 seconds probably corresponds to 60fps, but we need to dig into the existing CSI-2 driver(s).

Let's use the v4l2-ctl application to introspect the video driver:

# dnf install v4l-utils # v4l2-ctl -d /dev/video0 --all -D --list-formats-ext Driver Info (not using libv4l2): Driver name : mx6s-csi Card type : i.MX6S_CSI Bus info : platform:30a90000.csi1_bridge Driver version: 4.14.98 Capabilities : 0x84200001 Video Capture Streaming Extended Pix Format Device Capabilities Device Caps : 0x04200001 Video Capture Streaming Extended Pix Format Priority: 0 Video input : 0 (Camera: ok) Format Video Capture: Width/Height : 2592/1944 Pixel Format : '' Field : None Bytes per Line : 0 Size Image : 10077696 Colorspace : Default Transfer Function : Default YCbCr/HSV Encoding: Default Quantization : Default Flags : Crop Capability Video Capture: Bounds : Left 0, Top 0, Width 0, Height 0 Default : Left 0, Top 0, Width 0, Height 0 Pixel Aspect: 1/1 Crop: Left 0, Top 0, Width 0, Height 0 Streaming Parameters Video Capture: Capabilities : timeperframe Capture mode : high quality Frames per second: 15.000 (15/1) Read buffers : 0 ioctl: VIDIOC_ENUM_FMT Index : 0 Type : Video Capture Pixel Format: 'YUYV' Name : YUYV 4:2:2 Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 720x480 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 1920x1080 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 2592x1944 Interval: Discrete 0.067s (15.000 fps) Size: Discrete 0x0 # v4l2-ctl --stream-mmap --stream-count=1 --stream-to=file.yuv

Note that the i.MX8 Reference Manual states CSI1 Bridge (Chapter 13.7) starts at 0x30A9_0000

Debugging the I2C Messages to the Camera

Next we rebuild our kernel with the following debug KConf defines active:

CONFIG_I2C_DEBUG_CORE=y CONFIG_I2C_DEBUG_ALGO=y CONFIG_I2C_DEBUG_BUS=y

After a reboot we can see the kernel's debug messages if we configure our console properly:

# cat /proc/sys/kernel/printk 4 4 1 7 # echo '8' > /proc/sys/kernel/printk # cat /proc/sys/kernel/printk 8 4 1 7

Now when we exercise the camera, we see I2C debug messages for writes and reads to the camera. An example is shown below:

i2c i2c-1: master_xfer[0] W, addr=0x3c, len=2 ... i2c i2c-1: <i2c_imx_write> write byte: B0=0x38 ... i2c i2c-1: <i2c_imx_write> write byte: B1=0xD ... i2c i2c-1: master_xfer[0] R, addr=0x3c, len=1 ... i2c i2c-1: <i2c_imx_read> read byte: B0=0x1C

Referring to the OV5640 datasheet, we can see that the i.MX8 read a 0x1c from the TIMING HTS register.

USB 3.0 node via Type-C interface

To Be Added...

References and Resources

Acronyms and Terms

SRC: i.MX8 System Reset Controller

I2C

Although the i.MX8 RM states there are four I2C "channels" available on the device, only three are exposed:

# i2cdetect -l i2c-1 i2c 30a30000.i2c I2C adapter i2c-2 i2c 30a40000.i2c I2C adapter i2c-0 i2c 30a20000.i2c I2C adapter # ls /dev/i2c* /dev/i2c-0 /dev/i2c-1 /dev/i2c-2

We want to work with the i.MX8 driver: i2c/busses/i2c-imx.c

MODULE_LICENSE("GPL"); MODULE_AUTHOR("Darius Augulis"); MODULE_DESCRIPTION("I2C adapter driver for IMX I2C bus"); MODULE_ALIAS("platform:" DRIVER_NAME);

We find that function calls within i2c-mx.c mainly come through the functions in i2c-core-base.c.