--- /dev/null
+. /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
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=99
+
+boot() {
+ case $(board_name) in
+ methode,udpu|\
+ methode,edpu)
+ fw_setenv bootcount 0
+ ;;
+ esac
+}
+++ /dev/null
-#
-# 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
;;
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"
;;
methode,udpu|\
methode,edpu)
- platform_copy_config_uDPU
+ emmc_copy_config
;;
esac
}
+++ /dev/null
-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
-}
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
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 | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
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
# 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