Closed koehlma closed 9 months ago
swupdate might also be worth evaluating as it does have the potential to stream the new images to partition (though I haven't used it personally).
Streaming the new image directly to the cold partition is attractive for devices with little available disk space. Mender supports streaming by default.
I decided against using RAUC or SWUpdate as a basis (for now). Integrating with them would add a lot of complexity (both in terms of required configuration and the building pipeline). As it turns out, getting a U-Boot setup working was easier than anticipated. And, by doing this ourselves, we gain more flexibility going ahead and overall achieve greater consistency between the different boot flows.
Rugpi Bakery does now support an option boot_flow = "u-boot"
to enable the U-Boot boot flow (this also disables the tryboot
boot flow). I modeled the U-Boot boot flow after the tryboot
boot flow such that they are more consistent (still need to update the docs). In particular, committing works by writing a file to the config
partition.
I tested the image built with the U-Boot boot flow and the Bullseye-based release of Raspberry Pi OS on a Raspberry Pi 3. In principle, the same image should work for Zero 2W as the device tree loaded by the Raspberry Pi firmware is used (or at least that is what the U-Boot documentation claims).
@reubenmiller Could you please test, whether it works on the Zero 2W?
Rugpi now also has experimental support for streaming images directly to the SD card by using --stream
. You can use
rugpi-ctrl update install --stream -
to install an image streamed to stdin, e.g., via curl
. This also allows using compressed images by piping them through xz
(or gzip
). Mid-term, streaming should also become the default.
@koehlma I must be doing something wrong, as I can't get the image to boot on Raspberry PI 3 or Zero 2W.
I've set the boot flow in the rugpi-bakery.toml
(see my project here: https://github.com/reubenmiller/rpi-tedge-image/tree/support-rp3), and I've made sure the latest docker image
boot_flow = "u-boot"
I've tried the following images (buster and bookworm):
And to confirm that there was nothing wrong with my sd card or my usage of the Raspberry Pi Imager, switching to the official images is able to boot both devices successfully.
No, you are doing everything right. GitHub Actions does not include LFS files by default. The U-Boot binaries are stored in LFS. Instead of them, their stubs were then baked into the image. Commit 94fd6e7 should fix that. If you are building the Docker image yourself, please make sure that you have a working LFS setup.
Edit: The integrity of the binaries will now also be verified when building the Docker image (see 44f3f70).
Perfect. I’ll give the images a try again in the next day.
I've been able to successfully test initial bootstrapping and using the u-boot and everything works as expected 🥇
Procedure
boot_flow = "u-boot"
option)Devices under Test
✅ = PASS
Any idea on the effort to support older 32 bit Pi models such as, Raspberry Pi 1, 2 and Zero? I would be happy to assist with testing (if that helps).
That's great news!
For 32-bit support, first Rugpi Bakery needs to be made aware of the architecture (currently, it simply assumes arm64
). As far as I know, there are three different architectures which we would have to support: arm64
(ARMv8), armhf
(ARMv7), and armel
(ARMv6). At least this is how the CPU families fit into Debian's architecture schema.
Raspberry Pi 2 B v1.2 is actually based on ARMv8 (same chip family as Pi 3) and should support 64-bit. However, I am not sure whether this is properly supported by the bootrom (first stage bootloader burned into the ROM of the chip). I can test the existing U-Boot boot flow with it later – maybe it just works. ;) I tried using the existing image and U-Boot binary and copied over the respective .dtb
s but it did not work.
In any case, supporting armhf
, i.e., the entire Raspberry Pi 2 family, should be rather easy. We would have to produce U-Boot binaries and adapt Rugpi Bakery to place them together with an appropriate config.txt
in the image. Rugpi Ctrl gets build for armhf
already. The recipe installing it simply needs to be made aware of the architecture. This should all be easily doable in an afternoon.
For Raspberry Pi 1 and Zero, I am not sure. Actually, it is still a bit unclear to me how there can just be one armhf
image apparently working on all Pis. It seems like this involves some customization as it falls between the officially supported Debian architectures armhf
and armel
.^1 I guess, building Rugpi Ctrl for arm-unknown-linux-musleabihf
instead of armv7-unknown-linux-musleabihf
would do the trick – but I have to investigate this further.
Do you think that someone starting a new project with Rugpi today would like to use those older boards? Or, is this just so that existing setups can switch to Rugpi? I would like to understand the use case better before investing time into this.
That's great news!
For 32-bit support, first Rugpi Bakery needs to be made aware of the architecture (currently, it simply assumes
arm64
). As far as I know, there are three different architectures which we would have to support:arm64
(ARMv8),armhf
(ARMv7), andarmel
(ARMv6). At least this is how the CPU families fit into Debian's architecture schema.Raspberry Pi 2 B v1.2 is actually based on ARMv8 (same chip family as Pi 3) and should support 64-bit. However, I am not sure whether this is properly supported by the bootrom (first stage bootloader burned into the ROM of the chip). ~I can test the existing U-Boot boot flow with it later – maybe it just works. ;)~ I tried using the existing image and U-Boot binary and copied over the respective
.dtb
s but it did not work.In any case, supporting
armhf
, i.e., the entire Raspberry Pi 2 family, should be rather easy. We would have to produce U-Boot binaries and adapt Rugpi Bakery to place them together with an appropriateconfig.txt
in the image. Rugpi Ctrl gets build forarmhf
already. The recipe installing it simply needs to be made aware of the architecture. This should all be easily doable in an afternoon.For Raspberry Pi 1 and Zero, I am not sure. Actually, it is still a bit unclear to me how there can just be one
armhf
image apparently working on all Pis. It seems like this involves some customization as it falls between the officially supported Debian architecturesarmhf
andarmel
.1 I guess, building Rugpi Ctrl forarm-unknown-linux-musleabihf
instead ofarmv7-unknown-linux-musleabihf
would do the trick – but I have to investigate this further.Do you think that someone starting a new project with Rugpi today would like to use those older boards? Or, is this just so that existing setups can switch to Rugpi? I would like to understand the use case better before investing time into this.
Footnotes
I was able to run the same image and do an image update on a Raspberry Pi 2 Model B Rev 1.2
. I've done one successful update, so I'm happy to monitor future updates on this device to see if it could fall under the "supported" category.
Generally I think you can skip support for Raspberry 1 and Zero as these devices are very limited (only single core processors). I was just curious to see if it was an easy-win or not, as some customers are pushing for lower cost devices all the time and consider using older devices with lower specs just to save the per-unit cost....however I would still avoid those customers to avoid a single core cpu if possible.
I just realized that what I believed to be a Pi 2 B v1.2 is actually a Pi 1 B+ v1.2. That is probably the reason why it did not work.
Yes, that makes sense. Let's see. Of course, it would also be nice if we can just claim that every Pi model is supported. At some point it may also make sense to look at other boards than Raspberry Pi.
There may now be support for Pi 1, Pi 2, and Pi Zero. You need to use the following settings:
architecture = "armhf"
boot_flow = "u-boot"
They have to be used for customize
and for bake
.
And, of course, a 32-bit base image must be used (Bookworm worked for me).
I did test the resulting image on a Pi 1 B+ v1.2 and it seems to work.
@reubenmiller Can you please test whether this works on Pi Zero and Pi 2? The image should be identical for all those boards as the bootloader is selected by a filter in config.txt
.
Took me a bit less than an hour to get that working.
@koehlma I'm checking the images now, though I ran in to the classic error of forgetting to install the armhf
using tonistiigi/binfmt
, so should probably make it into the docs after we can confirm the image is working (should have confirmation within 12 hours)...
But for those reading this, if you are building for armhf
, then make sure you run the following command first.
docker run --privileged --rm tonistiigi/binfmt --install armhf
Sorry I'm distracted by other activities at the moment...but I should have something to report in the next few days.
After doing some testing I can confirm that I have been able to successfully build and flash the image, and do one OTA update (using thin-edge.io to apply the update, see tedge-rugpi-image).
Note: The above devices take 15-25 minutes to update given that they only have a one-core CPU.
The testing took longer than expected due to complications in the build process introduced because of the differences in the actual CPU architecture being used during the creation of the image, and the target device. Because of this, the install scripts I was using in the build was wrongly installing the armv7l (armv7-unknown-linux-musleabihf) version rather than the armv6 version of thin-edge.io (arm-unknown-linux-musleabihf).
Below shows the differences in the architectures in the build and target device:
At build time
$ uname -m
armv7l
At runtime (on device, pi0 and pi 1B)
$ uname -m
armv6l
I'm not sure if there is a better way to handle as the special "armv6" is not widely supported outside of Raspberry PI 1 and Zero, and causes a lot of issues (as you can't use the public debian repositories as armhf usually refers to armv7l and not armv6l).
Great, thanks!
Indeed, the whole situation with the different architectures is a bit of a mess. In general, the architecture of a binary is automatically determined by binfmt_misc
and the binary is then run via QEMU. We are not doing anything special here. I guess, this is then also what uname
reports. Rugpi Ctrl is also compiled for arm-unknown-linux-musleabihf
. Unfortunately, I do not think that we can do anything about it, except mentioning it in the docs.
I will close this issue now. It was an easy win after all. ;)
I am now also confident that we can rather easily support other boards, should the need arise.
As the next step, I will focus on introducing a layer architecture similar to Docker and enabling delta updates that way.
In principle, it should be possible to add support for older boards without the
tryboot
feature by using U-Boot as an intermediate bootloader. U-Boot would then be responsible for switching between A/B partitions. This would also open up the possibility to use Rugpi with other boards than Raspberry Pi. If you want to see this happen, please give this issue a 👍.Known Caveats
config.txt
and it needs to be configured to load the bootloader instead of the kernel.Open Questions
tryboot
switching within RAUC.