IPFire on Banana-Pi 4

Hey there you guys,

a couple of months ago, I wrote in this posting

that I’m trying to get IPFire up and running on a Banana-PI 4 (BPI-R4-Lite in my case).

Well, it took wayyy longer than I would have thought and I had some really intense and pretty inconsistent (therefore almost insane :zany_face:) conversations with multiple AI-entities over and over again but it’s finally done and it runs really smooth so far. :smiling_face_with_sunglasses:

Fortunately, I got my hands on a Thinkbook with a Snapdragon on loan, so compiling this stuff was no problem and now I wanted to share my experiences or rather give a tutorial to everyone who is interested.

I only tested it on BPI-R4-Lite but it should work on all devices of the 4th gen (normal, PoE, pro, lite, mini). So, lets go!

  1. IPFire-Image

First of all, you need a self-compiled IPFire (obviously).

I took the 7.0-Linux-Kernel from Frank Wunderlichs repo (GitHub - frank-w/BPI-Router-Linux: Linux kernel 4.14+ for BPI-R2, 5.4+ for R64, 6.1+ for R2Pro and R3, 6.12+ for R4, 6.17+ for R4Pro/R4Lite · GitHub), patched it, or rather merged it with the most recent one (7.0.12, because there is no 7.1-main yet) and compared his kernel-config to the one from IPFire.

I took the IPFire-config as a starting point, ignored every option that is missing in FWs and just checked additional or changed options.

Because IPFire is committed to security (and so am I), I did not want to just adopt every option from Frank but rather researched the meaning and effect of every one of the OVER 500 additional/changed OPTIONS (like I said, I’m committed! :sweat_smile:). I tried to change as little as possible but as much as necessary to make it work… and added some small things. :stuck_out_tongue:

I may have done a bit too much here and there and because IPFire uses ramdisk, I guess you could compile way more as module than I did, but after days and days full of contradictory arguments with the AI, I just lost my patience for streamlining. So I apologize that it is just pretty good and not perfect :wink: (of course, suggestions for improvements are wecome! :slight_smile:).

Here’s the diffconfig based on “kernel.config.aarch64-ipfire” (new entries with “=n” or “is not set” are omitted)

-ARCH_HAS_SUBPAGE_FAULTS y
-ARCH_SUPPORTS_SHADOW_CALL_STACK y
-ARCH_USES_PG_ARCH_2 y
-ARCH_USES_PG_ARCH_3 y
-ARM64_AS_HAS_MTE y
-ARM64_ERRATUM_4193714 y
-ARM64_LSE_ATOMICS y
-ARM64_MTE y
-ARM64_PAN y
-ARM64_USE_LSE_ATOMICS y
-AS_HAS_ARMV8_5 y
-AS_HAS_MOPS y
-BALLOON_COMPACTION y
-CC_HAS_BRANCH_PROT_PAC_RET y
-CC_HAS_BRANCH_PROT_PAC_RET_BTI y
-CC_HAVE_SHADOW_CALL_STACK y
-CC_HAVE_STACKPROTECTOR_SYSREG y
-CMDLINE_FROM_BOOTLOADER y
-CPUMASK_OFFSTACK y
-CRYPTO_AES_ARM64 m
-CRYPTO_AES_ARM64_CE m
-CRYPTO_ANSI_CPRNG m
-CRYPTO_LIB_POLY1305_GENERIC y
-CRYPTO_NHPOLY1305 m
-CRYPTO_NHPOLY1305_NEON m
-CRYPTO_POLYVAL m
-CRYPTO_POLYVAL_ARM64_CE m
-CRYPTO_SHA3_ARM64 m
-DNET m
-DRM_ST7571_I2C m
-FB_MODE_HELPERS y
-GCC_PLUGINS y
-HAVE_ARCH_KASAN_HW_TAGS y
-KVM_GENERIC_MMU_NOTIFIER y
-MEMORY_BALLOON y
-MFD_WL1273_CORE m
-NETFILTER_XT_MATCH_LAYER7 m
-NET_VENDOR_NETERION y
-NFS_V4_1 y
-PARTITION_PERCPU y
-PREEMPT_VOLUNTARY y
-RUSTC_HAS_COERCE_POINTEE y
-RUSTC_HAS_FILE_AS_C_STR y
-RUSTC_HAS_FILE_WITH_NUL y
-RUSTC_HAS_SPAN_FILE y
-RUSTC_HAS_UNNECESSARY_TRANSMUTES y
-S2IO m
-SERIAL_8250_DEPRECATED_OPTIONS y
-SHADOW_CALL_STACK y
-SLUB_CPU_PARTIAL y
-STACKPROTECTOR_PER_TASK y
-TCP_SIGPOOL y
 ARCH_MEDIATEK n -> y
 BLK_DEV_NVME m -> y
 CMDLINE "console=ttyAM0,115200 root=/dev/sda1 rootdelay=20" -> ""
 CPU_FREQ_DEFAULT_GOV_PERFORMANCE y -> n
 CPU_FREQ_DEFAULT_GOV_SCHEDUTIL n -> y
 CRYPTO_DH m -> y
 CRYPTO_HKDF m -> y
 CRYPTO_KPP m -> y
 DEVFREQ_GOV_PASSIVE n -> y
 EEPROM_AT24 m -> y
 EXTRA_FIRMWARE "" -> "aeonsemi/as21x1x_fw.bin mediatek/mt7987/i2p5ge-phy-DSPBitTb.bin mediatek/mt7987/i2p5ge-phy-pmb.bin"
 F2FS_FS n -> y
 FAT_FS m -> y
 FSL_DPAA2_SWITCH y -> m
 GARP m -> y
 GPIO_PCA953X m -> y
 HSR m -> y
 I2C_MUX_PCA954x m -> y
 IKCONFIG n -> y
 IRQ_TIME_ACCOUNTING n -> y
 LZ4HC_COMPRESS m -> y
 LZ4_COMPRESS m -> y
 LZO_COMPRESS m -> y
 MAXLINEAR_GPHY m -> y
 MDIO_I2C m -> y
 MEDIATEK_GE_PHY m -> y
 MEDIATEK_GE_SOC_PHY n -> y
 MMC_BLOCK m -> y
 MMC_CQHCI m -> y
 MMC_HSQ n -> y
 MMC_MTK n -> y
 MTK_NET_PHYLIB m -> y
 NET_DSA m -> y
 NET_DSA_MT7530 m -> y
 NET_DSA_MT7530_MDIO m -> y
 NET_DSA_MT7530_MMIO m -> y
 NET_DSA_TAG_MTK m -> y
 NF_TABLES_INET n -> y
 NF_TABLES_NETDEV n -> y
 NR_CPUS 512 -> 4
 NVME_AUTH m -> y
 NVME_CORE m -> y
 NVME_KEYRING m -> y
 PCIEASPM_DEFAULT y -> n
 PCIEASPM_PERFORMANCE n -> y
 PCS_MTK_LYNXI m -> y
 PHY_PACKAGE m -> y
 POLYNOMIAL m -> y
 POWER_RESET_SYSCON n -> y
 POWER_RESET_SYSCON_POWEROFF n -> y
 POWER_SEQUENCING n -> m
 PREEMPT n -> y
 PRINTK_TIME n -> y
 PSTORE_RAM n -> y
 REGULATOR_RT5190A n -> y
 RESET_GPIO m -> y
 RPMB m -> y
 RTC_DRV_PCF8563 m -> y
 SENSORS_PWM_FAN n -> y
 SERIAL_8250_NR_UARTS 4 -> 3
 SERIAL_8250_RUNTIME_UARTS 4 -> 3
 SERIAL_DEV_BUS n -> y
 SFP m -> y
 SPI n -> y
 UBIFS_FS n -> m
 VFAT_FS m -> y
 VLAN_8021Q m -> y
 VLAN_8021Q_MVRP n -> y
 WATCHDOG_SYSFS n -> y
 WWAN n -> m
 ZSTD_COMPRESS m -> y
+ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION y
+ARCH_HAS_LAZY_MMU_MODE y
+ARM64_ERRATUM_4311569 y
+ARM_MEDIATEK_CCI_DEVFREQ y
+ARM_MEDIATEK_CPUFREQ y
+ARM_MEDIATEK_CPUFREQ_HW y
+AS21XXX_PHY_DS y
+BALLOON y
+BALLOON_MIGRATION y
+BROKEN_GAS_INST y
+CLK_RV1126B y
+CMDLINE_LOG_WRAP_IDEAL_LEN 1021
+COMMON_CLK_MEDIATEK y
+COMMON_CLK_MEDIATEK_FHCTL y
+COMMON_CLK_MT2712 y
+COMMON_CLK_MT6765 y
+COMMON_CLK_MT6779 y
+COMMON_CLK_MT6795 y
+COMMON_CLK_MT6795_MFGCFG y
+COMMON_CLK_MT6795_MMSYS y
+COMMON_CLK_MT6795_VDECSYS y
+COMMON_CLK_MT6795_VENCSYS y
+COMMON_CLK_MT6797 y
+COMMON_CLK_MT7622 y
+COMMON_CLK_MT7981 y
+COMMON_CLK_MT7981_ETHSYS y
+COMMON_CLK_MT7986 y
+COMMON_CLK_MT7986_ETHSYS y
+COMMON_CLK_MT7987 y
+COMMON_CLK_MT7987_ETHSYS y
+COMMON_CLK_MT7988 y
+COMMON_CLK_MT8167 y
+COMMON_CLK_MT8167_AUDSYS y
+COMMON_CLK_MT8167_IMGSYS y
+COMMON_CLK_MT8167_MFGCFG y
+COMMON_CLK_MT8167_MMSYS y
+COMMON_CLK_MT8167_VDECSYS y
+COMMON_CLK_MT8173 y
+COMMON_CLK_MT8173_IMGSYS y
+COMMON_CLK_MT8173_MMSYS y
+COMMON_CLK_MT8173_VDECSYS y
+COMMON_CLK_MT8173_VENCSYS y
+COMMON_CLK_MT8183 y
+COMMON_CLK_MT8183_AUDIOSYS y
+COMMON_CLK_MT8183_CAMSYS y
+COMMON_CLK_MT8183_IMGSYS y
+COMMON_CLK_MT8183_IPU_ADL y
+COMMON_CLK_MT8183_IPU_CONN y
+COMMON_CLK_MT8183_IPU_CORE0 y
+COMMON_CLK_MT8183_IPU_CORE1 y
+COMMON_CLK_MT8183_MFGCFG y
+COMMON_CLK_MT8183_MMSYS y
+COMMON_CLK_MT8183_VDECSYS y
+COMMON_CLK_MT8183_VENCSYS y
+COMMON_CLK_MT8186 y
+COMMON_CLK_MT8186_CAMSYS y
+COMMON_CLK_MT8186_IMGSYS y
+COMMON_CLK_MT8186_IMP_IIC_WRAP y
+COMMON_CLK_MT8186_IPESYS y
+COMMON_CLK_MT8186_MCUSYS y
+COMMON_CLK_MT8186_MDPSYS y
+COMMON_CLK_MT8186_MFGCFG y
+COMMON_CLK_MT8186_MMSYS y
+COMMON_CLK_MT8186_VDECSYS y
+COMMON_CLK_MT8186_VENCSYS y
+COMMON_CLK_MT8186_WPESYS y
+COMMON_CLK_MT8188 y
+COMMON_CLK_MT8188_ADSP_AUDIO26M y
+COMMON_CLK_MT8188_CAMSYS y
+COMMON_CLK_MT8188_IMGSYS y
+COMMON_CLK_MT8188_IMP_IIC_WRAP y
+COMMON_CLK_MT8188_IPESYS y
+COMMON_CLK_MT8188_MFGCFG y
+COMMON_CLK_MT8188_VDECSYS y
+COMMON_CLK_MT8188_VDOSYS y
+COMMON_CLK_MT8188_VENCSYS y
+COMMON_CLK_MT8188_VPPSYS y
+COMMON_CLK_MT8188_WPESYS y
+COMMON_CLK_MT8192 y
+COMMON_CLK_MT8192_AUDSYS y
+COMMON_CLK_MT8192_CAMSYS y
+COMMON_CLK_MT8192_IMGSYS y
+COMMON_CLK_MT8192_IMP_IIC_WRAP y
+COMMON_CLK_MT8192_IPESYS y
+COMMON_CLK_MT8192_MDPSYS y
+COMMON_CLK_MT8192_MFGCFG y
+COMMON_CLK_MT8192_MMSYS y
+COMMON_CLK_MT8192_MSDC y
+COMMON_CLK_MT8192_SCP_ADSP y
+COMMON_CLK_MT8192_VDECSYS y
+COMMON_CLK_MT8192_VENCSYS y
+COMMON_CLK_MT8195 y
+COMMON_CLK_MT8195_APUSYS y
+COMMON_CLK_MT8195_CAMSYS y
+COMMON_CLK_MT8195_IMGSYS y
+COMMON_CLK_MT8195_IMP_IIC_WRAP y
+COMMON_CLK_MT8195_IPESYS y
+COMMON_CLK_MT8195_MFGCFG y
+COMMON_CLK_MT8195_SCP_ADSP y
+COMMON_CLK_MT8195_VDECSYS y
+COMMON_CLK_MT8195_VDOSYS y
+COMMON_CLK_MT8195_VENCSYS y
+COMMON_CLK_MT8195_VPPSYS y
+COMMON_CLK_MT8195_WPESYS y
+COMMON_CLK_MT8196 y
+COMMON_CLK_MT8196_IMP_IIC_WRAP y
+COMMON_CLK_MT8196_MCUSYS y
+COMMON_CLK_MT8196_MDPSYS y
+COMMON_CLK_MT8196_MFGCFG m
+COMMON_CLK_MT8196_MMSYS m
+COMMON_CLK_MT8196_PEXTPSYS y
+COMMON_CLK_MT8196_UFSSYS y
+COMMON_CLK_MT8196_VDECSYS m
+COMMON_CLK_MT8196_VENCSYS m
+COMMON_CLK_MT8365 y
+COMMON_CLK_MT8365_APU y
+COMMON_CLK_MT8365_CAM y
+COMMON_CLK_MT8365_MFG y
+COMMON_CLK_MT8365_MMSYS y
+COMMON_CLK_MT8365_VDEC y
+COMMON_CLK_MT8365_VENC y
+COMMON_CLK_MT8516 y
+COMMON_CLK_T7_PERIPHERALS y
+COMMON_CLK_T7_PLL y
+CRYPTO_LIB_AES_ARCH y
+CRYPTO_LIB_BLAKE2B m
+CRYPTO_LIB_POLYVAL m
+CRYPTO_LIB_POLYVAL_ARCH y
+CRYPTO_LIB_SHA3 y
+CRYPTO_LIB_SHA3_ARCH y
+DRM_IMX8MP_HDMI_PAI m
+DRM_INNO_HDMI m
+DRM_MIPI_DBI m
+DRM_PANEL_SAMSUNG_S6E63M0_SPI m
+EINT_MTK y
+EXTRA_FIRMWARE_DIR "utils/firmware/"
+F2FS_FS_COMPRESSION y
+F2FS_FS_LZ4 y
+F2FS_FS_LZ4HC y
+F2FS_FS_LZO y
+F2FS_FS_LZORLE y
+F2FS_FS_POSIX_ACL y
+F2FS_FS_SECURITY y
+F2FS_FS_XATTR y
+F2FS_FS_ZSTD y
+F2FS_IOSTAT y
+F2FS_STAT_FS y
+FWNODE_PCS y
+GENERIC_CPU_CACHE_MAINTENANCE y
+HAVE_SCHED_AVG_IRQ y
+HW_RANDOM_MTK y
+I2C_MT65XX y
+I3C_OR_I2C y
+IOSM m
+IO_URING_BPF y
+LIBETH_XDP m
+LOGO_LINUX_CLUT224_FILE "drivers/video/logo/logo_linux_clut224.ppm"
+MEDIATEK_2P5GE_PHY y
+MEDIATEK_WATCHDOG y
+MHI_WWAN_CTRL m
+MHI_WWAN_MBIM m
+MRP y
+MST_IRQ y
+MT7622_WMAC y
+MTD_NAND_ECC_MEDIATEK y
+MTD_SPI_NAND y
+MTD_SPI_NOR y
+MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE y
+MTD_SPI_NOR_USE_4K_SECTORS y
+MTK_CPUX_TIMER y
+MTK_CQDMA y
+MTK_GPUEB_MBOX y
+MTK_HSDMA y
+MTK_INFRACFG y
+MTK_LVTS_THERMAL y
+MTK_MFG_PM_DOMAIN y
+MTK_MMSYS y
+MTK_PMIC_WRAP y
+MTK_REGULATOR_COUPLER y
+MTK_SCPSYS y
+MTK_SCPSYS_PM_DOMAINS y
+MTK_SOCINFO y
+MTK_SOC_THERMAL y
+MTK_T7XX m
+MTK_THERMAL y
+MTK_TIMER y
+MTK_UART_APDMA y
+NET_DSA_LANTIQ_COMMON m
+NET_DSA_MXL862 y
+NET_DSA_TAG_MXL_862XX y
+NET_DSA_TAG_MXL_862XX_8021Q y
+NET_MEDIATEK_SOC y
+NET_MEDIATEK_SOC_WED y
+NET_VENDOR_ADI y
+NET_VENDOR_MEDIATEK y
+NET_VENDOR_MUCSE y
+NFS_V4_0 y
+NFT_REJECT_INET m
+NVMEM_MTK_EFUSE y
+OPENSSL_SUPPORTS_ML_DSA y
+PCIE_MEDIATEK y
+PCIE_MEDIATEK_GEN3 y
+PCS_MTK_USXGMII y
+PHY_COMMON_PROPS y
+PHY_MTK_TPHY y
+PHY_MTK_XFI_TPHY y
+PHY_MTK_XSPHY y
+PINCTRL_MT2712 y
+PINCTRL_MT6765 y
+PINCTRL_MT6779 y
+PINCTRL_MT6795 y
+PINCTRL_MT6797 y
+PINCTRL_MT6878 y
+PINCTRL_MT6893 y
+PINCTRL_MT7622 y
+PINCTRL_MT7981 y
+PINCTRL_MT7986 y
+PINCTRL_MT7987 y
+PINCTRL_MT7988 y
+PINCTRL_MT8167 y
+PINCTRL_MT8173 y
+PINCTRL_MT8183 y
+PINCTRL_MT8186 y
+PINCTRL_MT8188 y
+PINCTRL_MT8189 y
+PINCTRL_MT8192 y
+PINCTRL_MT8195 y
+PINCTRL_MT8196 y
+PINCTRL_MT8365 y
+PINCTRL_MT8516 y
+PINCTRL_MTK y
+PINCTRL_MTK_MOORE y
+PINCTRL_MTK_PARIS y
+PINCTRL_MTK_V2 y
+PRINTK_EXECUTION_CTX y
+PT_RECLAIM y
+PWM_MEDIATEK y
+REED_SOLOMON y
+REED_SOLOMON_DEC8 y
+REED_SOLOMON_ENC8 y
+REGMAP_SPI m
+REGULATOR_MT6380 y
+SERIAL_8250_MT6577 y
+SERIAL_DEV_CTRL_TTYPORT y
+SND_SOC_ES8328_SPI m
+SND_SPI y
+SPI_DYNAMIC y
+SPI_MASTER y
+SPI_MEM y
+SPI_MT65XX y
+SPI_MTK_NOR y
+SPI_MTK_SNFI y
+UBIFS_FS_LZO y
+UBIFS_FS_SECURITY y
+UBIFS_FS_XATTR y
+UBIFS_FS_ZLIB y
+UBIFS_FS_ZSTD y
+USB_XHCI_MTK y
+V4L2_ISP m

Please keep in mind that my final config is for kernel 7.0.12 and IPFire-config is 6.18, so some of the new/changed options may come from the more recent kernel and have nothing to do with the :banana:. Also there are way more options in this diffconfig than I altered (I only altered about 230 but with all the dependencies and auto-selects it just grew to about 800… this list is about 380 because, like I said, I ommitted non-functional ones… also this is NOT the full config file, ONLY the diffconfig!) I also updated linux-firmware and strace.

For further information regarding compiling your own IPFire, check the very good tutorial on the website. :slight_smile:

  1. U-Boot

Download U-Boot for you specific bpi-board (Releases · frank-w/u-boot · GitHub) and flash it on your SD-card (or eMMC or NVME or whatever).

Delete partitions 5 and 6 and create new ones (this is for SD-Card and might be different, depending on what device you use).

Partition 5 (/dev/mmcmblk0p5):
Filesystem: fat32 (instead of fat16)
Name: “boot”
Description: “BPI-BOOT”
Size: 500 MiB (instead of 100 MiB)

Partition 6 (/dev/mmcmblk0p6):
Filesystem f2fs (instead of ext4)
Name: “rootfs”
Description: “BPI-ROOT”
Size: as you wish

(The attentive reader may have noticed that I activated f2fs in the kernel, escpecially for the SD-Cards)

Then mount your self-compiled IPFire-Image and copy the partitions (or rather their content) to the equivalents on the SD-card.

sudo cp -a "boot-partition"/. BPI-BOOT/
sudo cp -a "root-partition"/. BPI-ROOT/

Use the “-a” parameter to preserve the attributes and simlinks, etc. Depending on your SD-card, this may take some time. Be patient and use

watch -n 1 "grep -E 'Dirty|Writeback' /proc/meminfo"

to check when the RAM is empty and all files are copied.

  1. Modifying files

Because U-Boot wants to use ext4 by default, we have to modify uEnv.txt (you find this file on the “BPI-BOOT”-partition in the main-folder). The new content should be

root=/dev/mmcblk0p6 rootfstype=f2fs rootwait
console=ttyS0,115200 earlycon panic=10 rd.shell

We also need to modify fstab to find the correct partitions, go easy on the SD-card, use compression and get rid of dump (you find this file on the “BPI-ROOT”-partition in the “/etc/”-folder). The new content should be

/dev/mmcblk0p5 /boot vfat defaults,nodev,noexec,nosuid,noatime,lazytime 0 2
/dev/mmcblk0p6 / f2fs defaults,noatime,lazytime,compress_algorithm=zstd,compress_chksum 0 1

Finally, because the BPI-boards use dynamic MAC-adresses, we have to “fix” them. Therefor we create a little script for udev (this file goes on the “BPI-ROOT”-partition in the “/etc/rc.d/rcsysinit.d/”-folder and we call it “S84macs”). Of course, you need to alter this one depending on your board (and of course, don’t forget chmod)!

sleep 1
ip link set dev eth0 down
ip link set dev eth1 down
ip link set dev lan0 down
ip link set dev lan1 down
ip link set dev lan2 down
ip link set dev lan3 down
ip link set dev sfp0 down
ip link set dev wlan0 down
sleep 1
ip link set dev eth0 address "new mac adress"
ip link set dev eth1 address "new mac adress"
ip link set dev lan0 address "new mac adress"
ip link set dev lan1 address "new mac adress"
ip link set dev lan2 address "new mac adress"
ip link set dev lan3 address "new mac adress"
ip link set dev sfp0 address "new mac adress"
ip link set dev wlan0 address "new mac adress"
sleep 1
ip link set dev eth0 name green
ip link set dev eth1 name green0
ip link set dev lan0 name red0
ip link set dev lan1 name green1
ip link set dev lan2 name green2
ip link set dev lan3 name green3
ip link set dev sfp0 name red1
ip link set dev wlan0 name blue0
sleep 1
ip link set dev green up
ip link set dev green0 up
ip link set dev red0 up
ip link set dev green1 up
ip link set dev green2 up
ip link set dev green3 up
ip link set dev red1 up
ip link set dev blue0 up
sleep 1

You could lose the “sleepies” but I like them. :slight_smile: At the first boot-up, this may not work completely because there could be some “dummy”-named interfaces, but from the second boot on everything works just fine… don’t forget to reconfigure your zones with “setup” after that.

  1. FIT-Image

To boot completely automatic, we need to build a FIT-Image. (I tried it with modifying uEnv.txt and fiddling around but it just would not work, so I chose this way… maybe you guys can find a solution).

For the image we need to copy some files and create some new ones and put them all in one folder. First go back to the boot-partition of your IPFire-Image and copy these files

initramfs-7.0.12-ipfire.img (the ramdisk, it is in the main-folder)
vmlinuz-7.0.12-ipfire (the kernel, also in the main-folder)
mt7987a-bananapi-bpi-r4-lite-sd-nand-1pci2lane.dtb (device-tree-blob for the bpi-board… of course yours may differ, it’s in the “/dtb…”-subfolder)

then you need to create some new files.

ov-sd.dts (dummy-file because the boot-conf is kind of hardcoded), the content should be:

/dts-v1/;
/plugin/;
/ {
};

bpi-r4.its (configuration file for FIT-Image), the content should be (of course, check and adjust the correct file-names):

/dts-v1/;

/ {
	description = "U-Boot fitImage for IPFire-BPI-R4";
	#address-cells = <1>;

images {

		kernel {
			description = "Linux Kernel";
			data = /incbin/("vmlinuz-7.0.12-ipfire");
			type = "kernel";
			arch = "arm64";
			os = "linux";
			compression = "none";
			load = <0x4C000000>;
			entry = <0x4C000000>;
			hash-1 {
				algo = "sha256";
			};
		};

		fdt-base {
			description = "BPI-R4-Lite";
			data = /incbin/("mt7987a-bananapi-bpi-r4-lite-sd-nand-1pci2lane.dtb");
			type = "flat_dt";
			arch = "arm64";
			// load = <0x4F000000>;
			compression = "none";
			hash-1 {
				algo = "sha256";
			};
		};

		fdt-ov-sd {
			description = "fdt-ov-sd";
			data = /incbin/("ov-sd.dtbo");
			type = "flat_dt";
		};

		ramdisk {
			description = "Initial RAM Filesystem";
			data = /incbin/("initramfs-7.0.12-ipfire.img");
			type = "ramdisk";
			arch = "arm64";
			os = "linux";
			// load = <0x50000000>;
			compression = "none";
			hash-1 {
				algo = "sha256";
			};
		};

	};

	configurations {
		default = "conf-base";

		conf-base {
			description = "Boot IPFire on BPI-R4";
			kernel = "kernel";
			fdt = "fdt-base", "fdt-ov-sd";
			ramdisk = "ramdisk";
			hash-1 {
				algo = "sha256";
			};
		};

		ov-sd {
			description = "ov-sd";
			fdt = "fdt-ov-sd";
		};  

	};

};

Create an own device-tree-blob for the dummy-file using

dtc -@ -I dts -O dtb -o ov-sd.dtbo ov-sd.dts

and then create your own FIT-Image

mkimage -f bpi-r4.its bpi-r4.itb

Put that FIT-Image in the main-folder of the BOOT-Partition.

  1. Enjoy IPFire on a BPI-R4

I know this is a long posting but I put a lot of work into that and hope that it may help some of you. I also hope that I did not forget anything.

Any suggestions for improvement (streamlining the kernel-config or modyfing uEnv.txt differently to get rid of the FIT-Image) are welcome.

Have a nice day! :slight_smile:

Greetings

Alex

Kudos on this excellent guide! The technical documentation is extremely detailed, precise, and logically structured.

To further optimize the project and maximize accessibility, it would be highly strategic to provide a pre-configured system image (IMG/ISO ready to flash) alongside the manual steps.

This addition wouldn’t diminish the value of the written guide, which remains essential for troubleshooting and custom configurations. Instead, it directly addresses the practical needs of specific user segments: less experienced users who might encounter configuration errors during the process, and power users looking for a rapid deployment without having to manually replicate the entire installation pipeline."