From 9b057ad54772bef4f2c1ac55c268f8e15cdf08bf Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sat, 18 Oct 2025 13:58:39 +0200 Subject: [PATCH] Support for Raspberry Pi 3B (BCM2837) The BCM2837 core is used not just in the RPi 3B but also in the Zero 2W, both device trees have been added to the board config. The BCM2711 support has been extended to include RPi 400 and CM4 I/O. To support the BCM2837 family more firmware options habe been enabled, since the RPi3 does not have bootcode.bin flashed in the SoC. The SD card image now uses a hybrid GPT/MBR format so the RPi3 bootcode.bin can read all files from the first VFAT partition. The default device tree for Linux is now chosen by the U-Boot probe and the only exception is the "laundry room" detector that looks for a RPi4 with a 7" touch screen, which then selects the DSI enabled RPi4 variant. This is enough to properly load an RPi 3B and a CM4 based router board. The BCM2837 does not have PCI/PCIe or a built-in MAC so it relies on the USB to Ethernet LAN78xx which does not support disabling pause frames. I have opted for checking for EOPNOTSUPP instead of adding yet another quirk, because it is likely to be a common limitation of more drivers and chipsets, and this code is best-effort anyway. Signed-off-by: Joachim Wiberg --- configs/rpi4_boot_defconfig | 3 ++ .../board/raspberry-pi-4/raspberry-pi-4.mk | 1 + src/board/raspberry-pi-4/config.txt | 52 ++++++++----------- src/board/raspberry-pi-4/dts/Makefile | 4 +- .../dts/broadcom/bcm2711-rpi-4-b.dts | 6 +-- .../dts/broadcom/bcm2711-rpi-400.dts | 9 ++++ .../dts/broadcom/bcm2711-rpi-cm4-io.dts | 9 ++++ .../dts/broadcom/bcm2837-rpi-3-b.dts | 9 ++++ .../dts/broadcom/bcm2837-rpi-zero-2-w.dts | 9 ++++ .../raspberry-pi-4/dts/broadcom/infix.dtsi | 13 +++++ src/board/raspberry-pi-4/genimage.cfg.in | 18 +++---- .../usr/share/product/raspberrypi,3-model-b | 1 + .../etc/factory-config.cfg | 2 +- src/board/raspberry-pi-4/uboot/rpi-env.dtso | 2 +- src/confd/src/ieee802-ethernet-interface.c | 15 +++++- 15 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-400.dts create mode 100644 src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-cm4-io.dts create mode 100644 src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-3-b.dts create mode 100644 src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-zero-2-w.dts create mode 100644 src/board/raspberry-pi-4/dts/broadcom/infix.dtsi create mode 120000 src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,3-model-b diff --git a/configs/rpi4_boot_defconfig b/configs/rpi4_boot_defconfig index d0a39a19..140dcdc4 100644 --- a/configs/rpi4_boot_defconfig +++ b/configs/rpi4_boot_defconfig @@ -14,6 +14,9 @@ BR2_SYSTEM_BIN_SH_NONE=y BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh" # BR2_PACKAGE_BUSYBOX is not set BR2_PACKAGE_RPI_FIRMWARE=y +BR2_PACKAGE_RPI_FIRMWARE_BOOTCODE_BIN=y +BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI=y +BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI_X=y BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4_X=y BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi-4/config.txt" diff --git a/package/board/raspberry-pi-4/raspberry-pi-4.mk b/package/board/raspberry-pi-4/raspberry-pi-4.mk index 2dc74bfd..88f36c8a 100644 --- a/package/board/raspberry-pi-4/raspberry-pi-4.mk +++ b/package/board/raspberry-pi-4/raspberry-pi-4.mk @@ -22,6 +22,7 @@ define RASPBERRY_PI_4_LINUX_CONFIG_FIXUPS $(call KCONFIG_SET_OPT,CONFIG_BRCMFMAC,m) $(call KCONFIG_ENABLE_OPT,CONFIG_BRCMFMAC_SDIO) $(call KCONFIG_SET_OPT,CONFIG_I2C_BCM2835,m) + $(call KCONFIG_SET_OPT,CONFIG_BCM2835_THERMAL,m) $(call KCONFIG_SET_OPT,CONFIG_BCM2711_THERMAL,m) $(call KCONFIG_ENABLE_OPT,CONFIG_MMC_BCM2835) $(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_IPROC) diff --git a/src/board/raspberry-pi-4/config.txt b/src/board/raspberry-pi-4/config.txt index 01bfe0dd..46d2e906 100644 --- a/src/board/raspberry-pi-4/config.txt +++ b/src/board/raspberry-pi-4/config.txt @@ -1,43 +1,35 @@ -# Please note that this is only a sample, we recommend you to change it to fit -# your needs. -# You should override this file using BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE. -# See http://buildroot.org/manual.html#rootfs-custom -# and http://elinux.org/RPiconfig for a description of config.txt syntax +[all] +arm_64bit=1 -start_file=start4.elf -fixup_file=fixup4.dat +arm_boost=1 +force_turbo=1 kernel=u-boot.bin -device_tree=bcm2711-rpi-4-b.dtb dtoverlay=rpi-env dtoverlay=infix-key + +disable_overscan=1 + +enable_uart=1 +uart_2ndstage=1 + +[pi3] +start_file=start.elf +fixup_file=fixup.dat + +dtoverlay=miniuart-bt + +gpu_mem=100 + +[pi4] +start_file=start4.elf +fixup_file=fixup4.dat + dtoverlay=vc4-kms-v3d-pi4 lcd_rotate=2 - # Prevent console on DSI console=map:0 -# To use an external initramfs file -#initramfs rootfs.cpio.gz - -# Disable overscan assuming the display supports displaying the full resolution -# If the text shown on the screen disappears off the edge, comment this out -disable_overscan=1 - gpu_mem=256 - -# Enable UART0 for serial console on ttyAMA0 -enable_uart=1 -force_turbo=1 -#dtoverlay=miniuart-bt - -# Run as fast as firmware / board allows -arm_boost=1 - -# enable 64bits support -arm_64bit=1 - -# Enable early debugging info -uart_2ndstage=1 diff --git a/src/board/raspberry-pi-4/dts/Makefile b/src/board/raspberry-pi-4/dts/Makefile index 0b6f5ce9..e96346bb 100644 --- a/src/board/raspberry-pi-4/dts/Makefile +++ b/src/board/raspberry-pi-4/dts/Makefile @@ -1 +1,3 @@ -dtb-y += broadcom/bcm2711-rpi-4-b.dtb broadcom/bcm2711-rpi-4-b-dsi.dtb +dtb-y += broadcom/bcm2837-rpi-3-b.dtb broadcom/bcm2837-rpi-zero-2-w.dtb \ + broadcom/bcm2711-rpi-4-b.dtb broadcom/bcm2711-rpi-4-b-dsi.dtb \ + broadcom/bcm2711-rpi-400.dtb broadcom/bcm2711-rpi-cm4-io.dtb diff --git a/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-4-b.dts b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-4-b.dts index 3153526f..2f557a9f 100644 --- a/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-4-b.dts +++ b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-4-b.dts @@ -1,4 +1,5 @@ #include +#include "infix.dtsi" / { /* Dynamic GPU reservation */ @@ -21,11 +22,6 @@ chosen { /* 8250 auxiliary UART instead of pl011 */ stdout-path = "serial1:115200n8"; - - infix { - /* Default admin user password: 'admin' */ - factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"; - }; }; }; diff --git a/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-400.dts b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-400.dts new file mode 100644 index 00000000..4bfb26da --- /dev/null +++ b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-400.dts @@ -0,0 +1,9 @@ +#include +#include "infix.dtsi" + +/ { + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; +}; diff --git a/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-cm4-io.dts b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-cm4-io.dts new file mode 100644 index 00000000..370edfac --- /dev/null +++ b/src/board/raspberry-pi-4/dts/broadcom/bcm2711-rpi-cm4-io.dts @@ -0,0 +1,9 @@ +#include +#include "infix.dtsi" + +/ { + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; +}; diff --git a/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-3-b.dts b/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-3-b.dts new file mode 100644 index 00000000..d93a4b0c --- /dev/null +++ b/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-3-b.dts @@ -0,0 +1,9 @@ +#include +#include "infix.dtsi" + +/ { + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; +}; diff --git a/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-zero-2-w.dts b/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-zero-2-w.dts new file mode 100644 index 00000000..58623875 --- /dev/null +++ b/src/board/raspberry-pi-4/dts/broadcom/bcm2837-rpi-zero-2-w.dts @@ -0,0 +1,9 @@ +#include +#include "infix.dtsi" + +/ { + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; +}; diff --git a/src/board/raspberry-pi-4/dts/broadcom/infix.dtsi b/src/board/raspberry-pi-4/dts/broadcom/infix.dtsi new file mode 100644 index 00000000..16cfafc8 --- /dev/null +++ b/src/board/raspberry-pi-4/dts/broadcom/infix.dtsi @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Infix OS defaults + */ + +/ { + chosen { + infix { + /* Default admin user password: 'admin' */ + factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"; + }; + }; +}; diff --git a/src/board/raspberry-pi-4/genimage.cfg.in b/src/board/raspberry-pi-4/genimage.cfg.in index ee7147d7..f78a2979 100644 --- a/src/board/raspberry-pi-4/genimage.cfg.in +++ b/src/board/raspberry-pi-4/genimage.cfg.in @@ -31,41 +31,41 @@ image var.ext4 { image #INFIX_ID##VERSION#-rpi4-sdcard.img { hdimage { - partition-table-type = "gpt" + partition-table-type = "hybrid" } partition boot { - partition-type-uuid = EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 + partition-type = 0xc bootable = "true" image = "boot.vfat" } partition aux { - partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035 + partition-type-uuid = srv image = "aux.ext4" } partition primary { - partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4 - bootable = true + partition-type-uuid = linux + bootable = "true" size = 250M image = "rootfs.squashfs" } partition secondary { - partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4 - bootable = true + partition-type-uuid = linux + bootable = "true" size = 250M image = "rootfs.squashfs" } partition cfg { - partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105 + partition-type-uuid = srv image = "cfg.ext4" } partition var { - partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F + partition-type-uuid = var image = "var.ext4" } } diff --git a/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,3-model-b b/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,3-model-b new file mode 120000 index 00000000..ef4c88cb --- /dev/null +++ b/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,3-model-b @@ -0,0 +1 @@ +raspberrypi,4-model-b \ No newline at end of file diff --git a/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg b/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg index 8ebc10a6..c744b02a 100644 --- a/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg +++ b/src/board/raspberry-pi-4/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg @@ -133,7 +133,7 @@ } }, "ietf-system:system": { - "hostname": "rpi4", + "hostname": "rpi", "ntp": { "enabled": true, "server": [ diff --git a/src/board/raspberry-pi-4/uboot/rpi-env.dtso b/src/board/raspberry-pi-4/uboot/rpi-env.dtso index 14b83c25..58fdd41c 100644 --- a/src/board/raspberry-pi-4/uboot/rpi-env.dtso +++ b/src/board/raspberry-pi-4/uboot/rpi-env.dtso @@ -17,7 +17,7 @@ stdin = "serial"; splashpos = "m,m"; splashfile = "splash.bmp"; - checkdisplay = "if testrpidisplay; then; setenv fdtfile broadcom/bcm2711-rpi-4-b-dsi.dtb; else; setenv fdtfile broadcom/bcm2711-rpi-4-b.dtb; fi"; + checkdisplay = "if testrpidisplay; then; setenv fdtfile broadcom/bcm2711-rpi-4-b-dsi.dtb; fi"; bootcmd = "fatload mmc 0:1 ${loadaddr} ${splashfile}; bmp display ${loadaddr}; run checkdisplay; run ixboot"; ixpreboot = /incbin/("scripts/ixpreboot.sh"); diff --git a/src/confd/src/ieee802-ethernet-interface.c b/src/confd/src/ieee802-ethernet-interface.c index 0dae3196..42d765a4 100644 --- a/src/confd/src/ieee802-ethernet-interface.c +++ b/src/confd/src/ieee802-ethernet-interface.c @@ -45,8 +45,19 @@ static int netdag_gen_ethtool_flow_control(struct dagger *net, struct lyd_node * if (!fp) return -EIO; fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supported-pause-frame-use\" == \"No\")') ]] && exit 0\n", ifname); - fprintf(fp, "ethtool --pause %s autoneg %s rx off tx off\n", - ifname, iface_uses_autoneg(cif) ? "on" : "off"); + + /* + * Some NICs report "supported-pause-frame-use": "Symmetric Receive-only", like + * RPi 3B's LAN78xx USB to Ethernet controller, but the drivers do not support + * disabling it. This call is best effort after all, so we capture and check + * the error. If the operation is not supported, we log it and exit cleanly. + */ + fprintf(fp, + "if ! err=$(ethtool --pause %s autoneg %s rx off tx off 2>&1); then\n" + " logger -it confd -p daemon.error \"%s: failed disabling flow-control\"\n" + " echo \"$err\" | grep -q \"Operation not supported\" && exit 0\n" + "fi\n", + ifname, iface_uses_autoneg(cif) ? "on" : "off", ifname); fclose(fp); return 0;