Pi3 USB boot support

Hi all,

We use Pi3’s here, but instead of uSD cards, we boot from USB. A while back I managed to hack together some u-boot patches that let me boot from usb and while it seemed to work initially, I’m pretty sure it had some issues with some of the Mender bits. I had to set the project aside for a while, but now that I’m coming back to it, I see there have been a lot of changes from 1.6 to 2.0. I’m using a debian-based OS with a non-yocto build system, so the mender conversion tools look very promising.

Getting to the point of the post, is there any word on if usb boot will be supported in terms of u-boot patches in the future? If not, has anyone done this successfully or have any pointers on the best way to approach crafting a proper patch?

Thanks it advance! I’m really looking forward to getting our update process migrated to mender!

We used it previously for our test farm, but this became broken at some
point in upstream U-Boot. See this message:
https://lists.denx.de/pipermail/u-boot/2018-January/319100.html

There was no reply, and we haven’t tried it since then, so I’m not sure
if it’s fixed or not.

Hi Kristian,

Thanks for the reply! It looks like I was using U-Boot 2018.07 and while I can’t confirm my build was working properly overall it was able to find and boot from the usb drive. Any chance you’d be willing to share the patches you were using? It would be pretty exciting (for me, at least) if usb support were to make it into mender officially.

We dismantled the whole system over a year ago, and unfortunately I don’t think I have them anymore. It was not overly complicated, the bootloader was still on the SD card, but was configured to load everything from USB. I think as long as MENDER_STORAGE_DEVICE is set to USB, it should load everything correctly, even if you put the bootloader on the SD.

No worries. Thank you for the tips! We’re running without SD cards, so I think that introduces a few quirks, but I’ll dig into it again and see if I can’t come up with something useful. Thanks again!

No worries. Thank you for the tips! We’re running without SD cards, so I think that introduces a few quirks, but I’ll dig into it again and see if I can’t come up with something useful. Thanks again!

I am curious, how are you running without SD cards? I didn’t think this was possible?

With the Pi3, you have the ability to boot from SD, USB and PXE.

You can look here for a more detailed explaination.

1 Like

Hi,

I’m also trying to boot from USB SSD without success. I’m doing a custom build, for now nothing too complicated as i’m using the default raspios root as rootfs. I started by using the u-boot files from the official mender images, which works fine when booting from SD.

Then i’ve compiled mender’s u-boot fork because i’ve noticed in the u-boot shell that USB was not compiled in. So i’ve taken reference on rpi_arm64_defconfig to add USB to rpi_4_32b_defconfig (i’m using 32bit rpi4 for now), changed the config_mender_defines.h and compiled (MMC seems to be the right denomination for the device as per this sanity check). USB is now compiled in and appears in u-boot shell commands, but when running usb start, u-boot says

U-Boot 2020.01-g83cf4883ec-dirty (May 18 2021 - 06:21:39 +0200)

DRAM:  3.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0 

U-Boot> run usb_boot
starting USB...
No working controllers found
USB is stopped. Please issue 'usb start' first.
U-Boot> usb start
starting USB...
No working controllers found

i’ve also adapted /data’s mender config to have the right device names, but i’m not reaching there yet.

Where to go from here? Thanks.

EDIT: Just a note, we would prefer to set the rpi4’s EEPROM to boot on USB first, which it can do fine using plain raspios. I’ve tried it and it does reach u-boot on the SSD, but u-boot fails to start properly. Using the u-boot files from the official mender image, u-boot’s log stops after:

U-Boot 2020.01-g83cf4883ec (Mar 09 2021 - 08:12:31 +0000)

DRAM:  3.9 GiB

Above description is when booting SD first, accessing u-boot files on mmcblk0p1 and trying to instruct it to boot from sda. It’s not ideal for us as we would like to have a maintenance OS on the SD, be able to update the u-boot partition on SSD and still have a fallback bootloader on SD. RPi4 supports it well because if USB boot fails, it will boot from SD.

That fork is 1.5 years old now. I wonder if it does not have the proper USB support. You may want to try a newer version.

Drew

I’m not sure how to correctly re-apply mender’s patches on a newer u-boot version, but i guess i’ll give it a try

I think that branch was created by taking a Yocto build and saving off the patched sources that Yocto created. If you are familiar with Yocto that may be a quick start.

Drew

I’ve rebased the official mender u-boot repo to the upstream’s current main and reapplied my modifications. It compiled without issues.

(note: compiled with CROSS_COMPILE=arm-linux-gnu-)

Booting the new u-boot from sd, it still says no working controllers found:

U-Boot 2021.07-rc2-00167-g5c2b1c0ee7 (May 18 2021 - 18:04:37 +0200)

DRAM:  7.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   
Warning: ethernet@7d580000 MAC addresses don't match:
Address in DT is                dc:a6:32:e7:97:8f
Address in environment is       b8:27:eb:9f:33:38
eth0: ethernet@7d580000
Hit any key to stop autoboot:  0 
U-Boot> usb start
starting USB...
No working controllers found
U-Boot> usb dev
USB is stopped. Please issue 'usb start' first.

Using the same u-boot but from ssd (just removed the sd so it falls back to usb), gives this output:

U-Boot 2021.07-rc2-00167-g5c2b1c0ee7 (May 18 2021 - 18:04:37 +0200)

DRAM:  7.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from MMC... Card did not respond to voltage select! : -110
*** Warning - No block device, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d580000
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
starting USB...
Bus xhci_pci: Host not halted after 16000 microseconds.
probe failed, error -16
No working controllers found
Hit any key to stop autoboot:  0 
Card did not respond to voltage select! : -110
Card did not respond to voltage select! : -110
starting USB...
Bus xhci_pci: Host not halted after 16000 microseconds.
probe failed, error -16
No working controllers found
USB is stopped. Please issue 'usb start' first.
starting USB...
Bus xhci_pci: Host not halted after 16000 microseconds.
probe failed, error -16
No working controllers found
ethernet@7d580000 Waiting for PHY auto negotiation to complete... done
BOOTP broadcast 1
DHCP client bound to address 10.0.0.130 (10 ms)
*** Warning: no boot file name; using '0A000082.img'
Using ethernet@7d580000 device
TFTP from server 10.0.0.1; our IP address is 10.0.0.130
Filename '0A000082.img'.
Load address: 0x200000
Loading: T T T T T T T T T T 
[... more tries of network boot]

The build’s defconfig (other files were not modified by the rebase):

CONFIG_ARM=y
CONFIG_ARCH_BCM283X=y
CONFIG_SYS_TEXT_BASE=0x00008000
CONFIG_TARGET_RPI_4_32B=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ENV_SIZE=0x4000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="pci enum; usb start;"
# CONFIG_PREBOOT="usb start"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_MISC_INIT_R=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_MISC_INIT_R=y
CONFIG_SYS_PROMPT="U-Boot> "
CONFIG_CMD_DFU=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_DM_DMA=y
CONFIG_DFU_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_BCM2835=y
CONFIG_DM_ETH=y
CONFIG_BCMGENET=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_PCI_BRCMSTB=y
CONFIG_PHYLIB=y
CONFIG_DM_ETH=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_GENERIC is not set
CONFIG_DM_RESET=y
CONFIG_DM_RNG=y
CONFIG_RNG_IPROC200=y
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_USB_GADGET_DWC2_OTG=y
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_DWC2=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_LAN78XX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
# CONFIG_VIDEO_BPP8 is not set
# CONFIG_VIDEO_BPP16 is not set
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_PHYS_TO_BUS=y
CONFIG_ADDR_MAP=y
CONFIG_SYS_NUM_ADDR_MAP=2
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_OFFSET=0x400000
CONFIG_ENV_OFFSET_REDUND=0x800000
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y

After finding this message, i’ve taken the boot files (bcm2711-rpi-4-b.dtb, boot/{bootcode.bin,fixup*,start*}) from the previous (unused, we decided to stick to raspios for now) mender yocto build I had made for raspberry. However u-boot still does not find the controller. Is there a command to check that the device has been correctly added? The official documentation is not so verbose about it…

@peac you are definitely into the depths of U-Boot which is beyond my expertise. You may have better luck on the U-Boot mailing list. I would definitely make sure you can get this booting with the standard non-Mender integrated images first to rule out issues with the basic configuration.

Drew

OK, so i started from scratch.

I took the official u-boot repo from u-boot, master branch. Built and booted it, and it has USB out of the box (my boot partition still has the latest DTB files that i’ve just built with latest linux kernel from the repo).

U-Boot 2021.07-rc2-00175-g7a1638c263 (May 18 2021 - 23:51:50 +0200)

DRAM:  7.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1... 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 
U-Boot> usb start
U-Boot>

I then applied the patches as mentionned in mender from scratch, with adjustments as it is a little outdated. Here’s the total modification diff below. This one does not find the usb controller, and also not sure why but it’s complaining about the env address ? I did not notice it the first time, i’m not sure if that’s the reason or not.

Could maybe a Mender engineer review the diff and see why applying the mender modifications disables USB? @mirzak

U-Boot 2021.07-rc2-00176-ga7daea5634-dirty (May 19 2021 - 00:09:07 +0200)

DRAM:  7.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... *** Error - No Valid Environment Area found
*** Warning - bad env area, using default environment

Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   
Warning: ethernet@7d580000 MAC addresses don't match:
Address in DT is                dc:a6:32:e7:97:8f
Address in environment is       b8:27:eb:9f:33:38
eth0: ethernet@7d580000
Hit any key to stop autoboot:  0 
U-Boot> usb start
starting USB...
No working controllers found
U-Boot> 
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index 47ea466454..04bcb2161d 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -59,3 +59,8 @@ CONFIG_PHYS_TO_BUS=y
 CONFIG_ADDR_MAP=y
 CONFIG_SYS_NUM_ADDR_MAP=2
 CONFIG_OF_LIBFDT_OVERLAY=y
+
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_OFFSET=0x400000
+CONFIG_ENV_OFFSET_REDUND=0x800000
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
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..2c8cdc65f1
--- /dev/null
+++ b/include/config_mender_defines.h
@@ -0,0 +1,32 @@
+/* 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 "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 "uImage"
+#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 */
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 834f1cd236..2da3229678 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
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index 2a61a5d6f0..b0bce1b5ac 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -20,6 +20,7 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stddef.h>
 #include <string.h>
 #include <sys/types.h>

The one thing that jumps to mind is this commit in meta-mender-community. I’m not sure if that results in a U-boot change but it may. You might want to see about running a Yocto build and getting the latest patches if you have not already done so.

@kacf any other ideas?

Hmm, I don’t think that’s related.

But I can’t see anything in the patch that would obviously be related either. I’m afraid the only suggestion I have is to start removing things from the patch, and try to pinpoint which part is causing the USB failure.

I know you’re working with a Pi4, but maybe my Pi3 diff will help. It’s based off commit ecd4d99f654f3f7bfb96001891d69c3125e70b69 of mainline u-boot with customized versions of the mender patches applied. Note that it’s pulling the kernel image from /srv on the root part, rather than /boot. Not shown in the diff is:
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;"
It could probably be done better, but it’s where I ended up and it seemed to be working. Again, not sure if it’s helpful, but I figured I’d share it just in case.

thank you very much, i’ll check it out tomorrow !

well what jumped to my face is that you’re using

#define MENDER_UBOOT_STORAGE_INTERFACE "usb"

instead of the recommended “mmc” for USB devices, so i’ll try that quickly before bedtime