i.MX6ULL Integration woes

Here is the mender patched u-boot environment:

U-Boot 2017.03-imx_v2017.03_4.9.88_2.0.0_ga+gb76bb1b (May 03 2019 - 15:56:36 +0100)

CPU:   Freescale i.MX6ULL rev1.0 at 396MHz
CPU:   Commercial temperature grade (0C to 95C) at 35C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT43AB (480x272)
Video: 480x272x24
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc1 is current device
Net:   eth1: ethernet@020b4000 [PRIME], eth0: ethernet@02188000
Normal Boot
Hit any key to stop autoboot:  0 
36245 bytes read in 106 ms (333 KiB/s)
load - load binary file from a filesystem

Usage:
load <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
    - Load binary file 'filename' from partition 'part' on device
       type 'interface' instance 'dev' to address 'addr' in memory.
      'bytes' gives the size to load in bytes.
      If 'bytes' is 0 or omitted, the file is read until the end.
      'pos' gives the file byte position to start reading from.
      If 'pos' is 0 or omitted, the file is read from the start.
Bad Linux ARM zImage magic!
=> printenv
altbootcmd=run mender_altbootcmd; run bootcmd
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootargs=root=/dev/mmcblk1p2
bootcmd=run mender_setup; setenv bootargs root=${mender_kernel_root} ${bootargs}; if test "${fdt_addr_r}" != ""; then load ${mender_uboot_root} ${fdt_addr_r} /boot/${mender_dtb_nam
e}; fi; load ${mender_uboot_root} ${kernel_addr_r} /boot/${mender_kernel_name}; ${mender_boot_kernel_type} ${kernel_addr_r} - ${fdt_addr_r}; run mender_try_to_recover
bootcmd_mfg=run mfgtool_args; if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi;
bootcount=1
bootdelay=3
bootlimit=1
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
eth1addr=00:04:9f:05:0b:24
ethact=ethernet@020b4000
ethaddr=00:04:9f:05:0b:23
ethprime=eth1
fdt_addr_r=0x83000000
fdt_file=undefined
fdt_high=0xffffffff
fdtcontroladdr=9ef210f8
fileaddr=83000000
filesize=8d95
findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $boa
rd_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
mender_altbootcmd=if test ${mender_boot_part} = 2; then setenv mender_boot_part 3; setenv mender_boot_part_hex 3; else setenv mender_boot_part 2; setenv mender_boot_part_hex 2; fi;
 setenv upgrade_available 0; saveenv; run mender_setup
mender_boot_kernel_type=bootz
mender_boot_part=2
mender_boot_part_hex=2
mender_boot_part_name=/dev/mmcblk1p2
mender_check_saveenv_canary=1
mender_dtb_name=imx6ull-14x14-evk.dtb
mender_kernel_name=zImage
mender_kernel_root=/dev/mmcblk1p2
mender_kernel_root_name=/dev/mmcblk1p2
mender_saveenv_canary=1
mender_setup=if test "${mender_saveenv_canary}" != "1"; then setenv mender_saveenv_canary 1; saveenv; fi; if test "${mender_pre_setup_commands}" != ""; then run mender_pre_setup_co
mmands; fi; setenv mender_kernel_root /dev/mmcblk1p${mender_boot_part}; if test ${mender_boot_part} = 2; then setenv mender_boot_part_name /dev/mmcblk1p2; else setenv mender_boot_p
art_name /dev/mmcblk1p3; fi; setenv mender_kernel_root_name ${mender_boot_part_name}; setenv mender_uboot_root mmc 1:${mender_boot_part_hex}; setenv mender_uboot_root_name ${mender
_boot_part_name}; setenv expand_bootargs "setenv bootargs \\"${bootargs}\\""; run expand_bootargs; setenv expand_bootargs; if test "${mender_post_setup_commands}" != ""; then run m
ender_post_setup_commands; fi
mender_try_to_recover=if test ${upgrade_available} = 1; then reset; fi
mender_uboot_boot=mmc 1:1
mender_uboot_dev=1
mender_uboot_if=mmc
mender_uboot_root=mmc 1:2
mender_uboot_root_name=/dev/mmcblk1p2
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_st
orage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused 
mmcargs=setenv bootargs console=${console},${baudrate} 
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_
fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1
mmcpart=1
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} 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} ${image}; if test ${tee} = yes; then ${g
et_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} $
{fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
panel=TFT43AB
script=boot.scr
tee=no
tee_addr=0x84000000
tee_file=uTee-6ullevk
upgrade_available=0

Environment size: 4766/131067 bytes

Here is the “stock” u-boot environment:

U-Boot 2017.03-imx_v2017.03_4.9.88_2.0.0_ga+gb76bb1bf9f (Dec 03 2018 - 16:19:18 +0000)

CPU:   Freescale i.MX6ULL rev1.0 at 396MHz
CPU:   Commercial temperature grade (0C to 95C) at 36C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

Display: TFT43AB (480x272)
Video: 480x272x24
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc1 is current device
Net:   
Warning: ethernet@020b4000 using MAC address from ROM
eth1: ethernet@020b4000 [PRIME]
Warning: ethernet@02188000 using MAC address from ROM
, eth0: ethernet@02188000
Normal Boot
Hit any key to stop autoboot:  0 
=> printenv
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else r
un netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args; if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi;
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
eth1addr=00:04:9f:05:0b:24
ethact=ethernet@020b4000
ethaddr=00:04:9f:05:0b:23
ethprime=eth1
fdt_addr=0x83000000
fdt_file=undefined
fdt_high=0xffffffff
fdtcontroladdr=9ef400f8
findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $boa
rd_rev = 14X14; then setenv fdt_file theopolis.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_st
orage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused 
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_
fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1
mmcpart=1
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} 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} ${image}; if test ${tee} = yes; then ${g
et_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} $
{fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
panel=TFT43AB
script=boot.scr
tee=no
tee_addr=0x84000000
tee_file=uTee-6ullevk

Environment size: 2973/8188 bytes

mender autopatch adds kernel_addr_r variable which is not present in your env. So as @mirzak suggested pls add patch to u-boot which add this variable then everything will be fine.

I have worked on several boards that did not have these variables set. In most cases there is another variable that is used instead. In this case I use MENDER_UBOOT_PRE_SETUP_COMMANDS to get kernel_addr_r setup. See for example https://github.com/mendersoftware/meta-mender-community/blob/432ea642fe05c4667190d887c78beaddfcbec5b7/meta-mender-variscite/recipes-bsp/u-boot/u-boot-variscite-mender-common.inc#L13

2 Likes

Thanks, this looks cleaner than a patch. I’ll give this a go.

Curios if it worked out @brianPTL?

I am also curious what type of board you are integrating and if it is a candidate to share in to our existing reference integrations, https://hub.mender.io/c/board-integrations/yocto-project

Still working on it now.

I can now boot the board and it shows up on the demo server. I tried an update and it failed with:

update: can not install: No match between boot and root partitions.: exit status 1

Which I am looking in to.

My board is a custom board with an i.MX6ULL chip, but I have been using an nxp dev kit ( link) first so that I am closer to other examples, e.g. toradex.

I would be happy to share the EVK integration once it’s fully working.

This is our first integration of Mender, and in fact our first trial of an off-the-shelf OTA updater. If we like Mender then I can see us integrating more boards.

We use a wide range of EVKs to kick off custom board designs. My last project used an i.MX6Q board and I have an i.MX8 board arriving soon for another project. We have done SAMA5D44 designs recently too so having the board support in a single place that is community/peer reviewed would be great.

We have a wide range of customers so having the SaaS server option is good since some will want that option.

My current error is that I cannot seem to run fw_printenv:

fw_printenv 
Cannot open /dev/mmcblk0: No such file or directory

Frustratingly this does not work on my custom board, but does work on my EVK build. If there’s a difference between the build configs then I am obviously missing it. Any clues as to where fw_printenv gets this path?

I’m using the following in machine.conf:

MENDER_STORAGE_DEVICE = "/dev/mmcblk1"

edit:

mount looks as follows:

/dev/mmcblk1p2 on / type ext4 (rw,relatime,data=ordered)

...

/dev/mmcblk1p4 on /data type ext4 (rw,relatime,data=ordered)
/dev/mmcblk1p1 on /uboot type vfat (rw,relatime,sync,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

edit2:

Dev Kit:

cat /etc/fw_env.config 
/dev/mmcblk1 0x800000 0x20000
/dev/mmcblk1 0x1000000 0x20000

Custom board:

cat fw_env.config 
/dev/mmcblk0 0x800000 0x20000
/dev/mmcblk0 0x1000000 0x20000

So the file is wrong, still trying to find the cause…

cat fw_env.config
/dev/mmcblk0 0x800000 0x20000
/dev/mmcblk0 0x1000000 0x20000
So the file is wrong, still trying to find the cause…

Hm, odd. It should come straight from the MENDER_STORAGE_DEVICE variable.

What does the following give you:

bitbake core-image-base -e | grep -E "^PREFERRED_PROVIDER_u-boot-fw-utils|^PREFERRED_RPROVIDER_u-boot-fw-utils"

I get:

PREFERRED_PROVIDER_u-boot-fw-utils="u-boot-fw-utils-mender-auto-provided"
PREFERRED_RPROVIDER_u-boot-fw-utils="u-boot-fw-utils-mender-auto-provided"

I saw the file change after I did a clean on the u-boot, e.g.:

cat ./cortexa7hf-neon-poky-linux-gnueabi/u-boot-fw-utils-mender-auto-provided/1.0-r0/fw_env.config
/dev/mmcblk0 0x800000 0x20000
/dev/mmcblk0 0x1000000 0x20000

bitbake u-boot-fw-utils-mender-auto-provided u-boot-imx -c cleanall
bitbake myimage

cat ./cortexa7hf-neon-poky-linux-gnueabi/u-boot-fw-utils-mender-auto-provided/1.0-r0/fw_env.config
/dev/mmcblk1 0x800000 0x20000
/dev/mmcblk1 0x1000000 0x20000

So I’m not convinced the image is pulling in the correct files.

edit: pasted the wrong thing

Cleaning the image and rebuilding seems to have changed some files.

I’m away from the board until Thursday and then I’ll pick it up again.

I have it working now against the demo server. I was just a Yocto funny - cleaning the image and building again flushed it all out.

Thanks for the help, going to play around with it a bit now.

Great to hear, thanks for reporting back!

Here are the important bits:

PREFERRED_PROVIDER_u-boot = "u-boot-imx"
PREFERRED_RPROVIDER_u-boot = "u-boot-imx"

MENDER_STORAGE_DEVICE = "/dev/mmcblk1"

MENDER_STORAGE_TOTAL_SIZE_MB = "7580"

IMAGE_BOOT_FILES ?= "u-boot.imx"

IMAGE_BOOT_FILES = "zImage your-dtb-file-here.dtb"

IMAGE_BOOTLOADER_BOOTSECTOR_OFFSET = "2"
IMAGE_BOOTLOADER_FILE = "u-boot.imx"

MENDER_UBOOT_PRE_SETUP_COMMANDS = " \
    setenv kernel_addr_r \${loadaddr}; \
"

IMAGE_FSTYPES_remove += "sdcard.bz2"

I also had to patch u-boot:

sources/meta-freescale-your-layer/recipes-bsp/u-boot/u-boot-imx_%.bbappend file:

require recipes-bsp/u-boot/u-boot-mender.inc

FILESEXTRAPATHS_prepend := "${THISDIR}/patches:"

# GCC Patch - see https://groups.google.com/a/lists.mender.io/forum/#!topic/mender/p54Sv7nbfjk
SRC_URI += "file://default-gcc.patch"

sources/meta-freescale-your-layer/recipes-bsp/u-boot/patches/default-gcc.patch:

OE needs to be able to change the default compiler. If we pass in HOSTCC
through the make command, it overwrites not only this setting but also the
setting in tools/Makefile wrapped in ifneq ($(CROSS_BUILD_TOOLS),) which
breaks the build.

We therefore use override to ensure the value of HOSTCC is overwritten when
needed.

RP: Updated the patch to the version being submitted to upstream u-boot

Upstream-Status: Submitted [emailed to Masahiro Yamada for discussion]
RP 2017/3/11

Index: git/tools/Makefile
===================================================================
--- git.orig/tools/Makefile
+++ git/tools/Makefile
@@ -262,7 +262,7 @@ $(LICENSE_H): $(obj)/bin2header $(srctre
 subdir- += env

 ifneq ($(CROSS_BUILD_TOOLS),)
-HOSTCC = $(CC)
+override HOSTCC = $(CC)

 quiet_cmd_crosstools_strip = STRIP   $^
       cmd_crosstools_strip = $(STRIP) $^; touch $@
Index: git/tools/env/Makefile
===================================================================
--- git.orig/tools/env/Makefile
+++ git/tools/env/Makefile
@@ -8,7 +8,7 @@
 # fw_printenv is supposed to run on the target system, which means it should be
 # built with cross tools. Although it may look weird, we only replace "HOSTCC"
 # with "CC" here for the maximum code reuse of scripts/Makefile.host.
-HOSTCC = $(CC)
+override HOSTCC = $(CC)

 # Compile for a hosted environment on the target
 HOST_EXTRACFLAGS  = $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \
1 Like

Would be great if you could convert your notes to an PR here, https://github.com/mendersoftware/meta-mender-community

:smiley:

1 Like

Is there a best-practice example to copy? Sometimes there are many ways to do things in Yocto and I would want to do it the best way.

Take a look here,

https://hub.mender.io/t/about-the-yocto-project-category/54/8

And I guess the git log is pretty good to look at for examples, e.g

https://github.com/mendersoftware/meta-mender-community/commits/sumo/meta-mender-nxp

The best way is very individual :slight_smile:

I am trying to get the PR and instructions done for this board now(link). Previously I was using my custom board which worked, but now that I am trying to adhere to the meta-mender-community structure I am getting this error:

ERROR: Task do_patch in /home/ecocel/mender-imx6ull/sources/meta-mender/meta-mender-core/recipes-bsp/u-boot/u-boot-fw-utils-mender-auto-provided_1.0.bb depends upon non-existent task do_mender_tar_src in /home/ecocel/mender-imx6ull/sources/meta-fsl-bsp-release/imx/meta-bsp/recipes-bsp/u-boot/u-boot-imx_2017.03.bb
ERROR: Command execution failed: 1

My structure is here: https://github.com/brianleePTL/meta-mender-community/tree/rocko/meta-mender-nxp-imx6ull

Any clues?

Can you post the resulting local.conf, you typically get this if you do not have

INHERIT += "mender-full"

or lacking require recipes-bsp/u-boot/u-boot-mender.inc in U-boot fork recipe, but this you seem to have so I suspect the first mentioned.

Thanks for the reply.

I think I solved it

I ran:

bitbake-layers show-appends | grep -i u-boot

and got:

u-boot-fw-utils_2017.09.bb:
/home/brian/mender-imx6ull/sources/meta-mender/meta-mender-core/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend
u-boot-fslc_2017.11.bb (skipped):
/home/brian/mender-imx6ull/sources/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-fslc_%.bbappend
u-boot_2017.09.bb (skipped):
/home/brian/mender-imx6ull/sources/meta-mender/meta-mender-core/recipes-bsp/u-boot/u-boot_%.bbappend

So I discovered I had missed adding my new layer to the bblayers.conf.sample file - doh!