Просмотр исходного кода

gemini: override IB-4220-B partitions for firmware

To optimize the flash usage and to make firmware upgrades
simpler, catenate the three firmware partitions "Kern",
"Ramdisk" and "Application" into one, and use all of this
for the combined MTD-splitted kernel+rootfs.

This works fine as long as the kernel is placed in the
beginning of this firmware partition and we leave the
RedBoot partition as is, so the boot loader still can load
the kernel from the first two RedBoot partitions.

Using the RedBoot partitions "as is" can be considered
harmful, because when you flash to a RedBoot partition the
file size is used for downsizing of the partition and make
firmware upgrades fail if they are larger than the RedBoot
partition size after flashing, despite there is actually
flash there. So overriding with fixed partitions is just
generally a good idea.

Link: https://github.com/openwrt/openwrt/pull/21820
Signed-off-by: Linus Walleij <[email protected]>
Linus Walleij 2 недель назад
Родитель
Сommit
387752dc76

+ 40 - 12
target/linux/gemini/base-files/lib/upgrade/platform.sh

@@ -56,8 +56,8 @@ gemini_check_redboot_parts() {
 	fi
 	fi
 }
 }
 
 
-gemini_do_platform_upgrade() {
-	echo "Extract the three firmware parts"
+gemini_do_redboot_upgrade() {
+	echo "Extract the three firmware parts from tarfile"
 	echo 3 > /proc/sys/vm/drop_caches
 	echo 3 > /proc/sys/vm/drop_caches
 	echo "COMMENCING UPGRADE. BE PATIENT, THIS IS NOT FAST!"
 	echo "COMMENCING UPGRADE. BE PATIENT, THIS IS NOT FAST!"
 	KFSZ=$(tar xfz "$1" zImage -O | wc -c)
 	KFSZ=$(tar xfz "$1" zImage -O | wc -c)
@@ -74,16 +74,45 @@ gemini_do_platform_upgrade() {
 	[ $? -ne 0 ] && exit 1
 	[ $? -ne 0 ] && exit 1
 }
 }
 
 
+# This converts the old RedBoot partitioning to the new shared
+# "firmware" partition.
+gemini_do_flat_redboot_upgrade() {
+	ESZ=131072
+	KSZ=$(($ESZ * $2))
+	RSZ=$(($ESZ * $3))
+	KRSZ=$(($KSZ + $RSZ))
+	ASZ=$(($ESZ * $4))
+	echo "Partition sizes: Kern ${KSZ}, Ramdisk ${RSZ}, Application ${ASZ}"
+	echo "Extract Kern from flat image ${1}"
+	echo "Write Kern from flat image ${1}"
+	dd if="$1" bs=1 count=${KSZ} | mtd write - Kern
+	echo "Write rd.gz from flat image ${1}"
+	dd if="$1" bs=1 skip=${KSZ} count=${RSZ} | mtd write - Ramdisk
+	echo "Write hddapp.tgz from flat image ${1}"
+	dd if="$1" bs=1 skip=${KRSZ} count=${ASZ} | mtd write - Application
+}
+
+# Check if we have the new partition scheme, else do it the old
+# way.
+gemini_do_combined_upgrade() {
+	NAME=`cat ${MTDSYSFS}/mtd1/name`
+	if test "x${NAME}" == "xfirmware" ; then
+		PART_NAME=firmware
+		default_do_upgrade "$1"
+	else
+		gemini_check_redboot_parts "$1" $2 $3 $4
+		gemini_do_flat_redboot_upgrade "$1" $2 $3 $4
+	fi
+}
+
 platform_check_image() {
 platform_check_image() {
 	local board=$(board_name)
 	local board=$(board_name)
 
 
 	case "$board" in
 	case "$board" in
-	dlink,dir-685)
-		return 0
-		;;
-	raidsonic,ib-4220-b|\
+	dlink,dir-685|\
 	itian,sq201|\
 	itian,sq201|\
-	storlink,gemini324)
+	storlink,gemini324|\
+	raidsonic,ib-4220-b)
 		return 0
 		return 0
 		;;
 		;;
 	esac
 	esac
@@ -100,14 +129,13 @@ platform_do_upgrade() {
 		PART_NAME=firmware
 		PART_NAME=firmware
 		default_do_upgrade "$1"
 		default_do_upgrade "$1"
 		;;
 		;;
+	raidsonic,ib-4220-b)
+		gemini_do_combined_upgrade "$1" 24 48 48
+		;;
 	itian,sq201|\
 	itian,sq201|\
 	storlink,gemini324)
 	storlink,gemini324)
 		gemini_check_redboot_parts "$1" 16 48 48
 		gemini_check_redboot_parts "$1" 16 48 48
-		gemini_do_platform_upgrade "$1"
-		;;
-	raidsonic,ib-4220-b)
-		gemini_check_redboot_parts "$1" 24 48 48
-		gemini_do_platform_upgrade "$1"
+		gemini_do_redboot_upgrade "$1"
 		;;
 		;;
 	esac
 	esac
 }
 }

+ 1 - 0
target/linux/gemini/config-6.12

@@ -277,6 +277,7 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_GEMINI=y
 CONFIG_MTD_PHYSMAP_GEMINI=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_SPLIT_FIRMWARE=y
 CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_OPENWRT_PROLOG=y
 CONFIG_MTD_SPLIT_WRGG_FW=y
 CONFIG_MTD_SPLIT_WRGG_FW=y
 CONFIG_NAMESPACES=y
 CONFIG_NAMESPACES=y
 CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_NEED_DMA_MAP_STATE=y

+ 66 - 12
target/linux/gemini/image/Makefile

@@ -89,14 +89,23 @@ endef
 # 0x000000320000-0x000000920000 : "Ramdisk" - second part of the kernel and
 # 0x000000320000-0x000000920000 : "Ramdisk" - second part of the kernel and
 #                                 some padding goes here
 #                                 some padding goes here
 # 0x000000920000-0x000000f20000 : "Application" - rootfs goes here
 # 0x000000920000-0x000000f20000 : "Application" - rootfs goes here
+
+define CreateStorlinkProlog
+	# 512 bytes copy routine
+	dd if=$(KDIR)/copy-kernel-$(2).bin of=$(1)
+	# Add OpenWrt prolog header (used by partition splitter)
+	echo "OPENWRT-PROLOG-512" >> $(1)
+	stat -c %s ${IMAGE_KERNEL} >> $(1)
+	$(call Image/pad-to,$(1),512)
+endef
+
 define CreateStorlinkTarfile
 define CreateStorlinkTarfile
 	mkdir -p [email protected]
 	mkdir -p [email protected]
 
 
 	# "Application" partition is the rootfs
 	# "Application" partition is the rootfs
 	mv $@ [email protected]/hddapp.tgz
 	mv $@ [email protected]/hddapp.tgz
-	# 512 bytes copy routine
-	dd if=$(KDIR)/copy-kernel-$(2).bin [email protected]/zImage
-	$(call Image/pad-to,[email protected]/zImage,512)
+	$(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS) -c 128 >>[email protected]/hddapp.tgz
+	$(call CreateStorlinkProlog,[email protected]/zImage,$(2))
 	# Copy first part of the kernel into zImage
 	# Copy first part of the kernel into zImage
 	dd if=$(IMAGE_KERNEL) [email protected]/zImage bs=1 seek=512 count=$(3)
 	dd if=$(IMAGE_KERNEL) [email protected]/zImage bs=1 seek=512 count=$(3)
 	$(call Image/pad-to,[email protected]/zImage,128k)
 	$(call Image/pad-to,[email protected]/zImage,128k)
@@ -114,14 +123,60 @@ define CreateStorlinkTarfile
 	exit 0
 	exit 0
 endef
 endef
 
 
+define CreateStorlinkFactoryfile
+	mkdir -p [email protected]
+	$(call CreateStorlinkProlog,[email protected]/zImage,$(2))
+	# Copy first part of the kernel into zImage
+	dd if=$(IMAGE_KERNEL) [email protected]/zImage bs=1 seek=512 count=$(3)
+	$(call Image/pad-to,[email protected]/zImage,128k)
+	# Put the rest of the kernel into the "ramdisk"
+	dd if=$(IMAGE_KERNEL) of=$@-ramdisk bs=1 skip=$(3) conv=sync
+	$(call Image/pad-to,$@-ramdisk,128k)
+	# Append the root filesystem right after this
+	dd if=$(IMAGE_ROOTFS) >> $@-ramdisk
+	$(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS) -c 128 >> $@-ramdisk
+	# Now rd.gz is too big so split off rd.gz and the tail into "hddapp.gz"
+	dd if=$@-ramdisk [email protected]/rd.gz bs=1 count=6144k conv=sync
+	dd if=$@-ramdisk [email protected]/hddapp.tgz bs=1 skip=6144k count=6144k conv=sync
+	rm -f $@-ramdisk
+	# Taglabel
+	cp ./ImageInfo-$(1) [email protected]/ImageInfo
+
+	sed -i -e "s/DATESTR/`date +%Y%m%d $(if $(SOURCE_DATE_EPOCH),--date "@$(SOURCE_DATE_EPOCH)")`/g" [email protected]/ImageInfo
+
+	(cd [email protected]; tar --sort=name --owner=0 --group=0 --numeric-owner -czf $@ * \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)"))
+
+	rm -rf [email protected]
+	exit 0
+endef
+
+define CreateStorlinkSysupgradefile
+	$(call CreateStorlinkProlog,$@,$(2))
+	# Catenate the kernel
+	dd if=$(IMAGE_KERNEL) >> $@
+	$(call Image/pad-to,$@,128k)
+	# Append the root filesystem right after this
+	dd if=$(IMAGE_ROOTFS) >> $@
+	$(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS) -c 128 >> $@
+endef
+
 # 2048k "Kern" partition
 # 2048k "Kern" partition
-define Build/storlink-default-image
+define Build/storlink-2048k-default-image
 	$(call CreateStorlinkTarfile,$(1),2048k,2096640)
 	$(call CreateStorlinkTarfile,$(1),2048k,2096640)
 endef
 endef
 
 
+define Build/storlink-2048k-sysupgrade-image
+	$(call CreateStorlinkSysupgradefile,$(1),2048k)
+endef
+
 # 3072k "Kern" partition
 # 3072k "Kern" partition
-define Build/raidsonic-ib-4220-b-image
-	$(call CreateStorlinkTarfile,$(1),3072k,3145216)
+define Build/storlink-3072k-factory-image
+	$(call CreateStorlinkFactoryfile,$(1),3072k,3145216)
+endef
+
+define Build/storlink-3072k-sysupgrade-image
+	$(call CreateStorlinkSysupgradefile,$(1),3072k)
 endef
 endef
 
 
 # WBD-111 and WBD-222:
 # WBD-111 and WBD-222:
@@ -203,9 +258,9 @@ define Device/storlink-reference
 	# Ramdisk      6144k remaining zImage
 	# Ramdisk      6144k remaining zImage
 	# Application  6144k
 	# Application  6144k
 	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 128k | \
 	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 128k | \
-		storlink-default-image $(1)
+		storlink-2048k-default-image $(1)
 	IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to 128k | \
 	IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to 128k | \
-		storlink-default-image $(1) | append-metadata
+		storlink-2048k-default-image $(1) | append-metadata
 	DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES)
 	DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES)
 endef
 endef
 
 
@@ -227,10 +282,9 @@ define Device/raidsonic_ib-4220-b
 	# Kern         3072k - 512 | = 3145216
 	# Kern         3072k - 512 | = 3145216
 	# Ramdisk      6144k       | = 9216k
 	# Ramdisk      6144k       | = 9216k
 	# Application  6144k       | = 15360k
 	# Application  6144k       | = 15360k
-	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 128k | \
-		raidsonic-ib-4220-b-image $(1)
-	IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to 128k | \
-		raidsonic-ib-4220-b-image $(1) | append-metadata
+	IMAGE/factory.bin := storlink-3072k-factory-image $(1)
+	IMAGE/sysupgrade.bin := storlink-3072k-sysupgrade-image $(1) |\
+			append-metadata
 endef
 endef
 TARGET_DEVICES += raidsonic_ib-4220-b
 TARGET_DEVICES += raidsonic_ib-4220-b
 
 

+ 80 - 0
target/linux/gemini/patches-6.12/303-gemini-augment-DTS-with-botched-partitions.patch

@@ -0,0 +1,80 @@
+From 1b5c6be7b6dc6c096e1fd55ce10809d350e3afab Mon Sep 17 00:00:00 2001
+From: Linus Walleij <[email protected]>
+Date: Mon, 26 Jan 2026 08:09:04 +0100
+Subject: [PATCH] gemini: augment DTS with botched partitions
+
+We override the RedBoot FIS partition table with a custom one
+using fixed-partitions.
+
+Mostly this is a 1-to-1 copy, but the three partitions called
+"Kern", "Ramdisk" and "Application" are combined into one
+called "firmware" which is optimal for OpenWrt.
+
+The RedBoot bootloader still sees the three partitions and will
+load the first two into memory to boot the system, which
+is fine: the kernel will still be there.
+
+To avoid confusing the MTD partition splitter we also need to
+remove any command line root partition arguments.
+
+Signed-off-by: Linus Walleij <[email protected]>
+---
+ arch/arm/boot/dts/gemini/gemini-nas4220b.dts | 39 ++++++++++++++++++--
+ 1 file changed, 35 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini/gemini-nas4220b.dts
++++ b/arch/arm/boot/dts/gemini/gemini-nas4220b.dts
+@@ -20,7 +20,7 @@
+ 	};
+ 
+ 	chosen {
+-		bootargs = "console=ttyS0,19200n8 root=/dev/mtdblock3 rw rootfstype=squashfs,jffs2 rootwait";
++		bootargs = "console=ttyS0,19200n8";
+ 		stdout-path = &uart0;
+ 	};
+ 
+@@ -82,10 +82,41 @@
+ 			/* 16MB of flash */
+ 			reg = <0x30000000 0x01000000>;
+ 
++			/*
++			 * Override the RedBoot partition table with fixed partitions
++			 * in order to create a coherent "firmware" partition so that
++			 * we can have optimal flash usage with OpenWrt in a big
++			 * MTD-splitted "firmware" partition.
++			 */
+ 			partitions {
+-				compatible = "redboot-fis";
+-				/* Eraseblock at 0xfe0000 */
+-				fis-index-block = <0x7f>;
++				compatible = "fixed-partitions";
++				#address-cells = <1>;
++				#size-cells = <1>;
++				partition@0 {
++					label = "BOOT";
++					reg = <0x00000000 0x00020000>;
++					read-only;
++				};
++				partition@1 {
++					compatible = "openwrt,executable-prolog";
++					label = "firmware";
++					reg = <0x00020000 0x00f00000>;
++				};
++				partition@2 {
++					label = "VCTL";
++					reg = <0x00f20000 0x00020000>;
++					read-only;
++				};
++				partition@3 {
++					label = "CurConf";
++					reg = <0x00f40000 0x000a0000>;
++					read-only;
++				};
++				partition@4 {
++					label = "FIS directory";
++					reg = <0x00fe0000 0x00020000>;
++					read-only;
++				};
+ 			};
+ 		};
+