Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Raspberry Pi 5 support #2914

Merged
merged 31 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
895fdbe
Add initial Raspberry Pi 5 buildroot config
agners Nov 7, 2023
e810552
Add machine-id support via cmdline.txt
agners Nov 7, 2023
5d03e05
Add new entry if entry is missing
agners Nov 7, 2023
59d55d4
Don't overwrite cmdline.txt when adding machine-id
agners Dec 6, 2023
ff1b3bf
Skeleton script for RAUC custom bootloader interface
agners Dec 6, 2023
3260b08
Deploy kernel/device-tree into a RAUC slot specific directory
agners Dec 8, 2023
a7d2cad
Deploy new kernel/device-tree to correct slot on installation
agners Dec 8, 2023
38bdab4
Increase boot size to 128MB
agners Dec 8, 2023
d6c6f5e
Initial tryboot implementation using os_prefix
agners Dec 8, 2023
f6efd8d
Make sure to delete the old slot completely
agners Dec 8, 2023
8adb1dc
Add Busybox xargs for tryboot bootloader script
agners Dec 8, 2023
a0340ae
Compare tryboot bootloader file silently
agners Dec 8, 2023
d3f1392
Revert "Increase boot size to 128MB"
agners Dec 8, 2023
2475841
Use compressed kernel
agners Dec 8, 2023
7542412
Address shellcheck
agners Dec 8, 2023
43a3f92
Address shellcheck issue in rauc-hook
agners Dec 8, 2023
be15f28
Fix shellcheck for rpi-tryboot.sh
agners Dec 8, 2023
e0fbd55
Do not follow source - it gets checked separately
agners Dec 8, 2023
1d4d2dc
Correctly set the slot to boot
agners Dec 8, 2023
9da239e
Apply suggestions from code review
agners Dec 8, 2023
dac5a03
Drop serial console from default cmdline.txt
agners Dec 8, 2023
dde3ec0
Resync rpi5_64_defconfig with rpi4_64_defconfig
agners Dec 8, 2023
4bb5089
Improve machine-id match
agners Dec 8, 2023
d9c488a
Deploy firmware overlays to OS prefix directory
agners Dec 8, 2023
a23c36b
Add Raspberry Pi 5 to documentation
agners Dec 11, 2023
ad12f4e
Bump buildroot
agners Dec 11, 2023
5c404c8
Install device tree overlays from Kernel sources
agners Dec 11, 2023
46fc170
Drop RPi RF modules for now
agners Dec 11, 2023
cb11ece
Use Raspberry 5 specific identifiers for Supervisor/OS Agent
agners Dec 11, 2023
ced4a12
Bump buildroot
agners Dec 12, 2023
ec716c1
Revert "Drop RPi RF modules for now"
agners Dec 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Documentation/boards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
The following boards/devices are supported:

- Raspberry Pi
- Pi 5 ([4 GB](https://www.raspberrypi.com/products/raspberry-pi-5/?variant=raspberry-pi-5-4gb) and [8 GB](https://www.raspberrypi.com/products/raspberry-pi-5/?variant=raspberry-pi-5-8gb) model) 64-bit
- Pi 4 Model B ([1 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-1gb), [2 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-2gb), [4 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-4gb) and [8 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-8gb) model) 32-bit or 64-bit (recommended)
- [Pi 3 Model B](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/) and [B+](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/) 32-bit or 64-bit (recommended)
- [Pi 2](https://www.raspberrypi.com/products/raspberry-pi-2-model-b/) (not recommended)
Expand Down Expand Up @@ -39,6 +40,7 @@ Notes:

|Board|Build|Config|Docs|
|-----|----|------|----|
|Pi5 64-bit |`make rpi5_64` |[rpi5_64](../../buildroot-external/configs/rpi5_64_defconfig)|[raspberrypi](./raspberrypi/)|
|Pi4B 64-bit |`make rpi4_64` |[rpi4_64](../../buildroot-external/configs/rpi4_64_defconfig)|[raspberrypi](./raspberrypi/)|
|Pi4B 32-bit |`make rpi4` |[rpi4](../../buildroot-external/configs/rpi4_defconfig)|[raspberrypi](./raspberrypi/)|
|Pi3B 64-bit |`make rpi3_64` |[rpi3_64](../../buildroot-external/configs/rpi3_64_defconfig)|[raspberrypi](./raspberrypi/)|
Expand Down
1 change: 1 addition & 0 deletions Documentation/boards/raspberrypi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| Raspberry Pi 2 B |2015 | not recommended | [rpi2](../../../buildroot-external/configs/rpi2_defconfig) |
| Raspberry Pi 3 B/B+ |2016/2018 | yes | [rpi3](../../../buildroot-external/configs/rpi3_defconfig) / [rpi3_64](../../../buildroot-external/configs/rpi3_64_defconfig) |
| Raspberry Pi 4 B |2019 | yes | [rpi4](../../../buildroot-external/configs/rpi4_defconfig) / [rpi4_64](../../../buildroot-external/configs/rpi4_64_defconfig) |
| Raspberry Pi 5 |2023 | yes (beta) | [rpi5_64](../../../buildroot-external/configs/rpi5_64_defconfig) |

## Serial console

Expand Down
1 change: 1 addition & 0 deletions Documentation/kernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Default Kernel tree: 6.1
| Raspberry Pi 2 | 6.1.63 |
| Raspberry Pi 3 | 6.1.63 |
| Raspberry Pi 4 | 6.1.63 |
| Raspberry Pi 5 | 6.1.63 |
| Home Assistant Yellow | 6.1.63 |
| Home Assistant Green | 6.1.66 |
| Tinker Board | 6.1.66 |
Expand Down
2 changes: 1 addition & 1 deletion buildroot
1 change: 1 addition & 0 deletions buildroot-external/board/raspberrypi/rpi5-64/cmdline.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
zram.enabled=1 zram.num_devices=3 rootwait cgroup_enable=memory fsck.repair=yes console=tty1 root=PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd rootfstype=squashfs ro rauc.slot=A
53 changes: 53 additions & 0 deletions buildroot-external/board/raspberrypi/rpi5-64/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Run in 64-bit mode
arm_64bit=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

# Use OS prefix for A/B slot (RAUC)
os_prefix=slot-A/
cmdline=/cmdline.txt

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[all]

20 changes: 20 additions & 0 deletions buildroot-external/board/raspberrypi/rpi5-64/hassos-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
# shellcheck disable=SC2155

function hassos_pre_image() {
local BOOT_DATA="$(path_boot_dir)"

mkdir -p "${BOOT_DATA}/slot-A/"
cp "${BINARIES_DIR}"/*.dtb "${BOOT_DATA}/slot-A/"
gzip --stdout "${BINARIES_DIR}"/Image > "${BOOT_DATA}/slot-A/kernel_2712.img"
agners marked this conversation as resolved.
Show resolved Hide resolved
cp -r "${BINARIES_DIR}/overlays/" "${BOOT_DATA}/slot-A/"
cp "${BINARIES_DIR}"/*.dtbo "${BOOT_DATA}/slot-A/overlays/" 2>/dev/null || true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need BR2_PACKAGE_RPI_FIRMWARE=y in the board config, otherwise there will be no DT overlays, as we use those from that package.

Moreover, there should be almost always some overlays (at least in HAOS) - and this currently just fails because the target directory doesn't exist, so even the rpi-rf-mod overlays don't get copied.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the rpi-rf-mod overlays need testing first? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I've added now BR2_PACKAGE_RPI_FIRMWARE=y and an appropriate copy command.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That being said, I wonder if we should do this differently: IMHO either we consider device tree and device tree overlays firmware, and we should both take from there, or we should build both and deploy our builds 🤔 ..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have to pick from those two options, then I vote for using self-built DTBs and overlays. We have to build and supply DTB for Yellow anyway and having the rest built from sources is IMHO more flexible and easier for maintenance than using those from the RPi repo.

Anyway it's been like this for ages and there's no urgency for changing that, but good point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to build and supply DTB for Yellow anyway and having the rest built from sources is IMHO more flexible and easier for maintenance than using those from the RPi repo.

So far we build and supply extra overlays through the rpi-rf-mod package, which is Homematic specific (speaking of which, maybe we should make that more clear in that package name 🤔 ). But other than that we do not supply overlays from the main Linux kernel source tree so far.

IMHO, the current situation is bad, as we mix the device tree from kernel source and overlays from the firmware.

Technically, the device tree is supposed to be provided by the machine's firmware. Like in the x86 world the ACPI tables are part of the BIOS. So there is definitely an argument to make that we should deploy device tree and kernel from the Raspberry Pi provided directory.

However, in the Arm world the boards are much more diverse, and quite often firmware (or part of the firmware) is bundled with the OS. That is also the case in Home Assistant OS: We deploy machine firmware along with the OS (and not just the device trees and overlay, but also Raspberry Pi's start4.elf, or U-Boot which on some boards can be seen as firmware). Now where the individual components of the "firmware" come from are almost implementation detail: The Raspberry Pi device trees and overlays are maintained in their Linux kernel source tree anyway. It is only a matter of do we deploy their pre-built one or do we deploy our own builds.

Deploying our own builds gives us more flexibility and proves to be less confusing/error-prone (as often the newer Linux kernel benefits from a newer/matching device tree).

So with this in mind, I agree let's deploy overlays from our build.

It seems that Buildroot doesn't support that use case yet. But it is a fairly simple extension for the Buildroot build system: home-assistant/buildroot#18.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far we build and supply extra overlays through the rpi-rf-mod package, which is Homematic specific (speaking of which, maybe we should make that more clear in that package name 🤔 ). But other than that we do not supply overlays from the main Linux kernel source tree so far.

Sorry, but didn't follow the discussions closely enough. So what is the exact issue with the rpi-rf-mod since I noticed that you removed its CONFIG options from the rpi5 config file? In fact, it perfectly builds and runs with a rpi5 and the device tree overlay is working nicely AFAICS.

IMHO, the current situation is bad, as we mix the device tree from kernel source and overlays from the firmware.

I am not really sure if this is exactly the case for the RaspberryPi stuff. In fact, AFAIK even for RaspberryPiOS the makers are not directly using the in-tree device tree overlay stuff but rather uses the pre-build rpi-firmware dtbo files from their repository. So I am quite unsure if this would not construct an additional issue here if you guys would now switch to using the dtbo files from the kernel tree rather than pulling them from the rpi-firmware package.

And again. why is disabling/removing the rpi-rf-mod.dtbo required ATM?

Copy link
Member Author

@agners agners Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, it perfectly builds and runs with a rpi5 and the device tree overlay is working nicely AFAICS.

Ok, I wasn't aware that this got tested already, so we can re-enable it if it's known to be working. However, with just these two set:

BR2_PACKAGE_RPI_RF_MOD=y
BR2_PACKAGE_RPI_RF_MOD_DTS=y

I noticed that rpi-rf-mod-rpi1.dtbo gets deployed (besides rpi-rf-mod.dtbo), which I think is just wrong for Raspberry Pi 5? This might be just a config issue, not sure.

Btw, you typically find the rationals behind a change in the individual commits (46fc170 in this case).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jens-maus any thought on the rpi1 mod file? It came in with this commit 9582183.

I am fine re-adding the two config symbols above, but I think we should cleanup the rpi-rf-mod package.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's re-add them before merging and eventually address the rf-mod issues in another PR.

cp "${BOARD_DIR}/config.txt" "${BOOT_DATA}/config.txt"
cp "${BOARD_DIR}/cmdline.txt" "${BOOT_DATA}/cmdline.txt"
}


function hassos_post_image() {
convert_disk_image_xz
}

11 changes: 11 additions & 0 deletions buildroot-external/board/raspberrypi/rpi5-64/meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
BOARD_ID=rpi5-64
BOARD_NAME="RaspberryPi 5 64bit"
CHASSIS=embedded
BOOTLOADER=tryboot
KERNEL_FILE=Image
BOOT_SYS=gpt
BOOT_SIZE=64M
BOOT_SPL=false
BOOT_ENV_SIZE=0x4000
SUPERVISOR_MACHINE=raspberrypi5-64
SUPERVISOR_ARCH=aarch64
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# shellcheck shell=sh
# Shell script functions to manipulate kernel cmdline

# Function to get the value of a key from a command line string
get_value() {
key="$1"
cmdline_string="$2"

# Split the command line string by whitespace and then by '=' using xargs
echo "$cmdline_string" | xargs -n1 | grep "^$key=" | cut -d= -f2-
}

# Function to set or update the value of a key in a command line string
set_value() {
key="$1"
new_value="$2"
cmdline_string="$3"

# Use sed to replace the value of the key if it exists, or add a new key-value pair
if echo "$cmdline_string" | grep -q "$key="; then
echo "$cmdline_string" | sed "s/$key=[^ ]*/$key=$new_value/"
else
echo "$cmdline_string $key=$new_value"
fi
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/sh

# shellcheck source=/dev/null # Our GitHub Actions tests this separately
. /usr/lib/rauc/cmdline.sh

# RAUC hook script for Raspberry Pi firmwaree tryboot
# Meant to be usesd as a RAUC bootloader-custom-backend script.

boot_dir="/mnt/boot"
root_slot_a="PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd"
root_slot_b="PARTUUID=a3ec664e-32ce-4665-95ea-7ae90ce9aa20"

case "$1" in
get-primary)
# Actions to be performed when getting the primary bootloader
# Example: Output the path to the current primary bootloader
echo "tryboot get-primary" >&2
cmdline=$(head -n1 "${boot_dir}/cmdline.txt")
get_value rauc.slot "${cmdline}"
;;

set-primary)
# Actions to be performed when setting the primary bootloader
# Example: Set the specified bootloader as the primary one
slot_bootname="$2"
echo "tryboot set-primary $slot_bootname" >&2
cmdline=$(head -n1 "${boot_dir}/cmdline.txt")
if [ "${slot_bootname}" = "A" ]; then
cmdline=$(set_value root "${root_slot_a}" "${cmdline}")
elif [ "${slot_bootname}" = "B" ]; then
cmdline=$(set_value root "${root_slot_b}" "${cmdline}")
else
exit 1
fi
cmdline=$(set_value rauc.slot "${slot_bootname}" "${cmdline}")
echo "${cmdline}" > "${boot_dir}/cmdline-tryboot.txt"
sed -e "s/^\(os_prefix=\)slot-[A-Z]\/$/\1slot-${slot_bootname}\//" \
-e "s/^\(cmdline=\).*$/\1\/cmdline-tryboot.txt/" \
"${boot_dir}/config.txt" > "${boot_dir}/tryboot.txt"
# Use tryboot to try booting the new primary on reboot
echo "0 tryboot" > /run/systemd/reboot-param
;;

get-state)
# Actions to be performed when getting the bootloader state
# Example: Output the current state of the bootloader
# You need to implement logic to determine the state (good or bad) based on the slot.bootname
slot_bootname="$2"
echo "tryboot get-state $slot_bootname" >&2
if [ -f "${boot_dir}/slot-${slot_bootname}/.good" ]; then
echo "returning good" >&2
echo "good"
else
echo "returning bad" >&2
echo "bad"
fi
;;

set-state)
# Actions to be performed when setting the bootloader state
# Example: Set the specified state for the bootloader
slot_bootname="$2"
new_state="$3"
echo "tryboot set-state $slot_bootname $new_state" >&2
if [ "${new_state}" = "good" ]; then
touch "${boot_dir}/slot-${slot_bootname}/.good"
else
rm -f "${boot_dir}/slot-${slot_bootname}/.good"
exit 0
fi

# It seems we call set-state in any case. Use this to "commit" tryboot
# state...

# Check if tryboot is active
if ! cmp -s -n 4 /proc/device-tree/chosen/bootloader/tryboot /dev/zero; then
cmdline_tryboot=$(head -n1 "${boot_dir}/cmdline-tryboot.txt")
tryboot_slot=$(get_value rauc.slot "${cmdline_tryboot}")
if [ "${tryboot_slot}" != "${slot_bootname}" ]; then
echo "tryboot doesn't reflect the expected boot slot, not committing." >&2
exit 1
fi
echo "Committing tryboot state to primary boot" >&2
mv "${boot_dir}/tryboot.txt" "${boot_dir}/config.txt"
mv "${boot_dir}/cmdline-tryboot.txt" "${boot_dir}/cmdline.txt"
fi
;;

get-current)
# We don't have a better detection then /proc/cmdline...
echo "Cannot reliably determine current slot with tryboot" >&2
exit 1
;;

*)
echo "Unknown operation: $1"
exit 1
;;
esac

exit 0
2 changes: 1 addition & 1 deletion buildroot-external/busybox.config
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ CONFIG_GREP=y
# CONFIG_EGREP is not set
# CONFIG_FGREP is not set
# CONFIG_FEATURE_GREP_CONTEXT is not set
# CONFIG_XARGS is not set
CONFIG_XARGS=y
# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
Expand Down
Loading
Loading