Raspberry Pi OS 64 Bit conversion

@jjsteele well take one step back? mender-convert/configs/raspberrypi/uboot/debian at master · mendersoftware/mender-convert · GitHub

Note, not tested on the CM5 yet as I’m having hardware issues there.

Greetz,
Josef

Hi Josef,

I have several Raspberry Pi 4 devices currently running arm32 Debian Bookworm images in standalone mode. In the past, we had to use arm32 because mender-convert didn’t support arm64. Now that arm64 is supported, I need to upgrade these devices from arm32 to arm64 using a golden image.

I created the artifact from a golden arm64 device and installed it successfully. I also remapped the /uboot mount point to /boot/firmware to match the new layout, and the update process itself went smoothly.

However, I’m running into issues with the U-Boot environment variables. The arm32 and arm64 configurations use different variables, and simply switching the root filesystem isn’t enough.

To address this, I used dd to extract the U-Boot environment sectors from the arm64 device—specifically from offsets 0x400000 (size 0x4000) and 0x800000 (size 0x4000)—and wrote them to the same locations on the target devices. With this, the device boots successfully into the arm64 system and the new partition.

The issue is that these U-Boot variables include some device-specific values, such as the MAC address. When I overwrite these sectors, I also overwrite those identifiers, which is problematic.

Is there a way to trigger a regeneration of the U-Boot environment variables in a similar way to how they are initially created when the system boots for the first time from a fresh image? That way, I could avoid overwriting device-specific data like the MAC address, while still applying the correct layout and boot configuration for arm64.

Thanks in advance!

Hi @Pedro-Jesus-Fuentes,

Thanks for reaching out, that’s an interesting use case! It certainly can be done with some custom scripting, but there’s a number of things to watch out for:

  • all of the following probably is best put into a state script, preferably in the ArtifactInstall_Leave stage.
  • please be aware that this introduces a number of single points of failure
  • you can adjust specific variables in the 'u-bootenvironment using thefw_printenv` command
  • only adjusting the live environment works well for the happy path, but it will fail if for whatever reason the environment is corrupted, and falls back to the default which is baked into the u-boot binary.
  • as far as I can tell, there are variables in config.txt which also affect 32bit vs. 64bit.

Takeaway therefore is:

  • be aware that this is a possible destructive, no-rollback, single point of failure operation
  • put the logic for modification into a state script which runs at the latest point in time before final reboot, and still error out if needed.

Greetz,
Josef

Hi Josef,

Thanks for your quick reply! I understand this type of update is risky and difficult to roll back.

For now, I’m using an ArtifactInstall_Leave script to back up both the U-Boot environment sectors and the boot partition. The boot partition and its config.txt are not a problem, since I completely wipe and overwrite them with the arm64 boot files during the update.

What I discovered is that if I clear the U-Boot environment sectors by zeroing them out using dd, and then reboot the system, U-Boot automatically resets the environment to its default values — including critical ones like ethaddr. However, in the parts of the system I’ve tested so far, this reset doesn’t appear to cause any major issues. The only problem I’ve encountered is that mender_boot_part and mender_boot_part_hex also revert to their default values, which breaks Mender’s partition logic.

To handle this, I found that during the ArtifactInstall_Leave phase, I can retrieve the currently active Mender boot partition, and then — after clearing the environment — set that specific value. The system retains this new value while all other variables are safely reset to defaults, which seems to be a workable solution.

I’ve tested this entire flow on an arm64 device, and so far it appears to work correctly. Now I plan to test the same process on an arm32 device as part of the migration to arm64. I believe this approach is on the right track. In the worst case, I can connect to the devices via OTG and recover them manually, so the update is not too critical.

I’ll stay in touch and share further updates as I make progress.

Thanks again for your help!