Make Mender use eMMC boot partitions for saving uboot environment

The configuration that will be presented here has been tested only to kirkstone yocto branch.
Previous knowledge of setting up yocto with mender it is assumed!

Some raspberry CM modules come with an eMMC card. Some of those cards have some special boot partitions which in /dev can be seen as:
/dev/mmcblk0boot0 /dev/mmcblk0boot1

Those partitions come empty and are not utilized.
The default MENDER configuration will save the uboot environment in an unallocated space between MBR and first FAT partition which holds the firmware files of the RPI.
This space is usually 12MBs or even more depending the MENDER_PARTITION_ALIGNMENT variable.
The space required for saving the uboot environment is only 16Kbs plus other 16Kbs for the redundancy. So there is a huge space that is lost from the eMMC card.

With the configuration shown below, uboot and MENDER will be configured to use both /dev/mmcblk0boot0 /dev/mmcblk0boot1 and so we are going to have “hardware” redundancy.

First of all uboot needs to be patched.
Mender already patches uboot to add its specific values.
So we are going to mangle that patch.

At file:
meta-mender-raspberrypi/recipes-bsp/u-boot/patches/0001-configs-rpi-enable-mender-requirements.patch

Go to your boards defconfig section (eg rpi_3_32b_defconfig) and make the following changes:

-@@ -43,3 +43,7@@ CONFIG_SYS_WHITE_ON_BLACK=y
+@@ -43,3 +43,9 @@ CONFIG_SYS_WHITE_ON_BLACK=y  
  CONFIG_CONSOLE_SCROLL_LINES=10
  CONFIG_PHYS_TO_BUS=y
  CONFIG_OF_LIBFDT_OVERLAY=y
 +CONFIG_ENV_IS_IN_MMC=y
-+CONFIG_ENV_OFFSET=0x800000
-+CONFIG_ENV_OFFSET_REDUND=0x1000000
++CONFIG_ENV_OFFSET=0x0
++CONFIG_ENV_OFFSET_REDUND=0x0 
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
++CONFIG_SYS_MMC_ENV_PART=1
++CONFIG_SUPPORT_EMMC_BOOT=y

Where:
CONFIG_ENV_OFFSET:
Says that the u-boot environment will be saved at offset 0x0 from the start of the storing place
CONFIG_ENV_OFFSET_REDUND:
Says that the redundancy data will be saved at the same offset also 0x0
This seems to be wrong since we save the actual and redundancy data to the same place but in fact this enables into uboot the hardware redundancy so uboot will use both mmcblk0boot0 and mmcblk0boot1 eMMC partitions!
Further info can be found also here:

CONFIG_SYS_MMC_ENV_PART=1:
This tell uboot to use the eMMC special boot partitions.
CONFIG_SUPPORT_EMMC_BOOT=y:
Enables into uboot access to above partitions

That’s all with uboot patching

Now we need to make some small changes to mender u-boot-mender-helpers.inc file.
Add the following modifications:

diff --git a/meta-mender-core/recipes-bsp/u-boot/u-boot-mender-helpers.inc b/meta-mender-core/recipes-bsp/u-boot/u-boot-mender-helpers.inc
index 6eb17583..16b31926 100644
--- a/meta-mender-core/recipes-bsp/u-boot/u-boot-mender-helpers.inc
+++ b/meta-mender-core/recipes-bsp/u-boot/u-boot-mender-helpers.inc
@@ -52,7 +53,7 @@ mender_create_fw_env_config_file() \{
     # create fw_env.config file
     cat > $1 <<EOF
 ${MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH} ${MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1} $HEX_BOOTENV_SIZE
-${MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH} ${MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2} $HEX_BOOTENV_SIZE
+${MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH_REDUND} ${MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2} $HEX_BOOTENV_SIZE EOF
 }

The new MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH_REDUND variable is required in order for libubootenv recipe to create the correct /etc/fw_env.config file which says where u-boot saves its environment so that mender client can make its modifications using the fw_setenv command.
So it will create:

cat /etc/fw_env.config
/dev/mmcblk0boot0 0x0 0x4000
/dev/mmcblk0boot1 0x0 0x4000

Finally at your local.conf or distro.conf file you will need the following configuration:

# MENDER eMMC HW REDUND BOOT PARTITION
# /dev/mmcblk0boot0 0x0 0x4000
# /dev/mmcblk0boot1 0x0 0x4000
# We want to have start section 2048
# start sector 2048 * 512 = 1048576
MENDER_PARTITION_ALIGNMENT = "1048576"
MENDER_RESERVED_SPACE_BOOTLOADER_DATA = "0"
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET = ""
MENDER_UBOOT_CONFIG_SYS_MMC_ENV_PART = "1"
MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH = "${MENDER_STORAGE_DEVICE}boot0"
MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH_REDUND = "${MENDER_STORAGE_DEVICE}boot1"
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 = "0x0"
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_2 = "0x0"

MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET = “”
This will deter mender from writing at the wks part file the uboot environment entry.
So mender will not create empty space for the uboot environment at the start of the eMMC since now we are not going to use it.

MENDER_RESERVED_SPACE_BOOTLOADER_DATA = “0”
This instructs mender not to use MENDER_RESERVED_SPACE_BOOTLOADER_DATA variable for its image TOTAL size calculation.

MENDER_PARTITION_ALIGNMENT = “1048576”
Is the partition alignment variable which in our case leaves the 1MB empty space from the start of the eMMC. We want to have some empty space at first at least for the MBR. A little more doesn’t hurt.

That was all!

Most of the functionality is already present into meta-mender layer and only small changes are required.
The new MENDER_UBOOT_MMC_ENV_LINUX_DEVICE_PATH_REDUND will trigger a warning since this variable is not recognized but maybe can be added in meta-mender with a later update?

In case something is not clear or requires fixing in the guide or something does not work well posts are always welcome.