Installing U-Boot by hand - setting up the U-Boot env as TEZI does

Hi!

I’m working on integrating an OTA solution (rauc) to our custom yocto image, which is based on the txd-reference-minimal-image BSP 5.5.0. I’m using a Toradex Apalis iMX8QM 4GB IT v1.1C CoM with an Ixora carrier board.

We would like to support updating the U-Boot too, but it is clear that rauc is not suitable for this, and I have to do it with a custom script.

I can copy the imx-boot file to its place and load the default u-boot env values, but for some reason, this u-boot env does not match the one TEZI creates when installing the image. What I’m doing is:

  1. Wipe the mmcblk0boot0 device except for the last 512 byte sectore where the Toradex config block is located.
  2. dd the imx-boot file to the beginning of the mmcblk0boot0 device.
  3. install the u-boot-initial-env-sd U-Boot environment with fw_setenv --config /etc/fw_env.config --script /home/root/u-boot-initial-env-sd command as seen in this thread.

The device boots and everything works as expected, but the U-Boot env is not identical to the one I get after installing the image with TEZI, and since we’re running fitImage secure boot and redundant A-B boot logic I would not really like to mess with the U-Boot config more than I should.

I tried to use the default env (by running env default -a as suggested in this thread, and also by leaving the U-Boot env empty altogether), but the default env is also different from the other two mentioned above. Even if I “update” it with the u-boot-initial-env-sd, its still not the same.

My question is, exactly how does TEZI create the U-Boot env? Load the defaults hardcoded in the U-Boot binary, or load the u-boot-initial-env-sd, or something else?
Can it be that the TEZI leaves some residue config from its own U-Boot config on the device as suggested in this thread?

Thanks!
Csongor

Hi @csongor.ferenczi,

Thanks for reaching out. Usually, TEZI should check the u-boot-initial-env present on the folder of the image that you’re trying to install and use it to define the variables. For instance, a reference-minimal-image for BSP 5.7.0 without any customization will have the following u-boot-initial-env-sd:
u-boot-initial-env-sd (4.8 KB)

Can you please give us more details on what exact differences you see when you do both procedures? This way, we can track the possible origins of this variation.

Do you have any bbapend on Yocto for the u-boot on the recipes that you use?

Best regards,

bbappends

I have both a u-boot-distro-boot.bbappend and a u-boot-toradex_%.bbappend file. The u-boot-distro-boot.bbappend file appends the rauc redundant A-B boot logic to the boot script, while the u-boot-toradex_%.bbappend applies a few patches to the include/configs/apalis-imx8.h file, including enabling AHAB boot, setting a few OTA related variables, and disabling DHCP boot.

U-Boot environments

This is the environment I get after installing the image with TEZI: (I extracted all of these files with fw_printenv)
U-Boot_env_after_fresh_TEZI_install.txt (5.3 KB)

Please note, how the boot_targets does not contain the DHCP option, while the bootcmd_dhcp=setenv (...) line is still present. More on this below.


This is the U-Boot environment I get after deleting the old U-Boot environment, to force U-Boot into loading the defaults from the binary itself:
U-Boot_env_after_zeroing_the_old_env.txt (4.7 KB)
The command I use for deleting the old enviroment is the following:

echo "0" > /sys/block/mmcblk0boot0/force_ro
dd if=/dev/zero of=/dev/mmcblk0boot0 conv=noerror,sync,notrunc iflag=fullblock status=progress seek=64495 count=16
echo "1" > /sys/block/mmcblk0boot0/force_ro

(Note: The seek 64495 is equal to the -0x2200 offset used in /etc/fw_env.config, I verified it with hexdump)

This env does not contain the bootcmd_dhcp=setenv line, but every OTA related variables and related modifications are present, which is the expected outcome. Thus, I believe the U-Boot binary only contains everything I would like to, excluding the bootcmd_dhcp=setenv line.


This is the U-boot environment I get after deleting the old U-Boot environment, and reinitialize it with the u-boot-initial-env-sd file.
U-Boot_env_after_loading_it_with_fw_setenv_from_u-boot-initial-env-sd.txt (4.2 KB)
Please note, that this is the state right after running the fw_setenv command but before restarting the device. This env does not contain the bootcmd_dhcp=(...) line either and it has several other missing lines which gets set by the boot.scr I assume?

After I restart the device, the U-Boot env reverts back to the same value as seen in the U-Boot_env_after_zeroing_the_old_env file.


The u-boot-initial-env-sd file used for these tests are the following:
custom_u-boot-initial-env-sd.txt (4.3 KB)

This file does not have the bootcmd_dhcp= line either, and this is where my confusion comes from. If this line is not in the binary’s default values, and nor in the u-boot-initial-env-sd file, where does it come from? It must be a residual thing from TEZI’s own U-Boot env?

I’m asking what are the exact steps TEZI does for setting up the U-Boot env, because as you can see above, it seems to me that wiping the mmcblk0boot0 device expect the last sector and copying the imx-boot file to its place is sufficient, and there is no need to configure the U-Boot environment using u-boot-initial-env-sd afterwards, since it results in the same environment as without it.

But I’m not sure if I’m okay to skip this step, or do I have initialize it just to get to the same state, or what are the steps TEZI is doing, to initialize the U-Boot env.

Hello @csongor.ferenczi,
Because of the way the u-boot environment works, you’ll always end up getting a mix between the variables that are included in u-boot when compiled, variables that are created at runtime and the environment that’s written on flash.
The only thing that gets edited by fw_setenv is the environment that’s written on the flash.
What TEZI does depends on whether you provide an environment file as part of your image.json (u_boot_env directive):

If the environment file is not provided, then TEZI won’t touch the environment while installing the image.

If the environment file is provided, TEZI will call

fw_setenv -f /etc/u-boot-initial-env --config /etc/fw_env.config --script your_env_file

Because of this, you’ll always get all the variables that are part of the /etc/u-boot-initial-env file written in your flash environment. The default file that’s included in TEZI should be pretty similar to the one in our minimal image, but I’m not sure if they are the same. This could be the reason why you see a difference between the environment that comes from a TEZI install and the environment that comes from your own installation.

We have an open bug in TEZI to actually change this behavior so that the default environment that’s provided by TEZI when writing the u_boot_env is an empty one, so that it would do something like this, although there is no forecast on when this will be implemented:

fw_setenv -f empty_env_file --config /etc/fw_env.config --script your_env_file

My suggestion for you to get a repeatable environment would be to setup the important variables in the default u-boot environment (compiled in) and then write the configuration variables you need using fw_setenv with the empty default environment file. By doing it this way you’ll get the default_compiled_variables + runtime_variables + your_env_file_variables as your u-boot environment after reboot.

Please keep in mind that by executing fw_printenv you’ll only be able to see the variables that are stored on your flash environment. So if you only set one variable on your u_boot_env file, you’ll only see that variable after fw_printenv.

Regards,
Rafael

3 Likes

Hi @rafael.tx ,

Thank you so much for your clarification, this was the exact information I needed.

Cheers!
Csongor