Why must u-boot env offset be multiple of alignment?


I would not say it is required. Where did you find this text?

At best, it is a recommendation which is applied when you build the .sdimg/uefiimg images.

This is an optimization,

  1. If partitions are aligned to a boundary that matches the HW erase block size, there are certain performance gains (see flashbench)

  2. If U-Boot environment is aligned to the same HW boundary, this ensures that the redundant U-Boot environments do not end up in the same HW erase block. Though this is hard to know if it actually will be the case on managed flash devices (eMMC)

I’m referring to this error: https://github.com/mendersoftware/meta-mender/blob/6496fe9864a2c9473194195207beb2cdf665b85b/meta-mender-core/recipes-bsp/u-boot/u-boot-fw-utils-mender.inc#L8

Performance is probably not that important for this, but I do see the point of having the 2 environments in two separate erase blocks. Is it possible to find out how eMMCs handle this?

Is it possible to find out how eMMCs handle this?

I am not aware of a way to inspect this, but the assumption is as long as you are writing to blocks that are aligned to the erase-block size, that is the best one can do with the interface provided to the managed flash.

I can recommend this article, which contains some good information on how managed flash works,

It is essentially required for the above reason. Meta-mender doesn’t have an explicit erase block size variable, so we use MENDER_PARTITION_ALIGNMENT for that purpose.

Doesn’t it? What about MENDER_STORAGE_PEB_SIZE?

Alright, since you asked I will answer this a bit more in depth:

You are correct that MENDER_STORAGE_PEB_SIZE refers to the physical erase block size of the storage medium. And for MMC/SSD/HDD type storage devices, this is indeed the default value for MENDER_PARTITION_ALIGNMENT.

But here comes the additional complexity: On devices using UBIFS, MENDER_STORAGE_PEB_SIZE is no longer the same as MENDER_PARTITION_ALIGNMENT, because UBI volumes use additional bytes for internal bookkeeping. Here we have an additional unit, the MENDER_UBI_LEB_SIZE, or Logical Erase Block size, which is smaller than the PEB, and usually not a power of two. On UBI devices it is important that MENDER_PARTITION_ALIGNMENT is equal that this value, and not the PEB value.

Meta-mender doesn’t have an explicit erase block size variable, so we use MENDER_PARTITION_ALIGNMENT for that purpose.

So this statement was perhaps not entirely correct. What I meant was that we don’t have one single erase block size variable that can be used for the purpose of aligning the redundant environments, because on UBI devices the Logical Erase Block size is not equal to the Physical Erase Block size, whereas on other devices it is. One could perhaps argue that this should have been organized better, but the UBI support was added long after MENDER_PARTITION_ALIGNMENT was added, so the reason that the latter is considered the “master” variable is somewhat historical.

Thanks for the detailed writeup!

In my application, I would like to have a partition alignment of 4 MiB, but place the u-boot environments at 2048 kiB and 2560 kiB, respectively. This is because my eMMC has an erase_size of 512 kiB, but a preferred_erase_size of 4 MiB. In this scenario, the error mentioned above is quite limiting. Is there any way to get rid of that error?

The reason why I have such obscure requirements is that I’d like to transition existing devices (partition layout exists) to mender. This presents a few challenges as there is little space (4 MiB) before the first partition starts.

One possibility might be to bypass this error as you want to add your own custom /etc/fw_env.config.

Not sure what your setup is and if you are using a U-Boot fork recipe, but you might be able to omit the include of u-boot-fw-utils-mender.inc and just use u-boot-mender-common.inc.

I know something similar was done here, which also provided a custom /etc/fw_env.config instead of relying on the logic provided by u-boot-fw-utils-mender.inc

I suppose we could accept a PR which introduces a variable to skip that error, obviously with a huge warning in the comments that you better know what you’re doing if you disable the error. Of course I cannot guarantee that there aren’t other ill effects this would have, since we don’t test this configuration.