[PATCH v2 4/4] bmips: Build U-Boot into the XG6846 target

Linus Walleij linus.walleij at linaro.org
Thu Apr 25 13:12:51 PDT 2024


It appears that the CFE boot loader found in the XG6846
cannot load kernels over a certain size, and the old
relocate hack is not working.

What to do? We can build a small U-Boot into the image,
make CFE boot that, place the kernel immediately after
U-Boot, and use U-Boot to boot the system instead.

The compiled u-boot.bin becomes around ~300KB and with
LZMA compression it will swiftly fit into 128KB, so
we use two 64KB erase blocks right after the CFE to
store an imagetag:ed U-Boot.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 target/linux/bmips/dts/bcm6328-inteno-xg6846.dts |   3 ++-
 target/linux/bmips/image/Makefile                |  31 +++++++++++++++++++++++
 target/linux/bmips/image/bcm6328.mk              |   2 +-
 target/linux/bmips/image/null-initrd             |   1 +
 target/linux/bmips/image/u-boot.bin              | Bin 0 -> 289149 bytes
 5 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
index ee9d19839ccd..72f85a53ca7c 100644
--- a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
+++ b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
@@ -117,9 +117,10 @@
 			};
 
 			partition at 10000 {
-				compatible = "brcm,bcm963xx-imagetag";
+				compatible = "openwrt,uimage", "denx,uimage";
 				reg = <0x010000 0xfe0000>;
 				label = "firmware";
+				openwrt,offset = <0x30000>;
 			};
 
 			partition at ff0000 {
diff --git a/target/linux/bmips/image/Makefile b/target/linux/bmips/image/Makefile
index 9311e2df096f..b79974931d48 100644
--- a/target/linux/bmips/image/Makefile
+++ b/target/linux/bmips/image/Makefile
@@ -4,6 +4,7 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/image.mk
 
 KERNEL_LOADADDR := 0x80010000		# RAM start + 64K
+UBOOT_ENTRY := 0x81c00000
 LOADER_ENTRY := 0x81000000		# RAM start + 16M, for relocate
 LZMA_TEXT_START := 0x82000000		# RAM start + 32M
 
@@ -94,6 +95,21 @@ define Build/cfe-bin
 		$(CFE_EXTRAS) $(1)
 endef
 
+# Build a CFE image with just U-Boot
+define Build/cfe-bin-uboot
+	cp $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-u-boot.bin $@
+	$(call Build/lzma)
+	mv $@ $@.uboot.lzma
+	echo "dummy" > $@.dummyfs
+	$(STAGING_DIR_HOST)/bin/imagetag -i $@.uboot.lzma -f $@.dummyfs \
+		--output $@ --boardid $(CFE_BOARD_ID) --chipid $(CHIP_ID) \
+		--entry $(UBOOT_ENTRY) --load-addr $(UBOOT_ENTRY) \
+		--info1 "$(call ModelNameLimit16,$(DEVICE_NAME))" \
+		$(CFE_EXTRAS) $(1)
+	rm $@.uboot.lzma
+	rm $@.dummyfs
+endef
+
 define Build/cfe-jffs2
 	$(STAGING_DIR_HOST)/bin/mkfs.jffs2 \
 		--big-endian \
@@ -284,6 +300,21 @@ define Device/bcm63xx-cfe-legacy
   KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma-cfe
 endef
 
+# CFE images with U-Boot in front of the kernel, these will execute
+# U-Boot instead of the kernel and U-Boot will then proceed to load
+# the kernel. The reason to do this is that CFE is sometimes unable to
+# load big kernels even with the lzma loader tricks.
+define Device/bcm63xx-cfe-uboot
+  $(Device/bcm63xx-cfe)
+  KERNEL := kernel-bin | append-dtb | lzma | uImage lzma
+  IMAGE/cfe.bin := cfe-bin-uboot | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+    append-kernel | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+    append-rootfs $$$$(if $$$$(FLASH_MB),--pad $$$$(shell expr $$$$(FLASH_MB) / 2))
+  IMAGE/sysupgrade.bin := cfe-bin-uboot | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+    append-kernel | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+    append-rootfs | append-metadata
+endef
+
 # CFE expects a single JFFS2 partition with cferam and kernel. However,
 # it's possible to fool CFE into properly loading both cferam and kernel
 # from two different JFFS2 partitions by adding dummy files (see
diff --git a/target/linux/bmips/image/bcm6328.mk b/target/linux/bmips/image/bcm6328.mk
index 0e249fa96e45..b85b6ac7a88f 100644
--- a/target/linux/bmips/image/bcm6328.mk
+++ b/target/linux/bmips/image/bcm6328.mk
@@ -52,7 +52,7 @@ endef
 TARGET_DEVICES += innacomm_w3400v6
 
 define Device/inteno_xg6846
-  $(Device/bcm63xx-cfe-legacy)
+  $(Device/bcm63xx-cfe-uboot)
   DEVICE_VENDOR := Inteno
   DEVICE_MODEL := XG6846
   CHIP_ID := 6328
diff --git a/target/linux/bmips/image/null-initrd b/target/linux/bmips/image/null-initrd
new file mode 100644
index 000000000000..421376db9e8a
--- /dev/null
+++ b/target/linux/bmips/image/null-initrd
@@ -0,0 +1 @@
+dummy
diff --git a/target/linux/bmips/image/u-boot.bin b/target/linux/bmips/image/u-boot.bin
new file mode 100644
index 000000000000..2d74a169da6e
Binary files /dev/null and b/target/linux/bmips/image/u-boot.bin differ

-- 
2.44.0




More information about the openwrt-devel mailing list