]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
econet: en751221: add support for Huawei HG2821T-U 23131/head
authorDavid Yang <mmyangfl@gmail.com>
Mon, 27 Apr 2026 15:46:19 +0000 (23:46 +0800)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 14 May 2026 18:52:09 +0000 (20:52 +0200)
This patch adds support for Huawei HG2821T-U, EPON ONU and home router,
often comes with ISP service.

Specifications
==============
* SoC: Econet EN7526GT
* RAM: 512MiB DDR3L (MT41K256M16TW-107)
* Flash: 256MiB SPI NAND (TC58CVG1S3HRAIG)
* WiFi 2.4GHz: MT7592N
* WiFi 5GHz: MT7612EN
* Ethernet: builtin switch
* LED: Power, Internet, WiFi, USB
* Buttons: Reset
* UART: Serial console (115200 8n1)
* USB: 1 x USB2
* Other: Phone jack, XPON fiber port

!!! BACKUP YOUR ROM !!!
=======================
Please always have your FULL flash image backup before flashing
anything. The vendor firmware varies a lot depending on your ISP and
location. You will have a hard time finding the right regional firmware
if you don't have a backup.

Notes
=====
* Due to the target `econet` being incomplete, WiFi, DSA switch, and
many other features are not supported yet. Do not flash the image unless
you know the consquences or `econet` is declared stable.
* This device, and apparently many other devices of this platform, use
a dual-image layout. OpenWRT (with `econet` target) only uses slot A.
Slot B is not used by OpenWRT, and is applicable for dual-booting to
vendor firmware.
* If you do not use vendor firmware anymore, you can erase and reuse
anything after `configuration_b`, which gives you ~110 MiB free space.
Again, backup your flash first.

Installation
============
Within shell
------------
Note that acquiring the shell access to the vendor firmware can be a bit
tricky depending on the firmware variation. If you can't play with the
vendor firmware, boot to OpenWrt using debricking method below.

0. (Optional) Back up your flash, and / or move the vendor firmware to
   slot B
1. Build and then locate the `kernel.bin` and `rootfs.bin` image files
2. Upload `kernel.bin` and `rootfs.bin` to the device (via HTTP or USB
   stick), then type:
   ```
   mtd write -f -e KernelA kernel.bin KernelA
   mtd erase RootfsA
   mtd write -f -r -e AppA rootfs.bin AppA
   ```

From bootloader
---------------
1. Build and then locate the `kernel.bin` and `rootfs.bin` image files
2. Switch device on and press a key within 3 seconds
3. Upload `kernel.bin` via TFTP as described below
4. Once the transfer has completed successfully, bootloader will give
   you the file length in "Total %d (0x%X) bytes received", then type
   `flash 200000 80020000 <file length hex>`
5. Upload `rootfs.bin` then flash with
   `flash 600000 80020000 <file length hex>`
6. Restart the device to boot into OpenWRT

> [!IMPORTANT]
> Do not try `httpd` in the bootloader. It writes to the wrong address
  and will corrupt the flash.

Debricking
==========
1. Build and then locate the `initramfs-kernel.bin` image files
2. Switch device on and press a key within 3 seconds
3. Connect to device via ethernet, set the IP address to `192.168.1.X`,
   then upload the image via TFTP
   `tftp 192.168.1.1 -m binary -v -c put initramfs-kernel.bin`

   The file name can be anything except `tcboot.bin` or `tclinux.bin`,
   they will corrupt the flash.
4. Type `jump 80020000` to boot the kernel from memory

Dual boot
=========
Use `en75_chboot` tool to switch between vendor firmware and OpenWrt. If
you are soft-locked, you can also switch the flag in the bootloader:
1. Switch device on and press a key within 3 seconds
2. Select the kernel that you wish to use:
   - `memwl 80020000 30ffffff` for `KernelA` (OpenWrt)
   - `memwl 80020000 31ffffff` for `KernelB` (Factory)
3. Select the rootfs, which should be the same as the kernel:
   - `memwl 80020004 30ffffff` for `RootfsA` (OpenWrt)
   - `memwl 80020004 31ffffff` for `RootfsB` (Factory)
3. Commit the data to flash: `flash 1e0000 80020000 8`
4. Restart the device to boot into the selected OS

MAC addresses
=============
`//configuration_a/factory.conf` contains MAC addresses, along with
other pre-configured settings. OpenWrt uses `brmac`, `internetmac`,
`APMAC`, and `APMAC_5G`, while `tr069mac`, `voipmac`, `priprotocolmac`,
and `PONMac` are not used for now.

Signed-off-by: David Yang <mmyangfl@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23131
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/econet/base-files/etc/board.d/02_network [new file with mode: 0644]
target/linux/econet/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac [new file with mode: 0755]
target/linux/econet/base-files/lib/preinit/09_mount_factory_data [new file with mode: 0644]
target/linux/econet/base-files/sbin/en75_chboot
target/linux/econet/dts/en751221_huawei_hg2821t-u.dts [new file with mode: 0644]
target/linux/econet/en751221/config-6.12
target/linux/econet/image/Makefile
target/linux/econet/image/en751221.mk

diff --git a/target/linux/econet/base-files/etc/board.d/02_network b/target/linux/econet/base-files/etc/board.d/02_network
new file mode 100644 (file)
index 0000000..e27926d
--- /dev/null
@@ -0,0 +1,43 @@
+. /lib/functions/system.sh
+. /lib/functions/uci-defaults.sh
+
+econet_setup_interfaces()
+{
+       local board="$1"
+
+       case "$board" in
+       *)
+               # econet lacks DSA support now
+               ucidef_set_interface_lan "eth0"
+               ;;
+       esac
+}
+
+econet_setup_macs()
+{
+       local board="$1"
+       local lan_mac=""
+       local wan_mac=""
+       local label_mac=""
+
+       case "$board" in
+       huawei,hg2821t-u)
+               local conffile="/tmp/configuration_a/factory.conf"
+               lan_mac=$(get_mac_ascii "$conffile" brmac)
+               wan_mac=$(get_mac_ascii "$conffile" internetmac)
+               label_mac=$wan_mac
+               ;;
+       esac
+
+       [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" "$lan_mac"
+       [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" "$wan_mac"
+       [ -n "$label_mac" ] && ucidef_set_label_macaddr "$label_mac"
+}
+
+board_config_update
+board=$(board_name)
+econet_setup_interfaces $board
+econet_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/econet/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/econet/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
new file mode 100755 (executable)
index 0000000..b479abe
--- /dev/null
@@ -0,0 +1,17 @@
+[ "$ACTION" = "add" ] || exit 0
+
+PHYNBR=${DEVPATH##*/phy}
+
+[ -n "$PHYNBR" ] || exit 0
+
+. /lib/functions/system.sh
+
+board=$(board_name)
+
+case "$board" in
+huawei,hg2821t-u)
+       conffile="/tmp/configuration_a/factory.conf"
+       [ "$PHYNBR" -eq 0 ] && get_mac_ascii "$conffile" APMAC_5G > /sys${DEVPATH}/macaddress
+       [ "$PHYNBR" -eq 1 ] && get_mac_ascii "$conffile" APMAC > /sys${DEVPATH}/macaddress
+       ;;
+esac
diff --git a/target/linux/econet/base-files/lib/preinit/09_mount_factory_data b/target/linux/econet/base-files/lib/preinit/09_mount_factory_data
new file mode 100644 (file)
index 0000000..a6e553b
--- /dev/null
@@ -0,0 +1,18 @@
+preinit_mount_factory_data() {
+       local mtd_path=$(find_mtd_part "$1")
+
+       [ -n "$mtd_path" ] || return
+
+       mkdir -p "/tmp/$1"
+       mount -o ro,noatime -t jffs2 "$mtd_path" "/tmp/$1"
+}
+
+preinit_mount_factory_partitions() {
+       case $(board_name) in
+       huawei,hg2821t-u)
+               preinit_mount_factory_data configuration_a
+               ;;
+       esac
+}
+
+boot_hook_add preinit_main preinit_mount_factory_partitions
index a582d64a5d61b0ce18d7993c59223c6f217514c9..57ba961ba9941c27c408bfe7a9d1bfd9607bff8e 100755 (executable)
@@ -111,6 +111,14 @@ main() {
         code_openwrt=0000000101000002
         code_factory=0000000101010003
         ;;
+    huawei,hg2821t-u)
+        part=$(part_named '"flag"')
+        offset_blocks=14
+        block_size=$((1024 * 128))
+        code_offset=0
+        code_openwrt=30ffffff30ffffff
+        code_factory=31ffffff31ffffff
+        ;;
     nokia,g240g-e)
         part=$(part_named '"flag"')
         offset_blocks=0
diff --git a/target/linux/econet/dts/en751221_huawei_hg2821t-u.dts b/target/linux/econet/dts/en751221_huawei_hg2821t-u.dts
new file mode 100644 (file)
index 0000000..b60a272
--- /dev/null
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+#include "en751221.dtsi"
+
+/ {
+       model = "Huawei HG2821T-U";
+       compatible = "huawei,hg2821t-u", "econet,en751221";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x1c000000>;
+       };
+
+       chosen {
+               stdout-path = "/serial@1fbf0000:115200";
+               bootargs = "ubi.mtd=rootfs_a";
+       };
+};
+
+&nand {
+       status = "okay";
+       econet,bmt;
+
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0x0 0x20000>;
+                       read-only;
+               };
+
+               partition@20000 {
+                       label = "flag";
+                       reg = <0x20000 0x1e0000>;
+                       econet,enable-remap;
+               };
+
+               partition@200000 {
+                       label = "kernel_a";
+                       reg = <0x200000 0x400000>;
+                       econet,enable-remap;
+               };
+
+               partition@600000 {
+                       label = "rootfs_a";
+                       reg = <0x600000 0x3800000>;
+                       econet,boot-flag-value = <0>;
+               };
+
+               partition@3e00000 {
+                       label = "kernel_b";
+                       reg = <0x3e00000 0x400000>;
+                       econet,enable-remap;
+               };
+
+               partition@4200000 {
+                       label = "rootfs_b";
+                       reg = <0x4200000 0x3800000>;
+                       econet,boot-flag-value = <1>;
+               };
+
+               partition@7a00000 {
+                       label = "configuration_a";
+                       reg = <0x7a00000 0x200000>;
+                       read-only;
+               };
+
+               partition@7c00000 {
+                       label = "configuration_b";
+                       reg = <0x7c00000 0xa00000>;
+                       econet,enable-remap;
+               };
+
+               partition@8600000 {
+                       label = "userlocalct";
+                       reg = <0x8600000 0x400000>;
+                       econet,enable-remap;
+               };
+
+               partition@8a00000 {
+                       label = "userdata";
+                       reg = <0x8a00000 0x600000>;
+                       econet,enable-remap;
+               };
+
+               partition@9000000 {
+                       label = "framework1";
+                       reg = <0x9000000 0x800000>;
+                       econet,enable-remap;
+               };
+
+               partition@9800000 {
+                       label = "framework2";
+                       reg = <0x9800000 0x800000>;
+                       econet,enable-remap;
+               };
+
+               /* UBI */
+               partition@a000000 {
+                       label = "apps";
+                       reg = <0xa000000 0x4a00000>;
+               };
+
+               partition@ea00000 {
+                       label = "reservearea";
+                       reg = <0xea00000 0x100000>;
+                       econet,enable-remap;
+               };
+       };
+};
+
+&gmac0 {
+       status = "okay";
+};
index d68d0ca44d17af338056bcc42ff5df92f83fa242..fe69f10c74b87a7412205caf4c4bf64cf0c47ce4 100644 (file)
@@ -91,7 +91,8 @@ CONFIG_IRQ_DOMAIN_HIERARCHY=y
 CONFIG_IRQ_FORCED_THREADING=y
 CONFIG_IRQ_MIPS_CPU=y
 CONFIG_IRQ_WORK=y
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_ZLIB=y
 CONFIG_LIBFDT=y
 CONFIG_LOCK_DEBUGGING_SUPPORT=y
 CONFIG_LZO_COMPRESS=y
index 2d96d1374794be6c3bd05cb99894cae76aa8d306..a496a0891eeec2d55ab8c17b842c57f2091d58ff 100644 (file)
@@ -13,14 +13,35 @@ define Build/tclinux-trx
        mv $@.new $@
 endef
 
+# If TCSUPPORT_FREE_BOOTBASE is enabled, bootloader will decompress the kernel
+# at 0x80002000 instead of 0x80020000.
+#
+# You can tell it by looking at the bootloader version string
+# " at %s version %s free bootbase".
+define Build/tclinux-free-bootbase-jump
+       @[ "$(KERNEL_LOADADDR)" = 0x80020000 ] || { \
+               $(call ERROR_MESSAGE,WARNING: KERNEL_LOADADDR changed); \
+               rm -f $@; \
+       }
+       printf '\010\000\200\000' > $@.new
+       dd if=/dev/zero bs=122876 count=1 >> $@.new
+       cat $@ >> $@.new
+       mv $@.new $@
+endef
+
 # tclinux bootloader requires LZMA, BUT only provides 7.5MB of space
 # to decompress into. So we use vmlinuz and decompress twice.
 define Device/Default
   DEVICE_DTS_DIR := ../dts
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  # decompression buffer limit, the size of LZMA-compressed data is read from
+  # the trx header
   KERNEL_SIZE := 7480k
   KERNEL_NAME := vmlinuz.bin
   KERNEL_LOADADDR := 0x80020000
   KERNEL := kernel-bin | append-dtb
+  UBINIZE_OPTS := -E 5
 endef
 
 include $(SUBTARGET).mk
index 89fc0bdee2a865c19b5665afab3912a03fd7b393..13b8de4ddc6b680769a072df6f82d831c5bdeb23 100644 (file)
@@ -9,6 +9,26 @@ define Device/en751221_generic
 endef
 TARGET_DEVICES += en751221_generic
 
+define Device/huawei_hg2821t-u
+  DEVICE_VENDOR := Huawei
+  DEVICE_MODEL := HG2821T-U
+  DEVICE_DTS := en751221_huawei_hg2821t-u
+  KERNEL_DECOMPRESSED_SIZE := 7672k
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 57344k
+  FACTORY_SIZE := 40960k
+  NAND_SIZE := 256m
+  KERNEL := kernel-bin | append-dtb | tclinux-free-bootbase-jump | \
+    check-size $$(KERNEL_DECOMPRESSED_SIZE) | lzma
+  KERNEL_INITRAMFS := kernel-bin | append-dtb
+  IMAGES := kernel.bin rootfs.bin sysupgrade.bin
+  IMAGE/kernel.bin := append-kernel
+  IMAGE/rootfs.bin := append-ubi | check-size $$(FACTORY_SIZE)
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  DEVICE_PACKAGES := kmod-usb3
+endef
+TARGET_DEVICES += huawei_hg2821t-u
+
 define Device/nokia_g240g-e
   DEVICE_VENDOR := Nokia
   DEVICE_MODEL := G-240G-E