U-boot environment located past 0xFFFFFFFF fails

Hi Folks,

I’m working on an update for the mender tegra port which will allow users to specify larger rootfs sizes. The tegra platform has a very specific and unique flash layout, with a bunch of reserved flash sectors at the beginning of the part, meaning the u-boot environment is farther than it is on probably most/all platforms.

While working on this update I noticed that if I set my rootfs larger than a certain size the integration checklist started failing. I noticed the transition was at offset 0xFFFFFFFF (sizeof uint32). Here’s an example of the /etc/fw_env.confg
/dev/mmcblk0 0x11f129000 0x20000
/dev/mmcblk0 0x11f149000 0x20000

If I write a variable in u-boot, then attempt to read it with fw_printenv in Linux I can’t see the variable value. fw_setenv tells me the environment is corrupt. If I remove the leading 1 and make the address 0x1f129000 everything works. So it appears u-boot is writing the variable to the wrong offset.

I’ve veified the values are getting set correctly in u-boot and u-boot-fw-utils recipe
dan@dan-ubuntu:~/build$ bitbake -e u-boot | grep ^MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1=
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1=“0x11f129000”

My guess is the MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1/2 variables need a ULL suffix to ensure they are treated as 64 bit values. However my first attempt to address didn’t do the trick. I’ll take another look tomorrow but I’m curious if anyone has other suggestions about how to solve this.

Just my 2 cents here: I would play in u-boot if storing/reading variables works. Also you store env in sdcard in some offset ~4.48G. Is this correct? I suspect to be rounded on power of 2. Thanks.

Thanks @MarekBelisko

I would play in u-boot if storing/reading variables works

It definitely does, it’s just that it’s writing to the wrong area. Here’s an example sequence:

From Linux:
root@jetson-tx2:~# cat /etc/fw_env.config
/dev/mmcblk0 0x11f129000 0x20000
/dev/mmcblk0 0x11f149000 0x20000

root@jetson-tx2:~# fw_setenv mender_from_linux 1
Warning: Bad CRC, using default environment

Then from uboot

Tegra186 (P2771-0000-500) # printenv mender_from_linux
## Error: "mender_from_linux" not defined
Tegra186 (P2771-0000-500) # setenv mender_from_uboot 1
Tegra186 (P2771-0000-500) # saveenv

Back in Linux again

root@jetson-tx2:~# fw_printenv mender_from_uboot
## Error: "mender_from_uboot" not defined

Change to remove leading 1 from environment location

root@jetson-tx2:~# cat /etc/fw_env.config
/dev/mmcblk0 0x1f129000 0x20000
/dev/mmcblk0 0x1f149000 0x20000
root@jetson-tx2:~# fw_printenv mender_from_uboot
mender_from_uboot=1

Now able to access environment, written to MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 & 0xFFFFFFFF

I’m stuck with the 4.4+GB offset if I store the u-boot environment in the same partition as the image, due to the way default tegra partitioning works I believe. See a related discussion in my original pull request where Matt suggested using /dev/mmcblk0boot1 for the u-boot environment. The problem with this is I think Mender assumes the uboot environment is a part of the same storage device image as the root filesystem and I don’t completely understand the work required to decouple this. Ideally I think I need a way to tell Mender not to try building the full mmc image at all (I use tegraflash to build and flash the full image) and to allow me to specify /dev/mmcblk0boot1 for the u-boot environment storage while my images will be on /dev/mmcblk0

I also don’t completely understand why u-boot is choking on the 64 bit storage device offset. It looks like the relevant structures should all be using long long types.

I think I’m going to take a look tomorrow at what it would take to split the location of the u-boot environment and place on /dev/mmcblk0boot1 while keeping my rootfs on /dev/mmcblk0. This has the added benefit that it doesn’t require location changes when the application size changes and is probably a better long term solution for the platform.

I think I’m going to take a look tomorrow at what it would take to split the location of the u-boot environment and place on /dev/mmcblk0boot1 while keeping my rootfs on /dev/mmcblk0

I’ve got two pull requests which I haven’t completed testing yet but which show the changes that should allow moving the environment to /dev/mmcblk0boot1.

A bit more history, I decided not to implement the suggestions from Matt regarding u-boot environment location originally based on a discussion with Mirza on the mailing list. However, I think this is likely the best solution to the problem I’m currently facing because it won’t require changes to the tegra partition layout from default and will allow me to remove the u-boot environment partition after the rootfs partition, which makes offset calculation dependent on rootfs size and a pain to calculate and also introduces the problem mentioned here when the rootfs size is > 4GB.

I’ve got two pull requests/branches in progress if anyone wants to help test/fix
Here’s one on meta-mender-community

and one on meta-mender

I haven’t completed testing on these so they likely don’t work yet. However, I’ve hacked together a build which works for u-boot environment storage in mmcblk0boot1 so I know it’s ultimately possible with changes similar to these.

One change I haven’t tried to make yet is the handling for read only access handling in the boot block. This would probably be cleanest to implement in the mender client, for instance in WriteEnv, when /etc/fw_env.config exists and /sys/block/${device}/force_ro exists and has a value of 1 where $device is the device parsed from /etc/fw_env.config. For now the workaround is to use
echo 0 > /sys/block/mmcblk0boot1/force_ro
on boot.

I also don’t completely understand why u-boot is choking on the 64 bit storage device offset

See definitions like this one in the u-boot 2016.09 branch which assume 32 bit offsets for mmc environment.

I haven’t completed testing on these so they likely don’t work yet

They are working for me now, just waiting for questions on the PR before submitting a PR to the mender hosted meta-mender repository.

In case anyone else is interested the code is working now on tegra for u-boot environment, see pull requests https://github.com/Trellis-Logic/meta-mender-community/pull/1 and https://github.com/mendersoftware/meta-mender/pull/789

2 Likes

@dwalkes thanks for sharing :+1:

1 Like

Thank you @dwalkes !
Do you plan to do a PR ont the mender community repo ?

@Austriker I do plan to submit a PR but planned to wait until the warrior branch of meta mender community is ready since I haven’t tried on earlier branches.