I think you will need to create a custom boot.scr file. You can see how that is done for another RpI variant here.
This looks quite similar to what i have in my boot.scr:
fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs
run mender_setup
mmc dev ${mender_uboot_dev}
if load ${mender_uboot_root} ${kernel_addr_r} /boot/zImage; then
bootz ${kernel_addr_r} - ${fdt_addr}
elif load ${mender_uboot_root} ${kernel_addr_r} /boot/uImage; then
bootm ${kernel_addr_r} - ${fdt_addr}
else
echo "No bootable Kernel found."
fi
run mender_try_to_recover
# Recompile with:
# mkimage -C none -A arm -T script -d boot.cmd boot.scr
What i’m really looking for is the boot command for the kernel, not the boot script for u-boot. In case that can be relevant, here’s the last log i get before kernel handoff and no more serial input:
U-Boot 2021.07-rc2-00175-g7a1638c263-dirty (May 20 2021 - 00:43:37 +0200)
DRAM: 7.9 GiB
RPI 4 Model B (0xd03114)
MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... In: serial
Out: serial
Err: serial
Net: eth0: ethernet@7d580000
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
starting USB...
Bus xhci_pci: Register 5000420 NbrPorts 5
Starting the controller
USB XHCI 1.00
scanning bus xhci_pci for devices... 5 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
Hit any key to stop autoboot: 0
Saving Environment to FAT... OK
49090 bytes read in 1 ms (46.8 MiB/s)
6694592 bytes read in 25 ms (255.4 MiB/s)
## Booting kernel from Legacy Image at 00080000 ...
Image Name: Linux kernel
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 6694528 Bytes = 6.4 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02600000
Booting using the fdt blob at 0x2600000
Loading Kernel Image
Using Device Tree in place at 02600000, end 0260efc1
Starting kernel ...
The boot script for U-Boot is what defines the boot cmd for the kernel. If you need to modify the bootargs you can do so in the boot script before it calls boot*. The run mender_setup
line should set the values for that. You can always run it by hand to see what it ends up with and how it will need to be modified.
Drew
rootwait
was the missing parameter, it’s not even documented on the official raspi docs…
Hit any key to stop autoboot: 0
U-Boot> setenv bootargs 'root=/dev/sda2 rootfstype=ext4 rootwait'
U-Boot> boot
Thanks for your help !! I’ll try to post a final working patch for usb boot when i get some free time
The forum does not let me upload the .diff file, so here it is:
Activate Mender and USB boot from vanilla u-boot repo
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index 47ea466454..0090c62b31 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -59,3 +59,11 @@ CONFIG_PHYS_TO_BUS=y
CONFIG_ADDR_MAP=y
CONFIG_SYS_NUM_ADDR_MAP=2
CONFIG_OF_LIBFDT_OVERLAY=y
+
+CONFIG_ENV_FAT_INTERFACE="usb"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+# CONFIG_ENV_IS_IN_MMC=y
+# CONFIG_ENV_OFFSET=0x400000
+# CONFIG_ENV_OFFSET_REDUND=0x800000
+# CONFIG_PREBOOT="usb start; load usb 0 $kernel_addr_r /u-boot_splash.bmp; bmp display $kernel_addr_r m m; load usb 0:1 ${kernel_addr_r} /uboot.env; env import -c ${kernel_addr_r} 0x4000;"
+# CONFIG_PREBOOT="usb start; load usb 0 $kernel_addr_r ; load usb 0:1 ${kernel_addr_r} /uboot.env; env import -c ${kernel_addr_r} 0x4000;"
diff --git a/include/config_mender.h b/include/config_mender.h
new file mode 100644
index 0000000000..3377ab0a1b
--- /dev/null
+++ b/include/config_mender.h
@@ -0,0 +1,98 @@
+/*
+ Copyright 2017 Northern.tech AS
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef HEADER_CONFIG_MENDER_H
+#define HEADER_CONFIG_MENDER_H
+
+/* Avoid Mender specific code if we are just probing for configuration. */
+#ifndef MENDER_AUTO_PROBING
+
+#include <config_mender_defines.h>
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+# error A CONFIG_ENV_IS_IN_<storage-type> define is required for Mender to work. For standard Mender setups this should be CONFIG_ENV_IS_IN_MMC for HD/SSD/MMC/SD storage setup, and CONFIG_ENV_IS_IN_UBI for Flash/UBI storage.
+#endif
+
+#ifndef CONFIG_BOOTCOUNT_LIMIT
+# error CONFIG_BOOTCOUNT_LIMIT is required for Mender to work. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>
+#endif
+
+/* Currently Mender needs bootcount to reside in environment. */
+#ifndef CONFIG_BOOTCOUNT_ENV
+# error CONFIG_BOOTCOUNT_ENV is required for Mender to work. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>
+#endif
+
+#ifndef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+# error CONFIG_SYS_REDUNDAND_ENVIRONMENT is required for Mender to work. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>. Check also https://docs.mender.io/troubleshoot/yocto-project-build for Known Issues when upgrading.
+#endif
+
+#ifdef MENDER_UBI
+# ifndef CONFIG_MTDIDS_DEFAULT
+# define CONFIG_MTDIDS_DEFAULT MENDER_MTDIDS
+# endif
+# ifndef CONFIG_MTDPARTS_DEFAULT
+# define CONFIG_MTDPARTS_DEFAULT "mtdparts=" ## MENDER_MTDPARTS
+# endif
+# ifndef CONFIG_ENV_UBI_PART
+# define CONFIG_ENV_UBI_PART MENDER_MTD_UBI_DEVICE_NAME
+# endif
+# ifndef CONFIG_ENV_UBI_VOLUME
+# define CONFIG_ENV_UBI_VOLUME "u-boot-env-1"
+# endif
+# ifndef CONFIG_ENV_UBI_VOLUME_REDUND
+# define CONFIG_ENV_UBI_VOLUME_REDUND "u-boot-env-2"
+# endif
+#else
+# if defined(CONFIG_ENV_OFFSET)
+# if CONFIG_ENV_OFFSET != MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1
+# error CONFIG_ENV_OFFSET is not the same as MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1. Either set it to the same value (check for example in the defconfig file), or make sure it is not defined at all. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>. Check also https://docs.mender.io/troubleshoot/yocto-project-build for Known Issues when upgrading.
+# endif
+# else
+# define CONFIG_ENV_OFFSET MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1
+# endif
+# if defined(CONFIG_ENV_OFFSET_REDUND)
+# if CONFIG_ENV_OFFSET_REDUND != MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2
+# error CONFIG_ENV_OFFSET_REDUND is not the same as MENDER_ENV_OFFSET_REDUND. Either set it to the same value (check for example in the defconfig file), or make sure it is not defined at all. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>. Check also https://docs.mender.io/troubleshoot/yocto-project-build for Known Issues when upgrading.
+# endif
+# else
+# define CONFIG_ENV_OFFSET_REDUND MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2
+# endif
+# ifdef CONFIG_SYS_MMC_ENV_DEV
+# if CONFIG_SYS_MMC_ENV_DEV != MENDER_UBOOT_STORAGE_DEVICE
+# error CONFIG_SYS_MMC_ENV_DEV is not the same as MENDER_UBOOT_STORAGE_DEVICE. Either set it to the same value (check for example in the defconfig file), or make sure it is not defined at all. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>
+# endif
+# else
+# define CONFIG_SYS_MMC_ENV_DEV MENDER_UBOOT_STORAGE_DEVICE
+# endif
+# ifndef CONFIG_SYS_MMC_ENV_PART
+ /* Use MMC partition zero to select whole user area of memory card. */
+# define CONFIG_SYS_MMC_ENV_PART 0
+# endif
+#endif
+
+#ifdef CONFIG_ENV_SIZE
+# if MENDER_BOOTENV_SIZE != CONFIG_ENV_SIZE
+# error 'CONFIG_ENV_SIZE' define must be equal to bitbake variable 'BOOTENV_SIZE' set in U-Boot build recipe.
+# endif
+#else
+# define CONFIG_ENV_SIZE MENDER_BOOTENV_SIZE
+#endif
+
+#endif /* !MENDER_AUTO_PROBING */
+
+#endif /* HEADER_CONFIG_MENDER_H */
diff --git a/include/config_mender_defines.h b/include/config_mender_defines.h
new file mode 100644
index 0000000000..1bb2aec7fb
--- /dev/null
+++ b/include/config_mender_defines.h
@@ -0,0 +1,33 @@
+/* AUTOGENERATED FILE - DO NOT EDIT! */
+/* This file is provided by the meta-mender layer. */
+
+#ifndef HEADER_CONFIG_MENDER_DEFINES_H
+#define HEADER_CONFIG_MENDER_DEFINES_H
+
+/* Shell variables */
+#define MENDER_BOOT_PART_NUMBER 1
+#define MENDER_BOOT_PART_NUMBER_HEX 1
+#define MENDER_ROOTFS_PART_A_NUMBER 2
+#define MENDER_ROOTFS_PART_A_NUMBER_HEX 2
+#define MENDER_ROOTFS_PART_B_NUMBER 3
+#define MENDER_ROOTFS_PART_B_NUMBER_HEX 3
+#define MENDER_UBOOT_STORAGE_INTERFACE "usb"
+// #define MENDER_UBOOT_STORAGE_INTERFACE "mmc"
+#define MENDER_UBOOT_STORAGE_DEVICE 0
+
+/* BB variables. */
+#define MENDER_STORAGE_DEVICE_BASE "/dev/sda"
+#define MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 0x400000
+#define MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2 0x800000
+#define MENDER_ROOTFS_PART_A_NAME "/dev/sda2"
+#define MENDER_ROOTFS_PART_B_NAME "/dev/sda3"
+
+/* For sanity checks. */
+#define MENDER_BOOTENV_SIZE 0x4000
+
+#define MENDER_BOOT_KERNEL_TYPE "bootm"
+#define MENDER_KERNEL_NAME "kernel7l-uboot.img"
+#define MENDER_DTB_NAME "bcm2711-rpi-4-b.dtb"
+#define MENDER_UBOOT_PRE_SETUP_COMMANDS ""
+#define MENDER_UBOOT_POST_SETUP_COMMANDS ""
+#endif /* !HEADER_CONFIG_MENDER_DEFINES_H */
\ No newline at end of file
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 834f1cd236..3eb3faac47 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -97,6 +97,9 @@
/* Environment */
#define CONFIG_SYS_LOAD_ADDR 0x1000000
+#define CONFIG_BOOTCOUNT_LIMIT
+#define CONFIG_BOOTCOUNT_ENV
+
/* Shell */
/* ATAGs support for bootm/bootz */
diff --git a/include/env_default.h b/include/env_default.h
index 1ddd64ba8f..5343964cb0 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ -8,6 +8,7 @@
*/
#include <env_callback.h>
+#include <env_mender.h>
#include <linux/stringify.h>
#ifdef DEFAULT_ENV_INSTANCE_EMBEDDED
@@ -24,6 +25,7 @@ uchar default_environment[] = {
#else
const uchar default_environment[] = {
#endif
+ MENDER_ENV_SETTINGS
#ifndef CONFIG_USE_DEFAULT_ENV_FILE
#ifdef CONFIG_ENV_CALLBACK_LIST_DEFAULT
ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT "\0"
@@ -34,8 +36,8 @@ const uchar default_environment[] = {
#ifdef CONFIG_USE_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
-#ifdef CONFIG_BOOTCOMMAND
- "bootcmd=" CONFIG_BOOTCOMMAND "\0"
+#ifdef CONFIG_MENDER_BOOTCOMMAND
+ "bootcmd=" CONFIG_MENDER_BOOTCOMMAND "\0"
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
"ramboot=" CONFIG_RAMBOOTCOMMAND "\0"
diff --git a/include/env_mender.h b/include/env_mender.h
new file mode 100644
index 0000000000..261775afd5
--- /dev/null
+++ b/include/env_mender.h
@@ -0,0 +1,156 @@
+/*
+ Copyright 2017 Northern.tech AS
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef HEADER_ENV_MENDER_H
+#define HEADER_ENV_MENDER_H
+
+/* Avoid Mender specific code if we are just probing for configuration. */
+#ifdef MENDER_AUTO_PROBING
+#define MENDER_ENV_SETTINGS
+#else
+
+#include <config_mender_defines.h>
+
+#ifdef MENDER_NO_DEFAULT_ALTBOOTCMD
+# define MENDER_DEFAULT_ALTBOOTCMD
+#else
+# define MENDER_DEFAULT_ALTBOOTCMD "altbootcmd=run mender_altbootcmd; " \
+ "run bootcmd\0"
+#endif
+
+#ifdef MENDER_UBI
+# define MENDER_UBI_SETTINGS \
+ "mender_mtd_ubi_dev_name=" MENDER_MTD_UBI_DEVICE_NAME "\0"
+#else
+# define MENDER_UBI_SETTINGS
+#endif
+
+#define MENDER_ENV_SETTINGS \
+ MENDER_DEFAULT_ALTBOOTCMD \
+ MENDER_UBI_SETTINGS \
+ \
+ "bootlimit=1\0" \
+ "bootcount=0\0" \
+ \
+ "upgrade_available=0\0" \
+ \
+ "mender_boot_part=" __stringify(MENDER_ROOTFS_PART_A_NUMBER) "\0" \
+ \
+ "mender_boot_part_hex=" __stringify(MENDER_ROOTFS_PART_A_NUMBER_HEX) "\0" \
+ \
+ "mender_uboot_boot=" MENDER_UBOOT_STORAGE_INTERFACE " " __stringify(MENDER_UBOOT_STORAGE_DEVICE) ":" __stringify(MENDER_BOOT_PART_NUMBER_HEX) "\0" \
+ \
+ "mender_uboot_if=" MENDER_UBOOT_STORAGE_INTERFACE "\0" \
+ \
+ "mender_uboot_dev=" __stringify(MENDER_UBOOT_STORAGE_DEVICE) "\0" \
+ \
+ "mender_boot_kernel_type=" MENDER_BOOT_KERNEL_TYPE "\0" \
+ \
+ "mender_kernel_name=" MENDER_KERNEL_NAME "\0" \
+ \
+ "mender_dtb_name=" MENDER_DTB_NAME "\0" \
+ \
+ "mender_pre_setup_commands=" MENDER_UBOOT_PRE_SETUP_COMMANDS "\0" \
+ \
+ "mender_post_setup_commands=" MENDER_UBOOT_POST_SETUP_COMMANDS "\0" \
+ \
+ "mender_check_saveenv_canary=1\0" \
+ \
+ "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 " MENDER_STORAGE_DEVICE_BASE "${mender_boot_part}; " \
+ "if test ${mender_boot_part} = " __stringify(MENDER_ROOTFS_PART_A_NUMBER) "; " \
+ "then " \
+ "setenv mender_boot_part_name " MENDER_ROOTFS_PART_A_NAME "; " \
+ "else " \
+ "setenv mender_boot_part_name " MENDER_ROOTFS_PART_B_NAME "; " \
+ "fi; " \
+ "setenv mender_kernel_root_name ${mender_boot_part_name}; " \
+ "setenv mender_uboot_root " MENDER_UBOOT_STORAGE_INTERFACE " " __stringify(MENDER_UBOOT_STORAGE_DEVICE) ":${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\0" \
+ \
+ "mender_altbootcmd=" \
+ "if test ${mender_boot_part} = " __stringify(MENDER_ROOTFS_PART_A_NUMBER) "; " \
+ "then " \
+ "setenv mender_boot_part " __stringify(MENDER_ROOTFS_PART_B_NUMBER) "; " \
+ "setenv mender_boot_part_hex " __stringify(MENDER_ROOTFS_PART_B_NUMBER_HEX) "; " \
+ "else " \
+ "setenv mender_boot_part " __stringify(MENDER_ROOTFS_PART_A_NUMBER) "; " \
+ "setenv mender_boot_part_hex " __stringify(MENDER_ROOTFS_PART_A_NUMBER_HEX) "; " \
+ "fi; " \
+ "setenv upgrade_available 0; " \
+ "saveenv; " \
+ "run mender_setup\0" \
+ \
+ "mender_try_to_recover=" \
+ "if test ${upgrade_available} = 1; " \
+ "then reset; " \
+ "fi\0"
+
+#ifdef MENDER_UBI
+# define MENDER_BOOTARGS \
+ "setenv bootargs root=${mender_kernel_root} " \
+ "${mtdparts} " \
+ "ubi.mtd=${mender_mtd_ubi_dev_name} " \
+ "rootfstype=ubifs " \
+ "${bootargs}; "
+# define MENDER_LOAD_KERNEL_AND_FDT \
+ "ubi part ${mender_mtd_ubi_dev_name}; " \
+ "ubifsmount ${mender_uboot_root_name}; " \
+ "if test \"${fdt_addr_r}\" != \"\"; then " \
+ "ubifsload ${fdt_addr_r} /boot/${mender_dtb_name}; " \
+ "fi; " \
+ "ubifsload ${kernel_addr_r} /boot/${mender_kernel_name}; "
+#else
+# define MENDER_BOOTARGS \
+ "setenv bootargs root=${mender_kernel_root} ${bootargs}; "
+# define MENDER_LOAD_KERNEL_AND_FDT \
+ "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}; "
+#endif
+
+#define CONFIG_MENDER_BOOTCOMMAND \
+ "run mender_setup; " \
+ MENDER_BOOTARGS \
+ MENDER_LOAD_KERNEL_AND_FDT \
+ "${mender_boot_kernel_type} ${kernel_addr_r} - ${fdt_addr_r}; " \
+ "run mender_try_to_recover"
+
+#endif /* !MENDER_AUTO_PROBING */
+
+#endif /* HEADER_ENV_MENDER_H */
diff --git a/scripts/Makefile.autoconf b/scripts/Makefile.autoconf
index 0bfc1b2a62..104826c18b 100644
--- a/scripts/Makefile.autoconf
+++ b/scripts/Makefile.autoconf
@@ -108,7 +108,8 @@ define filechk_config_h
echo \#include \<configs/$(CONFIG_SYS_CONFIG_NAME).h\>; \
echo \#include \<asm/config.h\>; \
echo \#include \<linux/kconfig.h\>; \
- echo \#include \<config_fallbacks.h\>;)
+ echo \#include \<config_fallbacks.h\>; \
+ echo \#include \<config_mender.h\>;)
endef
include/config.h: scripts/Makefile.autoconf create_symlink FORCE
How did you do it ? I’ve set up some dtoverlays in config.txt and they’re not being loaded. Does removing the dtb from uboot suffice to let the firmware handle it all ?
I figured that the lines loading the fdt in u-boot had to be commented out, and that the kernel had to be passed the address of the fdt as fdt_addr
instead of fdt_addr_r
.
Now i’m stuck on fw_printenv not being able to find the right u-boot env, thus falling back to a default env and mender not accepting remote updates. I found a few threads that mention these issues, but i did not find an answer for the case of usb booting:
- Artifact update error: Failed to read the current active partition: No match between boot and root partitions
- Error in U-Boot setup: Boot and Root partitions don't match
Here’s my fw_printenv output:
Warning: Bad CRC, using default environment
bootargs=
bootcmd=
bootdelay=2
baudrate=115200
arch=sandbox
cpu=sandbox
board=sandbox
board_name=sandbox
stdin=serial,cros-ec-keyb,usbkbd
stdout=serial,vidconsole
stderr=serial,vidconsole
ethaddr=00:00:11:22:33:44
eth1addr=00:00:11:22:33:45
eth3addr=00:00:11:22:33:46
eth5addr=00:00:11:22:33:47
ipaddr=1.2.3.4
host_boot=if host dev ${devnum}; then setenv devtype host; run scan_dev_for_boot_part; fi
boot_net_pci_enum=pci enum
boot_net_usb_start=usb start
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
boot_prefixes=/ /boot/
boot_scripts=boot.scr.uimg boot.scr
boot_script_dhcp=boot.scr.uimg
boot_targets=host1 host0
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
bootcmd_host1=setenv devnum 1; run host_boot
bootcmd_host0=setenv devnum 0; run host_boot
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
bootm_size=0x10000000
kernel_addr_r=0x1000000
fdt_addr_r=0xc00000
ramdisk_addr_r=0x2000000
scriptaddr=0x1000
pxefile_addr_r=0x2000
# systemctl status mender-client
● mender-client.service - Mender OTA update service
Loaded: loaded (/lib/systemd/system/mender-client.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2021-06-11 18:13:10 CEST; 2 days ago
Process: 967 ExecStart=/usr/bin/mender daemon (code=exited, status=1/FAILURE)
Main PID: 967 (code=exited, status=1/FAILURE)
juin 11 18:13:10 cosmyx-nova systemd[1]: Started Mender OTA update service.
juin 11 18:13:10 cosmyx-nova mender[967]: time="2021-06-11T18:13:10+02:00" level=info msg="Loaded configuration file: /etc/mender/mender.conf"
juin 11 18:13:10 cosmyx-nova mender[967]: time="2021-06-11T18:13:10+02:00" level=error msg="Failed to read the current active partition: No match between boot and root partitions.: exit status 1"
juin 11 18:13:10 cosmyx-nova mender[967]: time="2021-06-11T18:13:10+02:00" level=error msg="mkdir /var/lib/mender: file exists"
juin 11 18:13:10 cosmyx-nova mender[967]: time="2021-06-11T18:13:10+02:00" level=error msg="Failed to read the current active partition: No match between boot and root partitions.: exit status 1"
juin 11 18:13:10 cosmyx-nova mender[967]: time="2021-06-11T18:13:10+02:00" level=error msg="mkdir /var/lib/mender: file exists"
juin 11 18:13:10 cosmyx-nova systemd[1]: mender-client.service: Main process exited, code=exited, status=1/FAILURE
juin 11 18:13:10 cosmyx-nova systemd[1]: mender-client.service: Failed with result 'exit-code'.
config_mender_defines.h
/* BB variables. */
#define MENDER_STORAGE_DEVICE_BASE "/dev/sda"
#define MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 0x400000
#define MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2 0x800000
#define MENDER_ROOTFS_PART_A_NAME "/dev/sda2"
#define MENDER_ROOTFS_PART_B_NAME "/dev/sda3"
/* For sanity checks. */
#define MENDER_BOOTENV_SIZE 0x4000
# cat /etc/fw_env.config
/dev/sda 0x400000 0x4000
/dev/sda 0x800000 0x4000
partition alignment:
sfdisk ${DEVICE} << EOF
label: dos
unit: sectors
start= 24576, size= 524288, type=c, bootable
start= 548864, size= 31457280, type=83
start= 32006144, size= 31457280, type=83
start= 63463424, size= 53767984, type=83
EOF
Any direction i could be looking into ?
My best guess is that the STORAGE_DEVICE_OFFSET values are wrong. They seem pretty large. I would expect to see them somewhere just before the start of a partition if my understanding is correct.
Drew
Thanks for your input. These values are default from both upstream u-boot and the Mender fork, as well as what’s recommended in Mender from scratch.
When is the env supposed to be written to that space, and how can I inspect it ? My build process involves creating a golden master with the OS, then making an image of that that is inserted in an sd card, which job is to flash the internal SSD with the image. It all works except this part.
Strangely, the golden master does manage to connect to mender, even though fw_printenv shows a similar output. Any leads on this ?
golden master fw_printenv
Warning: Bad CRC, using default environment
bootargs=
bootcmd=
bootdelay=2
baudrate=115200
arch=sandbox
cpu=sandbox
board=sandbox
board_name=sandbox
stdin=serial,cros-ec-keyb,usbkbd
stdout=serial,vidconsole
stderr=serial,vidconsole
ethaddr=00:00:11:22:33:44
eth1addr=00:00:11:22:33:45
eth3addr=00:00:11:22:33:46
eth5addr=00:00:11:22:33:47
ipaddr=1.2.3.4
host_boot=if host dev ${devnum}; then setenv devtype host; run scan_dev_for_boot_part; fi
boot_net_pci_enum=pci enum
boot_net_usb_start=usb start
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
boot_prefixes=/ /boot/
boot_scripts=boot.scr.uimg boot.scr
boot_script_dhcp=boot.scr.uimg
boot_targets=host1 host0
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
bootcmd_host1=setenv devnum 1; run host_boot
bootcmd_host0=setenv devnum 0; run host_boot
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
bootm_size=0x10000000
kernel_addr_r=0x1000000
fdt_addr_r=0xc00000
ramdisk_addr_r=0x2000000
scriptaddr=0x1000
pxefile_addr_r=0x2000
● mender-client.service - Mender OTA update service
Loaded: loaded (/lib/systemd/system/mender-client.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-06-11 17:52:06 CEST; 2 days ago
Main PID: 953 (mender)
Tasks: 13 (limit: 4915)
CGroup: /system.slice/mender-client.service
└─953 /usr/bin/mender daemon
juin 14 16:45:18 cosmyx-nova mender[953]: time="2021-06-14T16:45:18+02:00" level=info msg="State transition: check-wait [Idle] -> update-check [Syn
juin 14 16:45:19 cosmyx-nova mender[953]: time="2021-06-14T16:45:19+02:00" level=info msg="State transition: update-check [Sync] -> check-wait [Idl
juin 14 16:45:23 cosmyx-nova mender[953]: time="2021-06-14T16:45:23+02:00" level=info msg="State transition: check-wait [Idle] -> update-check [Syn
juin 14 16:45:23 cosmyx-nova mender[953]: time="2021-06-14T16:45:23+02:00" level=info msg="State transition: update-check [Sync] -> check-wait [Idl
juin 14 16:45:28 cosmyx-nova mender[953]: time="2021-06-14T16:45:28+02:00" level=info msg="State transition: check-wait [Idle] -> update-check [Syn
juin 14 16:45:28 cosmyx-nova mender[953]: time="2021-06-14T16:45:28+02:00" level=info msg="State transition: update-check [Sync] -> check-wait [Idl
juin 14 16:45:33 cosmyx-nova mender[953]: time="2021-06-14T16:45:33+02:00" level=info msg="State transition: check-wait [Idle] -> update-check [Syn
juin 14 16:45:33 cosmyx-nova mender[953]: time="2021-06-14T16:45:33+02:00" level=info msg="State transition: update-check [Sync] -> check-wait [Idl
juin 14 16:45:38 cosmyx-nova mender[953]: time="2021-06-14T16:45:38+02:00" level=info msg="State transition: check-wait [Idle] -> update-check [Syn
juin 14 16:45:38 cosmyx-nova mender[953]: time="2021-06-14T16:45:38+02:00" level=info msg="State transition: update-check [Sync] -> check-wait [Idl
maybe @mirzak could explain why these values are 0x400000 and 0x800000 instead of for instance 0x0 and 0x4000 which as far as i can tell would do the same. Anyway the problem seem to lie at least partly elsewhere, as mender-client is able to run on the golden master, even though i’m not sure it manages to properly read the environment and thus correctly manage the OS in terms of partition switching…
I’m not surprised that they need to be adjusted when switching from MMC to USB/SATA.
The other possibility is you still have CONFIG_ENV_IS_IN_MMC defined in the U-Boot config in which case it would be trying to read the environment from MMC instead of USB. I’m not sure if CONFIG_ENV_IS_IN_USB or SATA is supported in U-Boot.
I guess it may be related to these lines being removed from the config in order to make USB work
In case it rings any bells,
u-boot $ cat .config | grep CONFIG_ENV
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_ENV_SUPPORT=y
# CONFIG_ENV_OVERWRITE is not set
# CONFIG_ENV_IS_NOWHERE is not set
# CONFIG_ENV_IS_IN_EEPROM is not set
CONFIG_ENV_IS_IN_FAT=y
# CONFIG_ENV_IS_IN_EXT4 is not set
# CONFIG_ENV_IS_IN_FLASH is not set
# CONFIG_ENV_IS_IN_MMC is not set
# CONFIG_ENV_IS_IN_NAND is not set
# CONFIG_ENV_IS_IN_NVRAM is not set
# CONFIG_ENV_IS_IN_ONENAND is not set
# CONFIG_ENV_IS_IN_REMOTE is not set
CONFIG_ENV_FAT_INTERFACE="usb"
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_FAT_FILE="uboot.env"
CONFIG_ENV_FAT_FILE_REDUND="uboot-redund.env"
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
# CONFIG_ENV_IMPORT_FDT is not set
# CONFIG_ENV_APPEND is not set
# CONFIG_ENV_WRITEABLE_LIST is not set
# CONFIG_ENV_ACCESS_IGNORE_FORCE is not set
now trying to play with what @drewmoseley indicated.
adding
CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x800000
did not change the .config file, so i guess they’re ignored if they’re not with
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x800000
that yields the following .config
$ cat .config | grep CONFIG_ENV | grep -v "# "
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x800000
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_ENV_SUPPORT=y
CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_FAT_INTERFACE="usb"
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_FAT_FILE="uboot.env"
CONFIG_ENV_FAT_FILE_REDUND="uboot-redund.env"
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
Which surprisingly boots over USB, contrary to the previous post i had made earlier where these lines disabled USB detection in u-boot. The resulting booted environment then still does not seem to be correct and shows Warning: Bad CRC, using default environment
.
EDIT
Investigating further, I seem to understand that CONFIG_ENV_IS_IN_FAT means to write env in the boot partition’s uboot.env and uboot-redund.env, whereas CONFIG_ENV_IS_IN_MMC means to write at the device block level with offsets, and originally for mmcblk* type devices, but somewhat overused for USB devices.
I found that a uboot-redund.env file has been created on by boot partition, but not a uboot.env file, that’s quite strange. Then modifying /etc/fw_env.config:
# cat /etc/fw_env.config
/boot/u-boot/uboot-redund.env 0x0000 0x4000
the file is taken into account as i’ve made path mistakes that resulted in fw_printenv mentioning the file does not exist, so it does for /boot/u-boot/uboot.env as it has not been created. However the output of fw_printenv still mentions Bad CRC, using default environment
.
EDIT
I found this thread to be quite informative. I think u-boot should not need to write the env to a raw device and writing to a file should be sufficient, and that works for us to write in the boot partition for now. However i can’t figure out why the env file is not getting written and why the CRC is wrong.
From the u-boot console, run mender_setup
works without issues, and is supposed to write the config using saveenv
. Even manually executing saveenv
, does not create uboot.env
on the boot partition. uboot-rendund.env
is written but the CRC is incorrect. I don’t understand how that happens…
EDIT
I’ve just tested to double-check. Removed /boot/u-boot/uboot-redund.env, reboot, the file has been re-created by u-boot on startup, and the CRC is still incorrect. How is it possible that u-boot writes a file with an incorrect CRC?
EDIT
I could not find a resolution for this. To allow the device to boot, i’ve copied the output of printenv
in u-boot prompt to a uEnv.txt files and executed mkenvimage to create a properly CRC checked file in the boot partition, which fw_printenv can read so that mender-client can connect. However i’m pretty sure this will not allow switching partitions from mender, as u-boot does not seem to be able to write this file. I summed up the issue here.
@peac sorry for disappearing like that. I suspect you might be having an issue similar to what I ran into on my Pi3. It turned out that since it doesn’t run start usb
until later in the boot process, it isn’t able to automatically load the environment file and thus falls back to the default environment. There may be a better way to handle this, but I just set the following in the u-boot config and it fixed the problem for me. (The bmp part can be ignored).
CONFIG_PREBOOT="usb start; load usb 0 $kernel_addr_r /u-boot_splash.bmp; bmp display $kernel_addr_r m m; load usb 0:1 ${kernel_addr_r} /uboot.env; env import -c ${kernel_addr_r} 0x4000;"
I hadn’t set up the uboot-redund.env file in my config, so thanks for that tip!
Also, perhaps you could post your final diff somewhere like github’s gist? I’m sure others will appreciate your hard work and having it somewhere that’s easy to link to handy.
Hi there, still no luck.
@stiltr my preboot is inspired from what you shared earlier:
PREBOOT=" \
pci enum; \
usb start; \
load usb 0:1 \${kernel_addr_r} \/boot-splash.bmp; \
bmp display \${kernel_addr_r}; \
load usb 0:1 \${kernel_addr_r} \/uboot.env; \
env import -c \${kernel_addr_r} 0x4000; \
"
This part works fine as the BMP file gets displayed and the boot log shows it reads from FAT successfully.
What does not work, is saveenv
.
Currently the system boots because i’ve created uboot.env manually using mkenvimage from the dumped env of uboot’s prompt.
However, saveenv does not write uboot.env, it does write uboot-redund.env but with a wrong CRC, which makes it unreadable by fw_printenv when mender starts.
So i’ve configured fw_printenv to read the manually created uboot.env (that is not written by saveenv) instead of the corrupted automatically created uboot-redund.env (that is written by saveenv).
This way does not enable me to update the opposite partition or detect failed boots, as the env mechanism is basically broken. Any help appreciated.
EDIT:
I’ve dumped (mkenvimage manually created) uboot.env and (saveenv-created) uboot-redund.env with hexdump and diffed them:
# diff uboot-redund.txt uboot.txt
1c1
< 00000000 20 9e 7d 1c 03 61 6c 74 62 6f 6f 74 63 6d 64 3d | .}..altbootcmd=|
---
> 00000000 20 9e 7d 1c 02 61 6c 74 62 6f 6f 74 63 6d 64 3d | .}..altbootcmd=|
The 5th byte is different.
EDIT:
There seems to actually be no issues of CRC, probably just issues of a file not being the right one with redundant environment. I think that the above 02/03 byte difference is actually meant to be this way.
So the only issue would be that saveenv
does write uboot-redund.env
but not uboot.env
.
Update: the function that handles the file writing seems to be here.
Here’s a test i’m doing in case it lights up ideas in someone’s head:
U-Boot CosmOS > env set toto tata
U-Boot CosmOS > env print toto
toto=tata
U-Boot CosmOS > saveenv
Saving Environment to FAT... OK
U-Boot CosmOS > boot
6694592 bytes read in 47 ms (135.8 MiB/s)
## Booting kernel from Legacy Image at 00080000 ...
Image Name: Linux kernel (CosmOS)
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 6694528 Bytes = 6.4 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 2eff3a00
Booting using the fdt blob at 0x2eff3a00
Loading Kernel Image
Using Device Tree in place at 2eff3a00, end 2f002f6b
Starting kernel ...
root@pi:~ fw_printenv | grep toto
root@pi:~ cat /etc/fw_env.config
/boot/u-boot/uboot.env 0x0000 0x4000
/boot/u-boot/uboot-redund.env 0x0000 0x4000
root@pi:~ cat /etc/fstab
proc /proc proc defaults 0 0
/dev/root / ext4 defaults,noatime 0 1
/dev/sda1 /boot/u-boot vfat defaults 0 2
/dev/sda4 /data ext4 defaults 0 2
rpi_4_32b_defconfig
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_FAT_INTERFACE="usb"
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
new non-working test:
CONFIG_SYS_REDUNDAND_ENVIRONMENT=n
include/config_mender.h:41:3: error: #error CONFIG_SYS_REDUNDAND_ENVIRONMENT is required for Mender to work. Make sure that: 1) All the instructions at https:
41 | # error CONFIG_SYS_REDUNDAND_ENVIRONMENT is required for Mender to work. Make sure that: 1) All the instructions at https://docs.mender.io/system-updates-yocto-project/board-integration/bootloader-support/u-boot have been followed. 2) All required layers are included in bblayers.conf, including any board specific layers such as meta-mender-<board>. Check also https://docs.mender.io/troubleshoot/yocto-project-build for Known Issues when upgrading.