[][Refactor eMMC image of MT7986]
[Description]
Refactor eMMC image of MT7986.
The whole image format is changed:
- Kernel and rootfs reside in individual partitions.
- rootfs_data split from rootfs partition using loop device with offset.
- Upgrading firmware usig tarball with saving config files supported.
- No recovery partition needed.
- No GPT partition offset and size restricted.
Important note:
Please select the following packages to make emmc firmware upgrading work:
e2fsprogs mkf2fs blkid blockdev losetup kmod-fs-ext4 kmod-fs-f2fs
[Release-log]
N/A
Change-Id: I9c8c3800ae45c0316a30b2fc0bc825fd71b0f24e
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5258148
diff --git a/target/linux/mediatek/base-files/lib/upgrade/mmc.sh b/target/linux/mediatek/base-files/lib/upgrade/mmc.sh
new file mode 100644
index 0000000..bd1966c
--- /dev/null
+++ b/target/linux/mediatek/base-files/lib/upgrade/mmc.sh
@@ -0,0 +1,121 @@
+
+# Keep these values be up-to-date with definition in libfstools/rootdisk.c of fstools package
+ROOTDEV_OVERLAY_ALIGN=$((64*1024))
+F2FS_MINSIZE=$((100*1024*1024))
+
+mtk_get_root() {
+ local rootfsdev
+
+ if read cmdline < /proc/cmdline; then
+ case "$cmdline" in
+ *root=*)
+ rootfsdev="${cmdline##*root=}"
+ rootfsdev="${rootfsdev%% *}"
+ ;;
+ esac
+
+ echo "${rootfsdev}"
+ fi
+}
+
+mmc_upgrade_tar() {
+ local tar_file="$1"
+ local kernel_dev="$2"
+ local rootfs_dev="$3"
+
+ local board_dir=$(tar tf ${tar_file} | grep -m 1 '^sysupgrade-.*/$')
+ board_dir=${board_dir%/}
+
+ local kernel_length=$( (tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null)
+ local rootfs_length=$( (tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null)
+
+ [ "${kernel_length}" != 0 ] && {
+ tar xf ${tar_file} ${board_dir}/kernel -O >${kernel_dev}
+ }
+
+ [ "${rootfs_length}" != 0 ] && {
+ tar xf ${tar_file} ${board_dir}/root -O >${rootfs_dev}
+ }
+
+ local rootfs_dev_size=$(blockdev --getsize64 ${rootfs_dev})
+ [ $? -ne 0 ] && return 1
+
+ local rootfs_data_offset=$(((rootfs_length+ROOTDEV_OVERLAY_ALIGN-1)&~(ROOTDEV_OVERLAY_ALIGN-1)))
+ local rootfs_data_size=$((rootfs_dev_size-rootfs_data_offset))
+
+ local loopdev="$(losetup -f)"
+ losetup -o $rootfs_data_offset $loopdev $rootfs_dev || {
+ v "Failed to mount looped rootfs_data."
+ return 1
+ }
+
+ local fstype=ext4
+ local mkfs_arg="-q -L rootfs_data"
+ [ "${rootfs_data_size}" -gt "${F2FS_MINSIZE}" ] && {
+ fstype=f2fs
+ mkfs_arg="-q -l rootfs_data"
+ }
+
+ v "Format new rootfs_data at position ${rootfs_data_offset}."
+ mkfs.${fstype} ${mkfs_arg} ${loopdev}
+ [ $? -ne 0 ] && return 1
+
+ [ -n "$UPGRADE_BACKUP" ] && {
+ mkdir -p /tmp/new_root
+ mount -t ${fstype} ${loopdev} /tmp/new_root && {
+ v "Saving config to rootfs_data at position ${rootfs_data_offset}."
+ mv "$UPGRADE_BACKUP" "/tmp/new_root/$BACKUP_FILE"
+ umount /tmp/new_root
+ }
+ }
+
+ # Cleanup
+ losetup -d ${loopdev} >/dev/null 2>&1
+ sync
+
+ return 0
+}
+
+mtk_mmc_do_upgrade() {
+ local tar_file="$1"
+ local board=$(board_name)
+ local kernel_dev=
+ local rootfs_dev=
+ local cmdline_root="$(mtk_get_root)"
+
+ case "$cmdline_root" in
+ /dev/mmcblk*)
+ rootfs_dev=${cmdline_root}
+ ;;
+ PARTLABEL=* | PARTUUID=*)
+ rootfs_dev=$(blkid -t "${cmdline_root}" -o device)
+ [ -z "${rootfs_dev}" -o $? -ne 0 ] && return 1
+ ;;
+ *)
+ return 1;
+ ;;
+ esac
+
+ case "$board" in
+ *)
+ kernel_dev=$(blkid -t "PARTLABEL=kernel" -o device)
+ [ -z "${kernel_dev}" -o $? -ne 0 ] && return 1
+ ;;
+ esac
+
+ # keep sure its unbound
+ losetup --detach-all || {
+ v "Failed to detach all loop devices."
+ sleep 10
+ reboot -f
+ }
+
+ mmc_upgrade_tar "${tar_file}" "${kernel_dev}" "${rootfs_dev}"
+
+ [ $? -ne 0 ] && {
+ v "Upgrade failed."
+ return 1
+ }
+
+ return 0
+}
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-emmc-rfb.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-emmc-rfb.dts
index df49496..c094abe 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-emmc-rfb.dts
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-2500wan-emmc-rfb.dts
@@ -3,11 +3,11 @@
#include "mt7986a-pinctrl.dtsi"
/ {
model = "MediaTek MT7986a RFB";
- compatible = "mediatek,mt7986a-2500wan-nor-rfb";
+ compatible = "mediatek,mt7986a-emmc-rfb";
chosen {
bootargs = "console=ttyS0,115200n1 loglevel=8 \
earlycon=uart8250,mmio32,0x11002000 \
- root=/dev/mmcblk0p7 rootwait rootfstype=squashfs,f2fs";
+ root=PARTLABEL=rootfs rootwait rootfstype=squashfs,f2fs";
};
memory {
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-emmc-rfb.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-emmc-rfb.dts
index 27bf0b5..f5ec053 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-emmc-rfb.dts
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a-emmc-rfb.dts
@@ -7,7 +7,7 @@
chosen {
bootargs = "console=ttyS0,115200n1 loglevel=8 \
earlycon=uart8250,mmio32,0x11002000 \
- root=/dev/mmcblk0p7 rootwait rootfstype=squashfs,f2fs";
+ root=PARTLABEL=rootfs rootwait rootfstype=squashfs,f2fs";
};
memory {
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-2500wan-emmc-rfb.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-2500wan-emmc-rfb.dts
index a9b420e..d768e45 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-2500wan-emmc-rfb.dts
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-2500wan-emmc-rfb.dts
@@ -7,7 +7,7 @@
chosen {
bootargs = "console=ttyS0,115200n1 loglevel=8 \
earlycon=uart8250,mmio32,0x11002000 \
- root=/dev/mmcblk0p7 rootwait rootfstype=squashfs,f2fs";
+ root=PARTLABEL=rootfs rootwait rootfstype=squashfs,f2fs";
};
memory {
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-emmc-rfb.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-emmc-rfb.dts
index 1dfecc3..73f1462 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-emmc-rfb.dts
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b-emmc-rfb.dts
@@ -7,7 +7,7 @@
chosen {
bootargs = "console=ttyS0,115200n1 loglevel=8 \
earlycon=uart8250,mmio32,0x11002000 \
- root=/dev/mmcblk0p7 rootwait rootfstype=squashfs,f2fs";
+ root=PARTLABEL=rootfs rootwait rootfstype=squashfs,f2fs";
};
memory {
diff --git a/target/linux/mediatek/image/gen_mt7986_emmc_img.sh b/target/linux/mediatek/image/gen_mt7986_emmc_img.sh
deleted file mode 100755
index d74068c..0000000
--- a/target/linux/mediatek/image/gen_mt7986_emmc_img.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-OUTPUT_FILE=$1
-KERNEL_FILE=$2
-RECOVERY_FILE=$3
-ROOTFS_FILE=$4
-
-BS=512
-
-#RECOVERY_OFFSET= kernel size / BS = 20M / 512 (blocks)
-RECOVERY_OFFSET=40960
-
-#ROOTFS_OFFSET = RECOVERY_OFFSET + (RECOVERY_SIZE / BS)
-# = 40960 + (10M / 512) (blocks)
-ROOTFS_OFFSET=61440
-dd bs="$BS" of="$OUTPUT_FILE" if="$KERNEL_FILE"
-dd bs="$BS" of="$OUTPUT_FILE" if="$RECOVERY_FILE" seek="$RECOVERY_OFFSET"
-dd bs="$BS" of="$OUTPUT_FILE" if="$ROOTFS_FILE" seek="$ROOTFS_OFFSET"
-dd if=/dev/zero of="$OUTPUT_FILE" bs=128k count=1 oflag=append conv=notrunc
diff --git a/target/linux/mediatek/image/mt7986.mk b/target/linux/mediatek/image/mt7986.mk
index 7aac59d..65031a9 100644
--- a/target/linux/mediatek/image/mt7986.mk
+++ b/target/linux/mediatek/image/mt7986.mk
@@ -64,9 +64,11 @@
DEVICE_MODEL := mt7986a-ax6000-emmc-rfb
DEVICE_DTS := mt7986a-emmc-rfb
DEVICE_DTS_DIR := $(DTS_DIR)/mediatek
- DEVICE_PACKAGES := mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc
- IMAGES := sysupgrade-emmc.bin.gz
- IMAGE/sysupgrade-emmc.bin.gz := sysupgrade-emmc | gzip | append-metadata
+ SUPPORTED_DEVICES := mediatek,mt7986a-emmc-rfb
+ DEVICE_PACKAGES := mkf2fs e2fsprogs blkid blockdev losetup kmod-fs-ext4 \
+ kmod-mmc kmod-fs-f2fs kmod-fs-vfat kmod-nls-cp437 \
+ kmod-nls-iso8859-1
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += mt7986a-ax6000-emmc-rfb
@@ -209,9 +211,11 @@
DEVICE_MODEL := mt7986b-ax6000-emmc-rfb
DEVICE_DTS := mt7986b-emmc-rfb
DEVICE_DTS_DIR := $(DTS_DIR)/mediatek
- DEVICE_PACKAGES := mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc
- IMAGES := sysupgrade-emmc.bin.gz
- IMAGE/sysupgrade-emmc.bin.gz := sysupgrade-emmc | gzip | append-metadata
+ SUPPORTED_DEVICES := mediatek,mt7986b-emmc-rfb
+ DEVICE_PACKAGES := mkf2fs e2fsprogs blkid blockdev losetup kmod-fs-ext4 \
+ kmod-mmc kmod-fs-f2fs kmod-fs-vfat kmod-nls-cp437 \
+ kmod-nls-iso8859-1
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += mt7986b-ax6000-emmc-rfb
diff --git a/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
index 2ee99c7..4a1573a 100644
--- a/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
@@ -1,3 +1,5 @@
+RAMFS_COPY_BIN='mkfs.f2fs blkid blockdev'
+
platform_do_upgrade() {
local board=$(board_name)
@@ -5,6 +7,9 @@
*snand*)
nand_do_upgrade "$1"
;;
+ *emmc*)
+ mtk_mmc_do_upgrade "$1"
+ ;;
*)
default_do_upgrade "$1"
;;
@@ -20,7 +25,8 @@
[ "$#" -gt 1 ] && return 1
case "$board" in
- *snand*)
+ *snand* |\
+ *emmc*)
# tar magic `ustar`
magic="$(dd if="$1" bs=1 skip=257 count=5 2>/dev/null)"
@@ -42,4 +48,3 @@
return 0
}
-