From 442e67d31f3c8b8c43ecc59d25660faf8e824f31 Mon Sep 17 00:00:00 2001 From: Kenneth Kasilag Date: Sat, 21 Feb 2026 21:49:46 +0000 Subject: [PATCH] airoha: an7581: add uboot chainloader Due to issues surrounding the implementation of the vendor BMT/BBT on Airoha, upstream ATF + uboot has switched to UBI flash partitions. However, some devices shipped on this platform are bootloader locked, and thus it is impossible to replace ATF + uboot. During testing for the Gemtek W1700K (#17869), sysupgrades from Linux (which is unaware of the underlying BMT/BBT) would occasionally write data into blocks which were remapped by the vendor uboot when it was read on the following reboot, causing a soft brick. An acceptable workaround [1],[2] was discussed where an intermediate uboot would be written by the vendor uboot (which is aware of Airoha BMT/BBT). This chainloader would then ignore the regions of flash used by the vendor uboot, and store all relevant data inside of UBI. UBI would then be used to handle bad block management. As the vendor ATF + uboot do not read or interact with the UBI region, we would avoid unwanted remaps from BMT/BBT. This commit introduces support for building such a chainloader, by packaging u-boot and DTS into a FIT image; to be flashed like a kernel. Configuration for the Gemtek W1700K is provided as an example of how the chainloader is used. [1] https://github.com/openwrt/openwrt/pull/17869#discussion_r2836066746 [2] https://github.com/openwrt/openwrt/pull/17869#discussion_r2838395671 Signed-off-by: Kenneth Kasilag [ move FIP_COMPRESS to Build/Compile, wrap some long lines ] Link: https://github.com/openwrt/openwrt/pull/22151 Signed-off-by: Christian Marangi --- package/boot/uboot-airoha/Makefile | 22 +- .../999-airoha-add-gemtek-w1700k.patch | 318 ++++++++++++++++++ target/linux/airoha/image/an7581.mk | 27 ++ 3 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 package/boot/uboot-airoha/patches/999-airoha-add-gemtek-w1700k.patch diff --git a/package/boot/uboot-airoha/Makefile b/package/boot/uboot-airoha/Makefile index 4fedd972e4..1230e879da 100644 --- a/package/boot/uboot-airoha/Makefile +++ b/package/boot/uboot-airoha/Makefile @@ -46,10 +46,19 @@ define U-Boot/an7583_rfb BL31_IMAGE:=an7583-bl31.bin endef +define U-Boot/an7581_gemtek_w1700k + NAME:=Gemtek W1700K (UBI) + UBOOT_CONFIG:=an7581_w1700k + BUILD_DEVICES:=gemtek_w1700k-ubi + BUILD_SUBTARGET:=an7581 + UBOOT_IMAGE:=u-boot.bin +endef + UBOOT_TARGETS := \ en7523_rfb \ an7581_rfb \ - an7583_rfb + an7583_rfb \ + an7581_gemtek_w1700k UBOOT_CUSTOMIZE_CONFIG := \ --disable TOOLS_KWBIMAGE \ @@ -65,9 +74,6 @@ define Build/fip-image-bl2 endef define Build/fip-image - $(if $(LZMA_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \ - $(PKG_BUILD_DIR)/u-boot.bin \ - $(PKG_BUILD_DIR)/u-boot.bin.lzma) $(if $(LZMA_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \ files/$(BL31_IMAGE) \ $(PKG_BUILD_DIR)/bl31.bin.lzma) @@ -84,6 +90,9 @@ endef define Build/Compile $(call Build/Compile/U-Boot) + $(if $(LZMA_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \ + $(PKG_BUILD_DIR)/u-boot.bin \ + $(PKG_BUILD_DIR)/u-boot.bin.lzma) ifeq ($(UBOOT_IMAGE),u-boot.fip) $(call Build/fip-image-bl2) $(call Build/fip-image) @@ -99,6 +108,11 @@ define Build/InstallDev ifeq ($(UBOOT_IMAGE),u-boot.fip) $(INSTALL_DATA) $(PKG_BUILD_DIR)/bl2.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl2.fip $(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl31-u-boot.fip +else + $(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.bin$(if $(LZMA_COMPRESS),.lzma) \ + $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.bin$(if $(LZMA_COMPRESS),.lzma) + $(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.dtb \ + $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.dtb endif endef diff --git a/package/boot/uboot-airoha/patches/999-airoha-add-gemtek-w1700k.patch b/package/boot/uboot-airoha/patches/999-airoha-add-gemtek-w1700k.patch new file mode 100644 index 0000000000..c346499ded --- /dev/null +++ b/package/boot/uboot-airoha/patches/999-airoha-add-gemtek-w1700k.patch @@ -0,0 +1,318 @@ +From d6402eadaa56494b382e389d739b9f80d6883788 Mon Sep 17 00:00:00 2001 +From: Kenneth Kasilag +Date: Sat, 21 Feb 2026 21:49:46 +0000 +Subject: [PATCH] an7581: add uboot chainloader for w1700k + +Due to issues surrounding the implementation of the vendor BMT/BBT +on Airoha, upstream ATF + uboot has switched to UBI flash partitions. + +However, some devices shipped on this platform are bootloader locked, +and thus it is impossible to replace ATF + uboot. + +During testing for the Gemtek W1700K (#17869), sysupgrades from Linux +(which is unaware of the underlying BMT/BBT) would occasionally write +data into blocks which were remapped by the vendor uboot when it was +read on the following reboot, causing a soft brick. + +An acceptable workaround [1],[2] was discussed where an intermediate +uboot would be written by the vendor uboot (which is aware of Airoha +BMT/BBT). This chainloader would then ignore the regions of flash +used by the vendor uboot, and store all relevant data inside of UBI. + +UBI would then be used to handle bad block management. As the vendor +ATF + uboot do not read or interact with the UBI region, we would avoid +unwanted remaps from BMT/BBT. + +This commit introduces support for building such a chainloader, by +packaging u-boot and DTS into a FIT image; to be flashed like a kernel. + +Configuration for the Gemtek W1700K is provided as an example of how the +chainloader is used. + +[1] https://github.com/openwrt/openwrt/pull/17869#discussion_r2836066746 +[2] https://github.com/openwrt/openwrt/pull/17869#discussion_r2838395671 + +Signed-off-by: Kenneth Kasilag +--- + configs/an7581_w1700k_defconfig | 107 ++++++++++ + defenvs/an7581_w1700k_env | 21 ++ + dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts | 87 +++++ + 3 files changed, 215 insertions(+), 0 deletions(-) + create mode 100644 configs/an7581_w1700k_defconfig + create mode 100644 defenvs/an7581_w1700k_env + create mode 100644 dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts + +--- /dev/null ++++ b/configs/an7581_w1700k_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_AIROHA=y ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_TARGET_AN7581=y ++CONFIG_TEXT_BASE=0x81E00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x4000 ++CONFIG_ENV_OFFSET=0x7c000 ++CONFIG_DM_GPIO=y ++CONFIG_DEFAULT_DEVICE_TREE="airoha/an7581-w1700k-ubi" ++CONFIG_SYS_LOAD_ADDR=0x81800000 ++CONFIG_BUILD_TARGET="u-boot.bin" ++# CONFIG_EFI_LOADER is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_BOOTDELAY=30 ++CONFIG_DEFAULT_FDT_FILE="an7581-w1700k-ubi" ++CONFIG_SYS_PBSIZE=1049 ++CONFIG_SYS_CONSOLE_IS_IN_ENV=y ++# CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="U-Boot> " ++CONFIG_SYS_MAXARGS=8 ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_BOOTMENU=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_XIMG is not set ++CONFIG_CMD_BIND=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_SPI=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_PING=y ++CONFIG_CMD_EXT4=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_CMD_MTDPARTS=y ++CONFIG_CMD_LOG=y ++CONFIG_OF_UPSTREAM=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++# CONFIG_ENV_IS_IN_MTD is not set ++CONFIG_ENV_RELOC_GD_ENV_ADDR=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_SYS_RX_ETH_BUFFER=8 ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_DMA=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_ISSI=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_SPANSION=y ++CONFIG_SPI_FLASH_STMICRO=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_AIROHA_ETH=y ++CONFIG_DM_MDIO=y ++CONFIG_CMD_MII=y ++CONFIG_CMD_MDIO=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_SYS_NS16550=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_AIROHA_SNFI_SPI=y ++CONFIG_CMD_UBI=y ++# CONFIG_CMD_UBI_RENAME is not set ++CONFIG_CMD_UBIFS=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_ENV_REDUNDANT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_ENV_UBI_VID_OFFSET=0 ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_MODULE=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++CONFIG_UBI_BLOCK=y ++# CONFIG_UBIFS_SILENCE_MSG is not set ++# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set ++CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y ++CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7581_w1700k_env" ++CONFIG_SHA512=y +--- /dev/null ++++ b/defenvs/an7581_w1700k_env +@@ -0,0 +1,27 @@ ++loadaddr=0x81800000 ++initaddr=0x89000000 ++ipaddr=192.168.1.1 ++serverip=192.168.1.10 ++bootfile=openwrt-airoha-an7581-gemtek_w1700k-ubi-initramfs-recovery.itb ++installfile=openwrt-airoha-an7581-gemtek_w1700k-ubi-initramfs-installer.itb ++bootled_pwr=status:red ++bootled_rec=status:blue ++boot_ubi=ubi part ubi && run boot_production ; run boot_recovery ++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run ubi_read_recovery ; bootm $initaddr#$bootconf ; led $bootled_rec off ++boot_tftp=tftpboot $initaddr $bootfile && bootm $initaddr#$bootconf ++boot_installer=tftpboot $initaddr $installfile && bootm $initaddr#$bootconf ++bootconf=config-1 ++bootcmd=boot_ubi ++bootdelay=3 ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=3 ++bootmenu_title= 34m( ( ( mOpenWrt34m ) ) ) ++bootmenu_0=Run default boot command.=run boot_production ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot recovery system from flash.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_3=Boot installer via TFTP.=run boot_installer ; run bootmenu_confirm_return ++bootmenu_4=Reboot.=reset ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr ++ubi_read_recovery=ubi check recovery && ubi read $initaddr recovery +--- /dev/null ++++ b/dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts +@@ -0,0 +1,131 @@ ++// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++/dts-v1/; ++ ++/* Bootloader installs ATF here */ ++/memreserve/ 0x80000000 0x200000; ++ ++#include ++#include ++#include "en7581.dtsi" ++ ++/ { ++ model = "Gemtek W1700K (UBI)"; ++ compatible = "gemtek,w1700k-ubi", "airoha,an7581", "airoha,en7581"; ++ ++ aliases { ++ serial0 = &uart1; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ linux,usable-memory-range = <0x0 0x80200000 0x0 0x7fe00000>; ++ }; ++ ++ memory@80000000 { ++ device_type = "memory"; ++ reg = <0x0 0x80000000 0x2 0x00000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ key-restart { ++ label = "reset"; ++ gpios = <&en7581_pinctrl 0 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_status_green { ++ label = "status:green"; ++ gpios = <&en7581_pinctrl 17 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led_status_blue { ++ label = "status:blue"; ++ gpios = <&en7581_pinctrl 19 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led_status_red { ++ label = "status:red"; ++ gpios = <&en7581_pinctrl 29 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led_status_white { ++ label = "status:white"; ++ gpios = <&en7581_pinctrl 20 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++}; ++ ++&snfi { ++ status = "okay"; ++}; ++ ++&spi_nand { ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ vendor@0 { ++ label = "vendor"; ++ reg = <0x00000000 0x00600000>; ++ read-only; ++ }; ++ ++ chainloader@600000 { ++ label = "chainloader"; ++ reg = <0x00600000 0x00100000>; ++ read-only; ++ }; ++ ++ ubi@700000 { ++ label = "ubi"; ++ reg = <0x00700000 0x1f700000>; ++ }; ++ ++ /* reserved for bad block table */ ++ reserved_bmt@1fe00000 { ++ label = "reserved_bmt"; ++ reg = <0x1fe00000 0x00200000>; ++ read-only; ++ }; ++ }; ++}; ++ ++&en7581_pinctrl { ++ gpio-ranges = <&en7581_pinctrl 0 13 47>; ++ ++ pcie0_rst_pins: pcie0-rst-pins { ++ conf { ++ pins = "pcie_reset0"; ++ drive-open-drain = <1>; ++ }; ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_rst_pins>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++}; ++ ++&gdm1 { ++ status = "okay"; ++}; diff --git a/target/linux/airoha/image/an7581.mk b/target/linux/airoha/image/an7581.mk index 497c7acacf..35bfd09a50 100644 --- a/target/linux/airoha/image/an7581.mk +++ b/target/linux/airoha/image/an7581.mk @@ -12,6 +12,33 @@ define Build/an7581-bl31-uboot cat $(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip >> $@ endef +define Build/an7581-chainloader + $(INSTALL_DIR) $(KDIR)/chainload-fit-$(notdir $@) + @if [ -f "$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin.lzma" ]; then \ + KERNEL="$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin.lzma"; \ + COMP="lzma"; \ + else \ + KERNEL="$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin"; \ + COMP="none"; \ + fi; \ + $(TOPDIR)/scripts/mkits.sh \ + -D $(DEVICE_NAME) \ + -o $(KDIR)/chainload-fit-$(notdir $@)/u-boot.its \ + -k $$KERNEL \ + -C $$COMP \ + -a 0x80200000 -e 0x80200000 \ + -c conf-uboot \ + -A arm64 -v u-boot \ + -d $(STAGING_DIR_IMAGE)/an7581_$1-u-boot.dtb \ + -s 0x82000000 + PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) \ + $(STAGING_DIR_HOST)/bin/mkimage \ + -D "-i $(KDIR)/chainload-fit-$(notdir $@)" \ + -f $(KDIR)/chainload-fit-$(notdir $@)/u-boot.its \ + $(STAGING_DIR_IMAGE)/an7581_$1-chainload-u-boot.itb + cat $(STAGING_DIR_IMAGE)/an7581_$1-chainload-u-boot.itb >> $@ +endef + define Device/FitImageLzma KERNEL_SUFFIX := -uImage.itb KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb