Hello again,
Sadly, our vendor only supports Mender with GRUB. Therefore, we have to integrate it ourselves, but are struggling.
Although the patch above installs the correct environment in the deploy directory, it does not work properly on hardware.
In summary, after flashing the image onto the eMMC with bzcat /home/root/core-image-full-cmdline-iot-gate-imx8-2023.sdimg.bz2 | dd of=/dev/mmcblk2 bs=32M status=progress
,
- the correct U-Boot version shows up
- when adding
u-boot-mender.inc
to u-boot-compulab
, the mender env is built and deployed to one location but uboot.env
is empty, while u-boot-compulab-initial-env-iot-gate-imx8-sd-2021.04-r0
holds the desired environment
- (A) printenv displays the correct environment
- (B) the saveenv command throws an error
- (C) the image is bootable
- (D) inside user space,
fw_printenv
prints an error
- (E) the
sdimg
has its environment at a different location than the previous image, and only 1 time instead of three times
- (F) the environment offset in the
sdimg
is never at the configured offset in the sdimg
, but a hexdump on the mmc inside the user space of the zeus image shows the environment at the desired offsets
- (G) we have made some modifications to
u-boot-compulab
since it does not include Mender by default
- (H) diff between zeus and kirkstone iot-gate-imx8_defconfig
Questions upfront:
- Do we need to force the Mender overhead back to the zeus value?
- Why is uboot.env empty? It is also empty in the older zeus build, but it works in that case. But if I understood your first answer correctly, we don’t need to care about uboot.env, as long as the env is present at 0x800000 and 0x1000000
- Edit: maybe this is an issue because Compulab has provided their own u-boot-fw-utils, while mender appends on libubootenv? I have now removed compulab’s fw-utils, no change.
A: printenv displays the correct environment
IOT-GATE-iMX8 => printenv
altbootcmd=run mender_altbootcmd; run bootcmd
baudrate=115200
bluerange_mender_post_setup_commands=setenv bootargs ${bootargs} rootwait console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200 net.ifnames=0; echo "bootargs set to ${bootargs}"
bluerange_mender_pre_setup_commands=setenv mender_dtb_name "${fdt_file}"; echo "mender_dtb_name set to ${mender_dtb_name}";
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_name}; 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
bootcount=1
bootdelay=2
bootdev=2
bootlimit=1
bootstopkeysha256=<blurred>
ethaddr=00:01:c0:30:3b:41
ethprime=FEC
fastboot_dev=mmc2
fdt_addr_r=0x43000000
fdt_file=sb-iotgimx8.dtb
fdtcontroladdr=b6d20230
kernel_addr_r=0x40480000
loadaddr=0x40480000
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=booti
mender_boot_part=2
mender_boot_part_hex=2
mender_check_saveenv_canary=1
mender_dtb_name=sb-iotgimx8.dtb
mender_kernel_name=Image
mender_post_setup_commands= run bluerange_mender_post_setup_commands;
mender_pre_setup_commands= run bluerange_mender_pre_setup_commands;
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_commands; fi; if test "${mender_systemd_machine_id}" != ""; then setenv bootargs "systemd.machine_id=${mender_systemd_machine_id} ${bootargs}"; fi; setenv mender_kernel_root /dev/mmcblk2p${mender_boot_part}; if test ${mender_boot_part} = 2; then setenv mender_boot_part_name /dev/mmcblk2p2; else setenv mender_boot_part_name /dev/mmcblk2p3; fi; setenv mender_kernel_root_name ${mender_boot_part_name}; setenv mender_uboot_root mmc 2:${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 mender_post_setup_commands; fi
mender_try_to_recover=if test ${upgrade_available} = 1; then reset; fi
mender_uboot_boot=mmc 2:1
mender_uboot_dev=2
mender_uboot_if=mmc
serial#=1a3999aac2a41100
soc_type=imx8mm
upgrade_available=0
Environment size: 2632/131067 bytes
There are some changes in the env compared to zeus. If we try to remove fastboot again, the compilation fails. Also, the an address has changed.
The diff compared to our zeus environment is:
diff --git a/zeus_uboot.env b/kirkstone_uboot.env
index 5393848..1c64ec8 100644
--- a/zeus_uboot.env
+++ b/kirkstone_uboot.env
@@ -8,11 +8,12 @@ bootdelay=2
bootdev=2
bootlimit=1
bootstopkeysha256=<blurred>
-ethaddr=00:01:c0:2a:a6:23
+ethaddr=00:01:c0:30:3b:41
ethprime=FEC
+fastboot_dev=mmc2
fdt_addr_r=0x43000000
fdt_file=sb-iotgimx8.dtb
-fdtcontroladdr=74d29ee0
+fdtcontroladdr=b6d20230
kernel_addr_r=0x40480000
loadaddr=0x40480000
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
@@ -24,10 +25,11 @@ mender_dtb_name=sb-iotgimx8.dtb
mender_kernel_name=Image
mender_post_setup_commands= run bluerange_mender_post_setup_commands;
mender_pre_setup_commands= run bluerange_mender_pre_setup_commands;
-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_commands; fi; if test "${mender_systemd_machine_id}" != ""; then setenv bootargs "systemd.machine_id=${mender_systemd_machine_id} ${bootargs}"; fi; setenv mender_kernel_root /dev/mmcblk2p${mender_boot_part}; if test ${mender_boot_part} = 2; then setenv mender_boot_part_name /dev/mmcblk2p2; else setenv mender_boot_part_name /dev/mmcblk2p3; fi; setenv mender_kernel_root_name ${mender_boot_part_name}; setenv mender_uboot_root mmc 2:${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 mender_post_setup_commands; fi
mender_try_to_recover=if test ${upgrade_available} = 1; then reset; fi
mender_uboot_boot=mmc 2:1
mender_uboot_dev=2
mender_uboot_if=mmc
+serial#=1a3999aac2a41100
+soc_type=imx8mm
upgrade_available=0
B: saveenv throws an error
IOT-GATE-iMX8 => saveenv
Saving Environment to MMC... MMC partition switch failed
MMC partition switch failed
Failed (1)
IOT-GATE-iMX8 =>
C: image is bootable
Out: serial
Err: serial
BuildInfo:
- ATF cb51a0f
FDT[det]: sb-iotgimx8.dtb
flash target is MMC:2
Net: phy: RTL8211E@0 eth0: ethernet@30be0000
Fastboot: Normal
Normal Boot
Autoboot in 2 seconds
Saving Environment to MMC... MMC partition switch failed
MMC partition switch failed
Failed (1)
mender_dtb_name set to sb-iotgimx8.dtb
bootargs set to rootwait console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200 net.ifnames=0
41995 bytes read in 3 ms (13.3 MiB/s)
30073344 bytes read in 627 ms (45.7 MiB/s)
Moving Image from 0x40480000 to 0x40600000, end=423c0000
## Flattened Device Tree blob at 43000000
Booting using the fdt blob at 0x43000000
Loading Device Tree to 00000000b6d11000, end 00000000b6d1e40a ... OK
Modify /vpu_g1@38300000:status disabled
Modify /vpu_g2@38310000:status disabled
Modify /vpu_h1@38320000:status disabled
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.15.32-iot-gate-imx8m-3.2.1+ (oe-user@oe-host) (aarch64-poky-linux-gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.38.20220313) #1 SMP PREEMPT Tue Jul 18 09:22:22 UTC 2023
[ 0.000000] Machine model: CompuLab SB-IOTGIMX8 board
D: inside user space, fw_printenv
prints an error
fw_printenv
does not find the environment
root@localhost:~# fw_printenv
Cannot read environment, using default
Cannot read default environment from file
But the file has the desired offsets
root@localhost:~# cat /etc/fw_env.config
/dev/mmcblk2 0x800000 0x20000
/dev/mmcblk2 0x1000000 0x20000
E: Environment start address in sdimg has changed
- kirkstone: 0xE7800
- zeus: 0xD5988, 0x11455110 and 0x1145F110
These were found with a hex editor and searching the sdimg
for the altbootcmd=
, which is the beginning of our env.
Q:
- Between zeus and kirkstone, we had to reduce the
MENDER_STORAGE_TOTAL_SIZE_MB
from 5272
to 5264
because the mender overhead has increased. Can this cause the increase in the first offset?
In the old zeus image, why are the environments at these locations and not at 0x800000?
When looking at the .wic image, there is something at 0x800000: mkfs.fat .... boot FAT16 ... This is not a bootable disk.
- Also, why are they so close together, unlike specified in redundant offset 0x1000000?
G: our patches and modifications
Our patch is the following: (please note that the bootstopkey is blurred)
diff --git a/include/configs/iot-gate-imx8.h b/include/configs/iot-gate-imx8.h
index 565d53e..ae41f29 100644
--- a/include/configs/iot-gate-imx8.h
+++ b/include/configs/iot-gate-imx8.h
@@ -14,47 +14,29 @@
#endif
#endif
+#define ENV_CONSOLE console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200
+
+// MWAY: U-Boot Environment Settings
+//
+// Required for Mender integration:
+//
+// `fdt_addr_r`: Load address (RAM) of the device tree.
+//
+// `kernel_addr_r`: Load address (RAM) of the kernel image.
+//
+// `bluerange_mender_{pre,post}_setup_commands`:
+// Board specific command sequences to setup environment variables
+// required by menders u-boot integration.
+//
+// Required for BlueRange production:
+//
+// `bootstopkeysha256`: Default 'password' for unlocking the U-Boot CLI.
+
#undef CONFIG_EXTRA_ENV_SETTINGS
-#undef CONFIG_BOOTCOMMAND
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "fdt_addr_r=0x43000000\0" \
+ "kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
+ "bluerange_mender_pre_setup_commands=setenv mender_dtb_name \"${fdt_file}\"; echo \"mender_dtb_name set to ${mender_dtb_name}\";\0" \
+ "bluerange_mender_post_setup_commands=setenv bootargs ${bootargs} rootwait "__stringify(ENV_CONSOLE)" net.ifnames=0; echo \"bootargs set to ${bootargs}\"\0" \
+ "bootstopkeysha256=<blurred>\0"
-#define ENV_CONSOLE console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200
-#define CONFIG_EXTRA_ENV_SETTINGS \
- CONFIG_MFG_ENV_SETTINGS \
- "autoload=off\0" \
- "script=boot.scr\0" \
- "image=Image\0" \
- "fdt_addr=0x43000000\0" \
- "fdt_high=0xffffffffffffffff\0" \
- "initrd_high=0xffffffffffffffff\0" \
- "root_opt=rootwait rw\0" \
- "bootargs_common="__stringify(ENV_CONSOLE)" net.ifnames=0\0" \
- "sd_ul=setenv boot_dev_str SD; run boot_try_msg; " \
- "setenv iface mmc; setenv dev 1; setenv part 1;" \
- "setenv bootargs console=${console} root=/dev/mmcblk1p2 ${root_opt};\0" \
- "emmc_ul=setenv boot_dev_str eMMC; run boot_try_msg; " \
- "setenv iface mmc; setenv dev 2; setenv part 1;" \
- "setenv bootargs ${bootargs_common} root=/dev/mmcblk2p2 " \
- "${root_opt};\0" \
- "usb_ul=setenv boot_dev_str USB; run boot_try_msg; usb reset; " \
- "setenv iface usb; setenv dev 0; setenv part 1; " \
- "setenv bootargs ${bootargs_common} root=/dev/sda2 ${root_opt};\0" \
- "ulbootscript=load ${iface} ${dev}:${part} ${loadaddr} ${script};\0" \
- "ulimage=load ${iface} ${dev}:${part} ${loadaddr} ${image}\0" \
- "ulfdt=load ${iface} ${dev}:${part} ${fdt_addr} ${fdt_file};\0" \
- "bootscript=echo Running bootscript from ${boot_dev_str} ...; " \
- "source;\0" \
- "boot_try_msg=echo Trying to boot from ${boot_dev_str} ...;\0"
-#define CONFIG_BOOTCOMMAND \
- "for src in sd_ul usb_ul emmc_ul; do " \
- "run ${src}; " \
- "if run ulbootscript; then " \
- "run bootscript; " \
- "else " \
- "if run ulimage; then " \
- "if run ulfdt; then " \
- "echo Booting from ${boot_dev_str} script ...; " \
- "booti ${loadaddr} - ${fdt_addr}; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "done; "
diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config
index 988ef9f..10ad3dc 100644
--- a/tools/env/fw_env.config
+++ b/tools/env/fw_env.config
@@ -5,7 +5,25 @@
# Futhermore, if the Flash sector size is omitted, this value is assumed to
# be the same as the Environment size, which is valid for NOR and SPI-dataflash
# Device offset must be prefixed with 0x to be parsed as a hexadecimal value.
-
-# Block devices for CompuLab imx8m-mini
-/dev/mmcblk2boot0 0x4400 0x1000
-#/dev/mmcblk1 0x4400 0x1000
+#
+# == Format
+#
+# ----
+# (Block Device) (Offset in Bytes) (Size in Bytes) [Sector Size] [Sector Count]
+# ----
+#
+# Numbers can be specified in hex with a `0x` prefix.
+#
+# The fields `Sector Size` and `Sector Count` are optional for MMC devices.
+#
+# == BlueRange Gateway V4 - CompuLab IOT-GATE-iMX8
+#
+# Mender on U-Boot, without using GRUB as an intermediate bootloader.
+#
+# The U-Boot image compiled into the .sdimg is setup such that the environment
+# is loaded from the MMC user-partition (i.e. where the boot, root-a, root-b
+# and data partitions of the OS are stored). It lives between the start of the
+# block device and the first partition at the offsets specified below.
+#
+/dev/mmcblk2 0x800000 0x20000
+/dev/mmcblk2 0x1000000 0x20000
We have modified u-boot-compulab_%.bbappend
to look more like the u-boot append from toradex nxp:
FILESEXTRAPATHS:prepend:mender-uboot := "${THISDIR}/compulab/imx8mm:"
include ${@mender_feature_is_enabled("mender-uboot","recipes-bsp/u-boot/u-boot-mender.inc","",d)}
MENDER_UBOOT_AUTO_CONFIGURE:mender-uboot = "1"
# same results without the following 3 lines
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 = "0x800000"
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2 = "0x1000000"
BOOTENV_SIZE = "0x20000"
PROVIDES += "${@mender_feature_is_enabled("mender-uboot","u-boot-default-env","",d)}"
PROVIDES += "${@mender_feature_is_enabled("mender-uboot","u-boot","",d)}"
RPROVIDES:${PN} += "${@mender_feature_is_enabled("mender-uboot","u-boot","",d)}"
PROVIDES += "${@mender_feature_is_enabled("mender-uboot","u-boot-default-env","",d)}"
SRC_URI:append:mender-uboot = " \
file://0200-iot-gate-imx8-config-Add-the-SD-as-a-boot-candidate.patch \
"
H: differences between zeus and kirkstone iot-gate-imx8_defconfig
I have tried the old defconfig, the new and basically everything in between.
--- a/configs/iot-gate-imx8_defconfig
+++ b/configs/iot-gate-imx8_defconfig
@@ -5,27 +5,29 @@
CONFIG_SYS_TEXT_BASE=0x40200000
CONFIG_SPL_GPIO_SUPPORT=y
CONFIG_DM_GPIO=y
+CONFIG_SPL_TEXT_BASE=0x7E1000
CONFIG_TARGET_IOT_GATE_IMX8=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL=y
-CONFIG_CSF_SIZE=0x2000
-CONFIG_SPL_TEXT_BASE=0x7E1000
-CONFIG_LOCALVERSION="-iot-gate-imx8-2.5"
+CONFIG_DEFAULT_DEVICE_TREE="iot-gate-imx8"
+CONFIG_LOCALVERSION="-iot-gate-imx8-3.2"
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh"
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mm-lpddr4.cfg"
-CONFIG_CONSOLE_MUX=y
CONFIG_DEFAULT_FDT_FILE="sb-iotgimx8-can.dtb"
-CONFIG_BOARD_LATE_INIT=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_POWER_SUPPORT=y
+CONFIG_SPL_USB_HOST_SUPPORT=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="IOT-GATE-iMX8 => "
# CONFIG_BOOTM_NETBSD is not set
@@ -47,15 +49,17 @@
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
-CONFIG_EFI_PARTITION=y
CONFIG_OF_CONTROL=y
-CONFIG_DEFAULT_DEVICE_TREE="iot-gate-imx8"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_CLK_IMX8MM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x42800000
+CONFIG_FASTBOOT_BUF_SIZE=0x40000000
+CONFIG_FASTBOOT_FLASH=y
CONFIG_MXC_GPIO=y
CONFIG_CMD_PCA953X=y
CONFIG_DM_PCA953X=y
@@ -78,9 +82,9 @@
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_MXC_UART=y
CONFIG_DM_THERMAL=y
-CONFIG_NXP_TMU=y
CONFIG_USB=y
CONFIG_DM_USB=y
+# CONFIG_DM_USB_GADGET is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="FSL"
@@ -88,12 +92,11 @@
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_CI_UDC=y
CONFIG_SDP_LOADADDR=0x40400000
-CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_SDP=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_EXT4_WRITE=y
-CONFIG_FAT_WRITE=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_ENCRYPTION=y
@@ -101,6 +104,8 @@
CONFIG_ENV_OFFSET=0x800000
CONFIG_ENV_OFFSET_REDUND=0x1000000
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_MMC_ENV_DEV=2
+CONFIG_SYS_MMC_ENV_PART=0
# CONFIG_ENV_IS_NOWHERE is not set
# CONFIG_ENV_IS_IN_EEPROM is not set
# CONFIG_ENV_IS_IN_FAT is not set
@@ -122,7 +127,7 @@
# CONFIG_BOOTCOUNT_RAM is not set
# CONFIG_BOOTCOUNT_I2C is not set
# CONFIG_BOOTCOUNT_AT91 is not set
+# CONFIG_BOOTCOUNT_MEM is not set
# CONFIG_BOOTCOUNT_ALEN is not set
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y
-# CONFIG_BOOTCOMMAND is not set
I know this is a lot. Would appreciate any hint so we can dig deeper.
Best regards,
Dominik