summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Marko2026-02-23 16:41:18 +0000
committerRobert Marko2026-05-28 09:19:50 +0000
commitfbf01b4d62db5bcb8a72be1205d9f50dcd600d2b (patch)
treeea1ac030afc58a957be828e0fe61ad8724178034
parent526efddf7bbae26e63a882d78565a1ef9897fb3a (diff)
downloadopenwrt-fbf01b4d62db5bcb8a72be1205d9f50dcd600d2b.tar.gz
mvebu: cortexa53: uDPU/eDPU convert to dual firmware (A/B)
Methode uDPU and eDPU devices are one of the rare ones with a completely custom image format being used with custom partition table with F2FS. Instead of converting the boards to dual firmware (A/B style) and further expand the already convoluted custom scripts, especially considering that dual firmware conversion is a breaking change anyway, lets convert to using the generic eMMC sysupgrade based images. F2FS ZSTD compression is preserved thanks to fstools now supporting its use on overlays. Dual firmware support is implemented via U-Boot scripts so no U-Boot upgrade is required. Since there is a partition table layout change, eMMC must be wiped and reflashed with the generated GPT image from OpenWrt initramfs. Then on each sysupgrade the firmware slot will be altered. Instructions: 1. Boot into OpenWrt initramfs 2. Copy openwrt-mvebu-cortexa53-methode_edpu-squashfs-emmc-gpt.img.gz to the device into /tmp 3. Erase eMMC: dd if=/dev/zero of=/dev/mmcblk0 bs=1M 4. Extract image gzip -d /tmp/openwrt-mvebu-cortexa53-methode_edpu-squashfs-emmc-gpt.img.gz 5. Flash image dd if=/tmp/openwrt-mvebu-cortexa53-methode_edpu-squashfs-emmc-gpt.img of=/dev/mmcblk0 6. Reboot Signed-off-by: Robert Marko <robert.marko@sartura.hr> (cherry picked from commit ada2753d6a315b7ff75604342ef69d55b3b418ae)
-rw-r--r--target/linux/mvebu/cortexa53/base-files/etc/board.d/05_compat_version15
-rwxr-xr-xtarget/linux/mvebu/cortexa53/base-files/etc/init.d/bootcount12
-rw-r--r--target/linux/mvebu/cortexa53/base-files/lib/preinit/82_uDPU49
-rwxr-xr-xtarget/linux/mvebu/cortexa53/base-files/lib/upgrade/platform.sh34
-rw-r--r--target/linux/mvebu/cortexa53/base-files/lib/upgrade/uDPU.sh162
-rw-r--r--target/linux/mvebu/cortexa53/target.mk2
-rw-r--r--target/linux/mvebu/image/Makefile13
-rw-r--r--target/linux/mvebu/image/cortexa53.mk43
-rw-r--r--target/linux/mvebu/image/udpu.bootscript61
9 files changed, 146 insertions, 245 deletions
diff --git a/target/linux/mvebu/cortexa53/base-files/etc/board.d/05_compat_version b/target/linux/mvebu/cortexa53/base-files/etc/board.d/05_compat_version
new file mode 100644
index 0000000000..5a8f31e6a7
--- /dev/null
+++ b/target/linux/mvebu/cortexa53/base-files/etc/board.d/05_compat_version
@@ -0,0 +1,15 @@
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+case "$(board_name)" in
+ methode,udpu|\
+ methode,edpu)
+ ucidef_set_compat_version "2.0"
+ ;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/mvebu/cortexa53/base-files/etc/init.d/bootcount b/target/linux/mvebu/cortexa53/base-files/etc/init.d/bootcount
new file mode 100755
index 0000000000..6ebf8eddf6
--- /dev/null
+++ b/target/linux/mvebu/cortexa53/base-files/etc/init.d/bootcount
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+boot() {
+ case $(board_name) in
+ methode,udpu|\
+ methode,edpu)
+ fw_setenv bootcount 0
+ ;;
+ esac
+}
diff --git a/target/linux/mvebu/cortexa53/base-files/lib/preinit/82_uDPU b/target/linux/mvebu/cortexa53/base-files/lib/preinit/82_uDPU
deleted file mode 100644
index 1c72d0fe66..0000000000
--- a/target/linux/mvebu/cortexa53/base-files/lib/preinit/82_uDPU
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# Copyright (C) 2014-2019 OpenWrt.org
-# Copyright (C) 2016 LEDE-Project.org
-#
-
-preinit_mount_udpu() {
- . /lib/functions.sh
- . /lib/upgrade/common.sh
-
- case $(board_name) in
- methode,udpu|\
- methode,edpu)
- # Check which device is detected
- [ -b "/dev/mmcblk0" ] && mmcdev="/dev/mmcblk0" || mmcdev="/dev/mmcblk1"
-
- if [ -b "${mmcdev}p4" ]; then
- mkdir /misc
- mount -o compress_algorithm=zstd -t f2fs ${mmcdev}p4 /misc
- [ -f "/misc/$BACKUP_FILE" ] && {
- echo "- Restoring configuration files -"
- tar xzf "/misc/$BACKUP_FILE" -C /
- rm -f "/misc/$BACKUP_FILE"
- sync
- }
- [ -f "/misc/firmware/recovery.itb" ] && {
- echo "- Updating /recovery partition -"
- mkfs.ext4 -q ${mmcdev}p2 | echo y &> /dev/null
- mkdir -p /tmp/recovery
- mount ${mmcdev}p2 /tmp/recovery
- cp /misc/firmware/recovery.itb /tmp/recovery
- [ -f "/misc/firmware/boot.scr" ] && \
- cp /misc/firmware/boot.scr /tmp/recovery
- sync
- umount /tmp/recovery
- rm -rf /tmp/recovery
-
- # Replace previous backup with the new one
- [ -d "/misc/firmware_old" ] && rm -rf /misc/firmware_old
- [ -d "/misc/firmware" ] && mv /misc/firmware /misc/firmware_old
- }
- fi
-
- # Legacy support - if rootfs was booted, instruct u-boot to keep the current root dev
- [ "$(df | grep /dev/root)" ] && fw_setenv root_ok '2'
- ;;
- esac
-}
-
-boot_hook_add preinit_main preinit_mount_udpu
diff --git a/target/linux/mvebu/cortexa53/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa53/base-files/lib/upgrade/platform.sh
index f77f15ecab..7ddb516762 100755
--- a/target/linux/mvebu/cortexa53/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mvebu/cortexa53/base-files/lib/upgrade/platform.sh
@@ -35,7 +35,37 @@ platform_do_upgrade() {
;;
methode,udpu|\
methode,edpu)
- platform_do_upgrade_uDPU "$1"
+ [ "$(rootfs_type)" = "tmpfs" ] && {
+ local firmware_active="$(fw_printenv -n bootactive)"
+ case "$firmware_active" in
+ 1)
+ CI_KERNPART="kernel_2"
+ CI_ROOTPART="rootfs_2"
+ fw_setenv bootactive 2
+ ;;
+ 2)
+ CI_KERNPART="kernel_1"
+ CI_ROOTPART="rootfs_1"
+ fw_setenv bootactive 1
+ ;;
+ esac
+ }
+
+ local root="$(cmdline_get_var root)"
+ case "$root" in
+ /dev/mmcblk*p2)
+ CI_KERNPART="kernel_2"
+ CI_ROOTPART="rootfs_2"
+ fw_setenv bootactive 2
+ ;;
+ /dev/mmcblk*p4)
+ CI_KERNPART="kernel_1"
+ CI_ROOTPART="rootfs_1"
+ fw_setenv bootactive 1
+ ;;
+ esac
+
+ emmc_do_upgrade "$1"
;;
*)
default_do_upgrade "$1"
@@ -54,7 +84,7 @@ platform_copy_config() {
;;
methode,udpu|\
methode,edpu)
- platform_copy_config_uDPU
+ emmc_copy_config
;;
esac
}
diff --git a/target/linux/mvebu/cortexa53/base-files/lib/upgrade/uDPU.sh b/target/linux/mvebu/cortexa53/base-files/lib/upgrade/uDPU.sh
deleted file mode 100644
index a8d803ff59..0000000000
--- a/target/linux/mvebu/cortexa53/base-files/lib/upgrade/uDPU.sh
+++ /dev/null
@@ -1,162 +0,0 @@
-udpu_check_emmc() {
-# uDPU uses combined ext4 and f2fs partitions.
-# partition layout:
-# 1. boot (ext4)
-# 2. recovery (ext4)
-# 3. rootfs (f2fs)
-# 4. misc (f2fs)
-
- # Check which device is available, depending on the board revision
- if [ -b "/dev/mmcblk1" ]; then
- emmc_dev=/dev/mmcblk1
- elif [ -b "/dev/mmcblk0" ]; then
- emmc_dev=/dev/mmcblk0
- else
- echo "Cannot detect eMMC flash, aborting.."
- exit 1
- fi
-}
-
-udpu_part_prep() {
- if grep -q "$1" /proc/mounts; then
- mounted_part="$(grep -m 1 $1 /proc/mounts | awk '{print $2}')"
- umount "$mounted_part"
- grep -woq "$mounted_part" /proc/mounts && umount -l "$mounted_part"
- fi
-}
-
-udpu_do_part_check() {
- local emmc_parts="1 2 3 4"
- local part_valid="1"
-
- # Check if the block devices exist
- for num in ${emmc_parts}; do
- [ ! -b ${emmc_dev}p${num} ] && part_valid="0"
- done
-
- # If partitions are missing create a new partition table
- if [ "$part_valid" != "1" ]; then
- printf "Invalid partition table, creating a new one\n"
- printf "o\nn\np\n1\n\n+256M\nn\np\n2\n\n+256M\nn\np\n3\n\n+1536M\nn\np\n\n\nw\n" | fdisk -W always $emmc_dev > /dev/null 2>&1
-
- # Format the /misc part right away as we will need it for the firmware
- printf "Formating /misc partition, this make take a while..\n"
- udpu_part_prep ${emmc_dev}p4
- if mkfs.f2fs -q -l misc -O extra_attr,compression ${emmc_dev}p4; then
- printf "/misc partition formated successfully\n"
- else
- printf "/misc partition formatting failed\n"
- fi
-
- udpu_do_initial_setup
- else
- printf "Partition table looks ok\n"
- fi
-}
-
-udpu_do_misc_prep() {
- if ! grep -woq /misc /proc/mounts; then
- mkdir -p /misc
-
- # If the mount fails, try to reformat partition
- # Leaving possiblity for multiple iterations
- if ! mount ${emmc_dev}p4 /misc; then
- printf "Error while mounting /misc, trying to reformat..\n"
-
- format_count=0
- while [ "$format_count" -lt "1" ]; do
- udpu_part_prep ${emmc_dev}p4
- mkfs.f2fs -q -l misc -O extra_attr,compression ${emmc_dev}p4
- if ! mount ${emmc_dev}p4 /misc; then
- umount -l /misc
- printf "Failed while mounting /misc\n"
- format_count=$((format_count +1))
- else
- printf "Mounted /misc successfully\n"
- break
- fi
- done
- fi
- fi
-}
-
-udpu_do_initial_setup() {
- # Prepare /recovery parition
- udpu_part_prep ${emmc_dev}p2
- mkfs.ext4 -qF ${emmc_dev}p2 2>&1 /dev/null
-
- # Prepare /boot partition
- udpu_part_prep ${emmc_dev}p1
- mkfs.ext4 -qF ${emmc_dev}p1 2>&1 /dev/null
-
- # Prepare /root partition
- printf "Formating /root partition, this may take a while..\n"
- udpu_part_prep ${emmc_dev}p3
- mkfs.f2fs -q -l rootfs -O extra_attr,compression ${emmc_dev}p3 && printf "/root partition reformated\n"
-}
-
-udpu_do_regular_upgrade() {
- # Clean /boot partition - mfks.ext4 is not available in chroot
- grep -woq /boot /proc/mounts && umount /boot
- mkdir -p /tmp/boot
- mount ${emmc_dev}p1 /tmp/boot
- rm -rf /tmp/boot/*
-
- # Clean /root partition - mkfs.f2fs is not available in chroot
- grep -woq /dev/root /proc/mounts && umount /
- mkdir -p /tmp/rootpart
- mount ${emmc_dev}p3 /tmp/rootpart
- rm -rf /tmp/rootpart/*
-}
-
-platform_do_upgrade_uDPU() {
- udpu_check_emmc
-
- # Prepare and extract firmware on /misc partition
- udpu_do_misc_prep
-
- [ -f "/misc/firmware" ] && rm -r /misc/firmware
- mkdir -p /misc/firmware
- tar xzf "$1" -C /misc/firmware/
-
- udpu_do_regular_upgrade
-
- printf "Updating /boot partition\n"
- if tar xzf /misc/firmware/boot.tgz -C /tmp/boot; then
- printf "/boot partition updated successfully\n"
- else
- printf "/boot partition update failed\n"
- fi
- sync
-
- printf "Updating /root partition\n"
- if tar xzf /misc/firmware/rootfs.tgz -C /tmp/rootpart; then
- printf "/root partition updated successfully\n"
- else
- printf "/root partition update failed\n"
- fi
- sync
-
- # Saving configuration files over sysupgrade
- platform_copy_config_uDPU
-
- # Remove tmp mounts
- tmp_parts=$(grep "${emmc_dev}" /proc/mounts | awk '{print $2}')
- for part in ${tmp_parts}; do
- umount "$part"
- # Force umount is necessary
- grep -q "${part}" /proc/mounts && umount -l "$part"
- done
-
- # Sysupgrade complains about /tmp and /dev, so we can detach them here
- umount -l /tmp
- umount -l /dev
-}
-
-platform_copy_config_uDPU() {
- # Config is saved on the /misc partition and copied on the rootfs after the reboot
- if [ -f "$UPGRADE_BACKUP" ]; then
- cp -f "$UPGRADE_BACKUP" "/misc/$BACKUP_FILE"
- sync
- fi
-}
diff --git a/target/linux/mvebu/cortexa53/target.mk b/target/linux/mvebu/cortexa53/target.mk
index fcf658c398..48c8b7f021 100644
--- a/target/linux/mvebu/cortexa53/target.mk
+++ b/target/linux/mvebu/cortexa53/target.mk
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
ARCH:=aarch64
BOARDNAME:=Marvell Armada 3700LP (ARM64)
CPU_TYPE:=cortex-a53
-FEATURES+=ext4
+FEATURES+=ext4 emmc
DEFAULT_PACKAGES+=e2fsprogs ethtool mkf2fs partx-utils
KERNELNAME:=Image dtbs
diff --git a/target/linux/mvebu/image/Makefile b/target/linux/mvebu/image/Makefile
index a1fa4b9f8d..db933a075b 100644
--- a/target/linux/mvebu/image/Makefile
+++ b/target/linux/mvebu/image/Makefile
@@ -136,19 +136,6 @@ define Build/sdcard-img-ext4
83 $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS)
endef
-define Build/uDPU-firmware
- (rm -fR $@-fw; mkdir -p $@-fw)
- $(CP) $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) $@-fw/recovery.itb
- $(CP) $(IMAGE_ROOTFS) $@-fw/rootfs.tgz
- $(CP) $@-boot.scr $@-fw/boot.scr
- $(TAR) -czp --numeric-owner --owner=0 --group=0 --sort=name \
- $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
- -f $@-fw/boot.tgz -C $@.boot .
- $(TAR) -czp --numeric-owner --owner=0 --group=0 --sort=name \
- $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
- -f $(KDIR_TMP)/$(DEVICE_IMG_PREFIX)-firmware.tgz -C $@-fw .
-endef
-
define Device/FitImage
KERNEL_SUFFIX := -uImage.itb
KERNEL = kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
diff --git a/target/linux/mvebu/image/cortexa53.mk b/target/linux/mvebu/image/cortexa53.mk
index 65e64ac512..f4c99caaa0 100644
--- a/target/linux/mvebu/image/cortexa53.mk
+++ b/target/linux/mvebu/image/cortexa53.mk
@@ -97,19 +97,46 @@ define Device/marvell_armada-3720-db
endef
TARGET_DEVICES += marvell_armada-3720-db
+define Build/methode-gpt-emmc
+ cp $@ $@.tmp 2>/dev/null || true
+ ptgen -g -o $@.tmp -l 1024 \
+ -t 0x2e -N kernel_1 -r -B -p 32M@1M \
+ -t 0x2e -N rootfs_1 -r -p 1536M@33M \
+ -t 0x2e -N kernel_2 -r -B -p 32M@1569M \
+ -t 0x2e -N rootfs_2 -r -p 1536M@1601M
+ cat $@.tmp >> $@
+ rm $@.tmp
+endef
+
+define Build/append-boot-part
+ dd if=$@.bootimg bs=32M conv=sync >> $@
+endef
+
+define Device/eMMC-methode
+ DEVICE_DTS_DIR := $(DTS_DIR)/marvell
+ KERNEL_NAME := Image
+ KERNEL := kernel-bin
+ KERNEL_LOADADDR := 0x00800000
+ DEVICE_PACKAGES += kmod-i2c-pxa kmod-hwmon-lm75 kmod-dsa-mv88e6xxx
+ DEVICE_COMPAT_VERSION := 2.0
+ DEVICE_COMPAT_MESSAGE := Partition layout and image format was changed. \
+ Upgrade requires reinstallation from initramfs.
+ FILESYSTEMS := squashfs
+ IMAGES := sysupgrade.bin emmc-gpt.img.gz
+ IMAGE/sysupgrade.bin := boot-scr | boot-img-ext4 | sysupgrade-tar kernel=$$$$@.bootimg | append-metadata
+ IMAGE/emmc-gpt.img.gz := methode-gpt-emmc |\
+ pad-to 1M | boot-scr | boot-img-ext4 | append-boot-part |\
+ pad-to 33M | append-rootfs |\
+ gzip
+ BOOT_SCRIPT := udpu
+endef
+
define Device/methode_udpu
- $(call Device/Default-arm64)
+ $(call Device/eMMC-methode)
$(call Device/FitImage)
DEVICE_VENDOR := Methode
DEVICE_MODEL := micro-DPU (uDPU)
DEVICE_DTS := armada-3720-uDPU
- KERNEL_LOADADDR := 0x00800000
- DEVICE_PACKAGES += f2fs-tools fdisk kmod-i2c-pxa kmod-hwmon-lm75 kmod-dsa-mv88e6xxx
- DEVICE_IMG_NAME = $$(DEVICE_IMG_PREFIX)-$$(2)
- FILESYSTEMS := targz
- IMAGES := firmware.tgz
- IMAGE/firmware.tgz := boot-scr | boot-img-ext4 | uDPU-firmware | append-metadata
- BOOT_SCRIPT := udpu
endef
TARGET_DEVICES += methode_udpu
diff --git a/target/linux/mvebu/image/udpu.bootscript b/target/linux/mvebu/image/udpu.bootscript
index 741254e460..51eab7e381 100644
--- a/target/linux/mvebu/image/udpu.bootscript
+++ b/target/linux/mvebu/image/udpu.bootscript
@@ -8,26 +8,67 @@ gpio clear 12; gpio clear 40; gpio clear 45;
# Find eMMC device,
if mmc dev 0; then
setenv mmcdev 0
- setenv rootdev 'root=/dev/mmcblk0p3'
elif mmc dev 1; then
setenv mmcdev 1
- setenv rootdev 'root=/dev/mmcblk1p3'
fi
+# Check if bootactive variable exists and if not, default to 1
+if test -z "${bootactive}"; then
+ setenv bootactive 1
+fi
+
+# Check if bootcount variable exists and if not, default to 0
+if test -z "${bootcount}"; then
+ setenv bootcount 0
+fi
+
+if itest ${bootcount} > 2; then
+ if itest ${bootactive} == 2; then
+ setenv bootactive 1
+ else
+ setenv bootactive 2
+ fi
+
+ setenv bootcount 0
+fi
+
+# Find A/B firmware to boot
+if itest ${bootactive} == 2; then
+ setenv kernelpart 3
+ setenv rootfspart 4
+else
+ setenv kernelpart 1
+ setenv rootfspart 2
+fi
+
+setenv rootdev 'root=/dev/mmcblk'${mmcdev}'p'${rootfspart}
+
# Set the variables if necessary
if test ${kernel_addr_r}; then
setenv kernel_addr_r 0x5000000
fi
-setenv console 'rootfs_mount_options.compress_algorithm=zstd'
-setenv bootargs ${console} $rootdev rw rootwait
+echo 'Booting firmware:' ${bootactive}
-load mmc ${mmcdev}:1 ${kernel_addr_r} Image
+if itest ${bootcount} == 0; then
+ setenv bootcount 1
+elif itest ${bootcount} == 1; then
+ setenv bootcount 2
+elif itest ${bootcount} == 2; then
+ setenv bootcount 3
+else
+ setenv bootcount 4
+fi
-bootm ${kernel_addr_r}
+env save
+
+setenv bootargs $rootdev rootwait fstools_overlay_compression_type=zstd
+
+load mmc ${mmcdev}:${kernelpart} ${kernel_addr_r} Image
-# If the boot command fails, fallback to recovery image
-echo '-- Boot failed, falling back to the recovery image --'
-setenv bootargs $console
-load mmc ${mmcdev}:2 ${kernel_addr_r} recovery.itb
bootm ${kernel_addr_r}
+
+# If booting fails before kernel is loaded then reboot
+# so the bootcount can trigger a slot switch.
+echo 'Booting firmware:' ${bootactive} 'failed, rebooting'
+reset