-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
1,169 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"label": "Advanced Topics", | ||
"position": 20, | ||
"link": { | ||
"type": "doc", | ||
"id": "index" | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
www/versioned_docs/version-0.7.0/advanced/boot-flows.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
sidebar_position: 4 | ||
--- | ||
|
||
# Boot Flows | ||
|
||
A *boot flow* provides the base mechanism to switch between the A and B system, e.g., after installing an update. | ||
To this end, it must implement two primitive operations: (i) rebooting to the spare system once and (ii) setting the default system. | ||
Boot flows are typically implemented on top of a bootloader and Rugpi offers out-of-the-box integrations with popular bootloaders: | ||
|
||
- [Raspberry Pi's `tryboot` Mechanism](https://www.raspberrypi.com/documentation/computers/config_txt.html#example-update-flow-for-ab-booting) | ||
- [U-Boot](https://docs.u-boot.org/en/latest/) (popular on single board computers, GPL-2.0) | ||
- [Grub](https://www.gnu.org/software/grub/) (well-established standard option, GPL-3.0) | ||
<!-- - [Systemd Boot](https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html) (newer alternative to Grub, GPL-2.0) --> | ||
|
||
The boot flow for an image is chosen based on the target of the image as configured in `rugpi-bakery.toml`. | ||
Depending on the boot flow, Rugpi will automatically select an appropriate partitioning scheme for the image and system. | ||
|
||
## Supported Boot Flows | ||
|
||
We will now discuss the supported boot flows in more detail. | ||
|
||
### Tryboot | ||
|
||
``` | ||
MBR =============================== Image | ||
1: config FAT32 256M | ||
2: boot-a FAT32 128M (*) | ||
3: boot-b FAT32 128M | ||
5: system-a (*) | ||
=============================== System | ||
6: system-b | ||
7: data EXT4 .... | ||
``` | ||
|
||
The `tryboot` boot flow works almost as described in [Raspberry Pi's documentation on the `tryboot` mechanism](https://www.raspberrypi.com/documentation/computers/config_txt.html#example-update-flow-for-ab-booting). | ||
Instead of reading the device tree `tryboot` flag, it compares the booted partition with the default stored in `autoboot.txt`. | ||
|
||
This boot flow also allows updating the `config.txt` file as well as the device tree files. | ||
|
||
### U-Boot | ||
|
||
``` | ||
MBR =============================== Image | ||
1: config FAT32 256M | ||
2: boot-a FAT32 128M (*) | ||
3: boot-b FAT32 128M | ||
5: system-a (*) | ||
=============================== System | ||
6: system-b | ||
7: data EXT4 .... | ||
``` | ||
|
||
Rugpi supports upstream U-Boot, i.e., it does not require any patches to it. | ||
Rugpi achieves this by using U-Boot boot scripts to control the boot process. | ||
To this end, it relies on two environment files, `bootpart.default.env` and `boot_spare.env`, placed in the first partition, i.e., the `config` partition, of the boot drive. | ||
The file `bootpart.default.env` sets the `bootpart` variable either to `2` or to `3` indicating the default boot partition (`boot-a` or `boot-b`). | ||
The file `boot_spare.env` sets the `boot_spare` variable either to `1` or to `0` indicating whether the spare or default partition should be booted, respectively. | ||
These files can then be used by U-Boot boot scripts to control the boot process. | ||
In addition, there are the files `boot_spare.enabled.env` and `boot_spare.disabled.env` for overwriting the `boot_spare.env` file, e.g., to reset `boot_spare` to `0`. | ||
|
||
A typical U-Boot boot script would proceed as follows: | ||
|
||
1. Load `bootpart.default.env` and `boot_spare.env`. | ||
2. If `boot_spare` is set to `1`, invert `bootpart`. | ||
3. if `boot_spare` is set to `1`, overwrite `boot_spare.env` with `boot_spare.disabled.env`. | ||
4. Proceed booting from the respective partition. | ||
|
||
The reference implementation for Raspberry Pi uses two boot scripts, one first stage boot script on the config partition and a second stage boot script on the respective boot partition. | ||
The first stage follows the steps outlined above and then loads the second stage boot script. | ||
This has the advantage that the second stage script can be updated in a fail-safe way. | ||
|
||
For further details, we refer to the reference [boot scripts](https://github.com/silitics/rugpi/tree/main/boot/u-boot/scripts) for Raspberry Pi. | ||
|
||
### Grub (EFI) | ||
|
||
``` | ||
GPT =============================== Image | ||
1: config FAT32 256M | ||
2: boot-a EXT4 128M (*) | ||
3: boot-b EXT4 128M | ||
5: system-a (*) | ||
=============================== System | ||
6: system-b | ||
7: data EXT4 .... | ||
``` | ||
|
||
Follows a similar approach to U-Boot, using Grub boot scripts and environment blocks. | ||
|
||
### Systemd Boot | ||
|
||
:::warning | ||
|
||
**Not implemented yet!** | ||
|
||
::: | ||
|
||
``` | ||
GPT =============================== Image | ||
1: EFI FAT32 512M (*) | ||
2: system-a (*) | ||
=============================== System | ||
3: system-b | ||
4: data EXT4 .... | ||
``` | ||
|
||
Uses the [Boot Loader Interface](https://systemd.io/BOOT_LOADER_INTERFACE/) for A/B updates by writing to the following EFI variables: | ||
|
||
- `LoaderEntryDefault-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f` (default entry) | ||
- `LoaderEntryOneShot-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f` (oneshot entry) | ||
|
||
In contrast to the other boot flows there are no separate boot partitions. | ||
|
||
## Runtime Detection | ||
|
||
Rugpi detects the boot flow of a system dynamically at runtime by inspecting the first partition: | ||
|
||
1. If a file `autoboot.txt` exists, then the boot flow is `tryboot`. | ||
2. If a file `bootpart.default.env` exists, then the boot flow is `u-boot`. | ||
3. If a file `rugpi/grub.cfg` and a directory `EFI` exist, then the boot flow is `grub-efi`. | ||
<!-- 4. If a file `loader/loader.conf` exists, then the boot flow is `systemd-boot`. --> | ||
|
||
This information is used for repartitioning the root drive and interpreting updates. | ||
|
||
## On Atomicity of Commits | ||
|
||
Note that commits are the only critical operation because they modify the default partition set. | ||
This is usually done by temporarily remounting the bootloader configuration partition such that it is writeable and then replacing some files. | ||
As the filesystem is FAT32, the automitcity of this operation cannot be guaranteed. | ||
Still, Rugpi Ctrl does its best by first creating a new file and then replacing the old one with the new one by renaming it, and, the Linux kernel does guarantee atomicity for renaming. | ||
However, should the system crash during this process, the FAT32 filesystem may still be corrupted. | ||
We think that this is an acceptable risk as the likelihood of it happening is very low and any alternatives, like swapping the MBR, may be problematic for other reasons.[^4] | ||
|
||
[^4]: If you have any suggestions, please share them with us. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Advanced Topics |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
sidebar_position: 200 | ||
--- | ||
|
||
# Raspberry Pi | ||
|
||
In principle, Rugpi supports all Raspberry Pi models. | ||
|
||
Here is an overview over all the supported Raspberry Pi models: | ||
|
||
| Pi 5 | Pi 4 | Pi 3 | Pi 2 v1.2 | Pi 2 | Pi 1 | Pi Zero 2 | Pi Zero | CM 4 | CM 3 | CM 1 | | ||
| ---- | ---- | ------ | --------- | ----- | ------ | --------- | ------- | ---- | ----- | ------ | | ||
| ✅ | ✅ | ✅[^1] | ✅[^1] | 🤷♂️[^1] | ✅[^1] | ✅[^1] | ✅[^1] | ✅ | 🤷♂️[^1] | 🤷♂️[^1] | | ||
|
||
✅ fully supported, 🤷♂️ in principle supported but untested | ||
|
||
[^1]: Requires the U-Boot boot flow. | ||
|
||
**⚠️ Please also read the remarks for the respective boards bellow.** | ||
|
||
Raspberry Pi OS releases based on Debian Bullseye and Bookworm are supported. | ||
|
||
For 32-bit models and to build 32-bit images for 64-bit boards, you need to set the `architecture` for the respective image to: | ||
```toml | ||
architecture = "armhf" | ||
``` | ||
|
||
To build 32-bit images, you also need to enable emulation of `armhf` in Docker: | ||
```shell | ||
docker run --privileged --rm tonistiigi/binfmt --install armhf | ||
``` | ||
|
||
For `armhf`, note that the architecture reported by `uname -m` during the build process is `armv7l`, however, when running the image later on a non-ARMv7 board (e.g., Pi Zero or Pi 1), then the architecture will be `armv6l`. | ||
Make sure that the binaries you install are compatible with the `armv6l` architecture, if you aim to deploy the image to these boards. | ||
|
||
### Raspberry Pi 5 | ||
|
||
Updating the bootloader is not necessary for Raspberry Pi 5, as it already comes with the `tryboot` feature out-of-the-box. | ||
|
||
### Raspberry Pi 4 and Compute Module 4 | ||
|
||
The bootloader version shipped with Raspberry Pi 4 and Compute Module 4 does not support the `tryboot` feature out-of-the-box. | ||
To use Rugpi with these boards, the bootloader stored in the EEPROM must be updated to at least version `2023-05-11`. | ||
For Compute Module 4, this requires `usbboot` (see [CM4's documentation for details](https://www.raspberrypi.com/documentation/computers/compute-module.html#flashing-the-bootloader-eeprom-compute-module-4) or check out [this blog post by Jeff Geerling](https://www.jeffgeerling.com/blog/2022/how-update-raspberry-pi-compute-module-4-bootloader-eeprom)). | ||
For Raspberry Pi 4, you can use the `core/rpi-include-firmware` recipe to include the update in the image. | ||
The bootloader will then be automatically updated when first booting the image. | ||
Note that after the first boot, the automatic update will be disabled, i.e., you cannot take the SD card to another Raspberry Pi which does not yet have the update installed. | ||
Note that the resulting image will be specific for Raspberry Pi 4, do not use it for any other models. | ||
|
||
### Other Models | ||
|
||
For other models than Pi 5, Pi 4, Pi 400, and CM 4, you must use the `rpi-uboot` target. | ||
|
||
**⚠️ The U-Boot boot flow is experimental and does not allow updating the Raspberry Pi bootloader/firmware.** | ||
|
||
[^1]: To prevent the EEPROM from being updated on each boot. |
46 changes: 46 additions & 0 deletions
46
www/versioned_docs/version-0.7.0/advanced/reproducible-builds.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Reproducible Builds | ||
|
||
At Rugpi, we are huge proponents of [*reproducible builds*](https://reproducible-builds.org/). | ||
|
||
> “A build is *reproducible* if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts.” – https://reproducible-builds.org/docs/definition/ | ||
We aim to enable reproducible builds of Rugpi itself as well as of system images built with Rugpi. | ||
|
||
**Note that this is a work-in-progress effort and we are not there yet.** | ||
|
||
## Reproducibility of Rugpi | ||
|
||
> Given a commit hash of Rugpi, everyone should be able to reproduce all Rugpi-related binaries that may end up in images as well as the Docker image for Rugpi Bakery. This includes binaries of third-party software, e.g., Grub and U-Boot. | ||
Reproducible builds require a known build environment. | ||
To this end, we use [Debian's official snapshots](https://snapshot.debian.org/) as a basis. | ||
Note that most [Debian packages are also fully reproducible](https://tests.reproducible-builds.org/debian/reproducible.html), so one could in principle trace everything back its source code. | ||
Building upon Debian snapshots also has the advantage that it reduces the surface area that must be checked for Rugpi, provided that one trusts Debian. | ||
|
||
To obtain a reproducible build environment, we follow a two stage process: | ||
|
||
- Stage 0: We build a Debian Docker image containing [`mmdebstrap`](https://manpages.debian.org/bookworm/mmdebstrap/mmdebstrap.1.en.html). | ||
This image will not be reproducible as it is based on the latest version of Debian Bookworm. | ||
We are only using it to bootstrap Stage 1. | ||
- Stage 1: Using the previously built Docker image, we bootstrap a Debian Docker image based on an official snapshot. | ||
This image will be fully reproducible and everything we install will be pinned to the respective snapshot. | ||
Thereby, all images that we derive from it, e.g., to build Rugpi, Grub, or U-Boot, are also fully reproducible. | ||
|
||
Everything else we built will be based on the reproducible Stage 1 image. | ||
|
||
The infrastructure for reproducible builds is implemented as part of Rugpi's [`xtask`](https://github.com/silitics/rugpi/tree/main/xtask). | ||
|
||
## Reproducibility of Images | ||
|
||
**🚧 This is work-in-progress. 🚧** | ||
|
||
Reproducibility of Rugpi is a prerequisite for reproducible system images. | ||
|
||
Furthermore, reproducibility of images requires support by the underlying Linux distribution. | ||
In particular, it requires that a distribution provides immutable snapshots of their repositories (rebuilding packages is outside the scope of Rugpi). | ||
|
||
Among the distributions supported by Rugpi, only Debian [officially provides immutable snapshots](https://snapshot.debian.org/) of their repositories. | ||
Furthermore, Debian also participates in the Reproducible Builds project's [continuous reproducibility testing of their packages](https://tests.reproducible-builds.org/debian/reproducible.html). | ||
We aim to eventually support building fully reproducible Debian images based on the official snapshots. | ||
|
||
For other distributions and base layers built with third-party tools (e.g., Yocto Project and Buildroot), we aim to make images reproducible under the assumption that the external inputs (repositories, base layer, …) do not change. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"label": "Cookbook", | ||
"position": 20, | ||
"link": { | ||
"type": "doc", | ||
"id": "index" | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
www/versioned_docs/version-0.7.0/cookbook/discoverability.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Discoverability | ||
|
||
Sometimes an embedded device should be automatically discoverable in a network. | ||
For instance, automatic discovery allows service technicians to scan for devices and users to find and access devices more easily. | ||
|
||
To facility discovery, [Avahi](https://www.avahi.org/) can be used. | ||
To install Avahi, you can use the [Avahi Recipe](https://github.com/silitics/rugpi-extra/tree/main/recipes/avahi) available in the [`rugpi-extra` repository](https://github.com/silitics/rugpi-extra/tree/main). | ||
|
||
Installing Avahi makes it possible to reach the system under the local domain name `<hostname>.local` in the local network via [Multicast DNS](https://datatracker.ietf.org/doc/html/rfc6762). | ||
As a result, it is easy to access the Raspberry Pi simply by entering its hostname followed by `.local`, e.g., in the navigation bar of a browser. | ||
In addition, the recipe allows making SSH, SFTP, and an HTTP interface discoverable via [DNS-SD](https://datatracker.ietf.org/doc/html/rfc6763). | ||
To this end, use the recipe's parameters. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Cookbook | ||
|
||
A collection of guides and recipes for reoccurring problems. |
Oops, something went wrong.