Asus TUF AX4200 support

At the moment we aren't using the Asus eeprom calibration data as it can't be read.

@daniel is working on NVMEM support to read the eeprom data from UBI volumes.

I know he sent a PR upstream but not sure if there's any chance he would be upto backporting it to OpenWRT before it gets accepted to Linux mainline.

Somehow we managed to connect the UART (it works strangely with this device).
Now I see how the bootloader swears at the image that I slipped to it using the web interface:

Please choose the operation:
   1: Load System code to SDRAM via TFTP.
   2: Load System code then write to Flash via TFTP.
   3: Boot System code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                                                                 0
   3: Boot System code via Flash (default).

TUF-AX4200 bootloader version: 1.0.0.2
MAC Address: C8:7F:54:78:BB:3E
HwID A
Read 40 bytes from volume linux to 0000000046000000
   FIT/FDT format image found at 0x46000000,size 0x176e6d0
Read 24569592 bytes from volume linux to 0000000046000000
## Loading kernel from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'kernel-1' kernel subimage
     Description:  ARM64 OpenWrt Linux-5.15.134
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x460000ec
     Data Size:    3828481 Bytes = 3.7 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x48000000
     Entry Point:  0x48000000
     Hash algo:    crc32
     Hash value:   97f8d931
     Hash algo:    sha1
     Hash value:   ef8eb4f46fb7374e60d946f54b8b7f6796967a1e
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading ramdisk from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'initrd-1' ramdisk subimage
     Description:  ARM64 OpenWrt asus_tuf-ax4200 initrd
     Type:         RAMDisk Image
     Compression:  Unknown Compression
     Data Start:   0x463a6d2c
     Data Size:    20718272 Bytes = 19.8 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    crc32
     Hash value:   b415a9b1
     Hash algo:    sha1
     Hash value:   2a81a603216028fc1698d550b70c4f56458793cf
   Verifying Hash Integrity ... crc32+ sha1+ OK
WARNING: 'compression' nodes for ramdisks are deprecated, please fix your .its file!
## Loading fdt from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'fdt-1' fdt subimage
     Description:  ARM64 OpenWrt asus_tuf-ax4200 device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x477690f8
     Data Size:    20668 Bytes = 20.2 KiB
     Architecture: AArch64
     Load Address: 0x47000000
     Hash algo:    crc32
     Hash value:   ab5f8197
     Hash algo:    sha1
     Hash value:   23933b076fe071709ca592f8d9e30dff7425a5f6
   Verifying Hash Integrity ... crc32+ sha1+ OK
Error: fdt overwritten
Could not find a valid device tree
2 Likes

Liké a rt3200 ubi version ? I'm Would liké take and test Asus but not uart i Can command but hésit thanks

I don't think so.

It would enable a form of reading eeprom calibration data and MAC addresses.

1 Like

My router refused to restore the system through the official utility Rescue (v2.1.0.3). In the UART log there is an endless wait for requests from the TFTP client.

U-Boot 2022.04-rc1 (Nov 14 2022 - 15:04:49 +0800)
...
TUF-AX4200 bootloader version: 1.0.0.2
MAC Address: C8:7F:54:78:BB:3E
HwID A
reset button pressed!

## Enter Rescue Mode ##
switch prereq:0
tftpd start

Our IP address is:(192.168.1.1)
Wait for TFTP request...
tftpd open
D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D

The TFTPD64 utility was also unable to transfer blocks of data to the bootloader side.
I was very surprised by this.

Here is my method of restoring the system without using recovery mode (i.e. without the reset button):

  1. Run TFTPD64 utility (Base Directory = ".")
  2. Copy the stock trx-image to the directory in which the tftpd64.exe file is located.
  3. Rename trx-image file to "TUF-AX4200.trx"
  4. Reboot device and wait "choose the operation" in UART log.
  5. Press "2"
  6. Are you sure?(Y/N) : type "Y"
  7. Input device IP (192.168.1.1) ==: : press Enter
  8. Input server IP (192.168.1.70) ==: : type our computer IP-addr (or press Enter)
  9. Input Linux Kernel filename (TUF-AX4200.trx) ==: : press Enter
  10. Wait install firmware and load AsusWRT
Please choose the operation:
   1: Load System code to SDRAM via TFTP.
   2: Load System code then write to Flash via TFTP.
   3: Boot System code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.

You choosed 2


   2: Load System code then write to Flash via TFTP.
 Warning!! Erase Linux in Flash then burn new one. Are you sure?(Y/N)
 Please Input new ones /or Ctrl-C to discard
        Input device IP (192.168.1.1) ==:
        Input server IP (192.168.1.70) ==:
        Input Linux Kernel filename (TUF-AX4200.trx) ==:
switch prereq:0
Using ethernet0@15100000 device
TFTP from server 192.168.1.70; our IP address is 192.168.1.1
Filename 'TUF-AX4200.trx'.
Load address: 0x46000000
Loading: Got ARP REPLY, set eth addr (9c:6b:00:02:b5:42)
#################################################################
#################################################################
         5 MiB/s
done
Bytes transferred = 36755380 (230d7b4 hex)
0x230d774 bytes written to volume linux
0x230d774 bytes written to volume linux2
HwID A
## Loading kernel from FIT Image at 46000040 ...
   Using 'config-1' configuration
   Trying 'kernel-1' kernel subimage
     Description:  ARM64 OpenWrt Linux-3.0
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x46000124
     Data Size:    3288768 Bytes = 3.1 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x48080000
     Entry Point:  0x48080000
     Hash algo:    crc32
     Hash value:   0dc36517
     Hash algo:    sha1
     Hash value:   9b71605bb54f25f9cbb7795c18415a61380f6614
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading ramdisk from FIT Image at 46000040 ...
   Using 'config-1' configuration
   Trying 'rootfs-1' ramdisk subimage
     Description:  Root File System
     Type:         RAMDisk Image
     Compression:  Unknown Compression
     Data Start:   0x4632876c
     Data Size:    33442579 Bytes = 31.9 MiB
     Architecture: Unknown Architecture
     OS:           Unknown OS
     Load Address: 0x00000000
     Entry Point:  0x00000000
     Hash algo:    crc32
     Hash value:   1a15e2de
     Hash algo:    sha1
     Hash value:   58961af786578b5e255827d944adf8f0b4eb224b
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 46000040 ...
   Using 'config-1' configuration
   Trying 'fdt-1' fdt subimage
     Description:  ARM64 OpenWrt mt7986a-tuf-ax4200 device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x46323128
     Data Size:    21838 Bytes = 21.3 KiB
     Architecture: AArch64
     Hash algo:    crc32
     Hash value:   1e502b26
     Hash algo:    sha1
     Hash value:   64bcc295d1bef64fd2b4c74e3da4c2172e7432e1
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x46323128
   Uncompressing Kernel Image
   Loading Device Tree to 000000005f7f3000, end 000000005f7fb54d ... OK
volume linux seq: 4

Starting kernel ...

Booting Linux on physical CPU 0x0000000000 [0x410fd034]
Linux version 5.4.182 (root@asus) (gcc version 8.4.0 (OpenWrt GCC 8.4.0 r16530-c6256a6533)) #1 SMP Mon Dec 19 15:29:27 CST 2022
Machine model: TUF-AX4200/TUF-AX4200Q
earlycon: uart8250 at MMIO32 0x0000000011002000 (options '')
printk: bootconsole [uart8250] enabled

Are you sure this rescue mode tries to request anything from your tftp server? It looks like it sets up a tftp server, waiting for you to send a request to it. I.e., you have to push an image to 192.168.1.1.

Is this rescue method documented somewhere by the vendor?

Did you snoop the network traffic while it was active?

EDIT: to answer myself: This seems to be a common rescue method for many Asus routers: https://openwrt.org/toh/asus/rt-n16#oem_installation_using_the_tftp_method

2 Likes

In rescue mode, the TFTPD server starts on the bootloader side.

Yes

When you press the Upload button in Asus Rescue utility, the following appears in the wireshark log:

550	423.655119	ASRockIn_02:b5:42	Broadcast	ARP	42	Who has 192.168.1.49? Tell 192.168.1.10
551	424.629175	ASRockIn_02:b5:42	Broadcast	ARP	42	Who has 192.168.1.49? Tell 192.168.1.10
552	425.618529	ASRockIn_02:b5:42	Broadcast	ARP	42	Who has 192.168.1.49? Tell 192.168.1.10

So the rescue utility and the bootloader disagrees about the rescue server IP?

How about using a stanard tftp client to push an image to the device instead, as documented on https://openwrt.org/toh/asus/rt-n16#oem_installation_using_the_tftp_method
?

UART log:

Our IP address is:(192.168.1.1)
Wait for TFTP request...
tftpd open
D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D Got ARP REQUEST, return our IP

TFTP error: 'timeout on receive' (0)
Starting again

resetting ...

tftp client log:

C:\asus\TUF-AX4200\> tftp -i 192.168.1.1 PUT TUF-AX4200.trx
 connection request failed

WireShark:

47158	3879.578007	ASRockIn_02:b5:42	Broadcast	ARP	42	Who has 192.168.1.1? Tell 192.168.1.10
47159	3879.580733	ASUSTekC_78:bb:3e	ASRockIn_02:b5:42	ARP	60	192.168.1.1 is at c8:7f:54:78:bb:3e
47160	3879.580741	192.168.1.10	192.168.1.1	TFTP	65	Write Request, File: TUF-AX4200.trx, Transfer type: octet
47161	3879.580877	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1
47162	3880.590406	192.168.1.10	192.168.1.1	TFTP	65	Write Request, File: TUF-AX4200.trx, Transfer type: octet
47163	3880.590559	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1
47164	3882.603064	192.168.1.10	192.168.1.1	TFTP	65	Write Request, File: TUF-AX4200.trx, Transfer type: octet
47165	3882.603239	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1
47166	3886.604326	192.168.1.10	192.168.1.1	TFTP	65	Write Request, File: TUF-AX4200.trx, Transfer type: octet
47167	3886.604442	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1
47168	3891.610137	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1
47169	3894.617158	192.168.1.10	192.168.1.1	TFTP	65	Write Request, File: TUF-AX4200.trx, Transfer type: octet
47170	3894.617293	ASUSTekC_78:bb:3e	Broadcast	ARP	60	Who has 192.168.1.70? Tell 192.168.1.1

That's rather unexpected. Maybe the client must use this address?

afaik all that the reset button does is put it into tftp mode

edit: the only way I've found to go back to stock from OpenWRT is from bootloader use these commands:

ubi remove linux
ubi remove jffs2
ubi remove rootfs
ubi remove rootfs_data
ubi create linux 0x45fe000

hold reset button and type reset

Use Asus firmware restoration tool

That's not entirely correct. You are reading it from a userspace script. See target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata

The driver will complain like that, but the caldata is still loaded from the ubi volume and fed to it.

Of course, having support for direct access from the driver to the ubi volume is much better, both allowing this to be described in the DTS and happen at driver probe time.

Hoping we'll see something similar for eMMC too. Not sure how feasible that is. But the unifi-6-plus and other eMMC boards have the same problem.

EDIT: I see @daniel is fixing this as well: https://lkml.org/lkml/2023/7/19/1324 Great!

The wifi phy mac adresses is a related, but slightly different problem. They are loaded separately using the target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac script. Which I currently noticed (on a U6+) is subject to race condiftions. It's possible to slow down the hotplug script processing at boot by adding packages with completely unrelated hotplug scripts, like block-mount etc. This can cause BSSIDs to be confgured before the proper phy mac addresses have been set.

So the UBI NVMEM support is even more important for the mac adresses. But it also depends on solving another issue: AFAICS, there is no way to configure individual mac-addresses for the two phys on a DBDC mt76 radio. Currently, if you configure a "mac-address" nvmem-cell then the exact same address is used for both phys.

1 Like

The thing is that I have not yet installed OpenWRT in UBIFS.
Using AsusWRT, I wrote the kernel+initrd image to the linux1 volume.
Volume linux2 remains unchanged and the bootloader can restore the system from it:

Copy firmware from linux2(c4c0d000) to linux1(c060f000), length 231c34c
0x231c34c bytes written to volume linux
1 Like

@Gingernut

I highly recommend removing this line from the image generation config:

DEVICE_DTS_LOADADDR := 0x47000000

With a large rootfs/initrd size, this address ends up inside the already allocated memory area.

1 Like

I'm not the maintainer.

Pinging @daniel

I was able to create an OpenWRT-iritrd image that is installed via the AsusWRT admin WEB.
But when loading the kernel, the following error occurs:

Read 40 bytes from volume linux2 to 000000005f7ffb90
Copy firmware from linux1(c060f000) to linux2(c4c0d000), length 88024c
0x88024c bytes written to volume linux2
   Uncompressing Kernel Image
   Loading Device Tree to 000000005f7f3000, end 000000005f7fb0bb ... OK
volume linux seq: 4

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.15.134 (user@debian) (aarch64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r23497-6637af95aa) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Mon Oct 9 21:45:35 2023
[    0.000000] Machine model: ASUS TUF-AX4200
...
[    0.000000] Kernel command line: ubi.mtd=UBI_DEV
...
[    0.018155] PCI: CLS 0 bytes, default 64
[    0.038875] workingset: timestamp_bits=46 max_order=17 bucket_order=0
...
[    5.759482] ubi0: max/mean erase counter: 6/4, WL threshold: 4096, image sequence number: 1864024255
[    5.768591] ubi0: available PEBs: 0, total reserved PEBs: 2016, PEBs reserved for bad PEB handling: 38
[    5.777880] ubi0: background thread "ubi_bgt0d" started, PID 472
[    5.784157] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[    5.791624] Please append a correct "root=" boot option; here are the available partitions:
[    5.799964] 1f00            4096 mtdblock0
[    5.799968]  (driver?)
[    5.806477] 1f01          258048 mtdblock1
[    5.806479]  (driver?)
[    5.812993] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[    5.821232] SMP: stopping secondary CPUs
[    5.825139] Kernel Offset: disabled
[    5.828609] CPU features: 0x0,00000000,20000802
[    5.833122] Memory Limit: none
[    5.837715] Rebooting in 1 seconds..

If the same image is loaded using the bootm command, then this error does not occur:

   Booting using the fdt blob at 0x4687ac5c
   Uncompressing Kernel Image
   Loading Ramdisk to 5f318000, end 5f7fa1b0 ... OK
   Loading Device Tree to 000000005f30f000, end 000000005f3170bb ... OK
volume linux seq: 4

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.15.134 (user@debian) (aarch64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r23497-6637af95aa) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Mon Oct 9 21:45:35 2023
[    0.000000] Machine model: ASUS TUF-AX4200
...
[    0.000000] Kernel command line: ubi.mtd=UBI_DEV
...
[    0.018155] PCI: CLS 0 bytes, default 64
[    0.018300] Unpacking initramfs...
[    0.038875] workingset: timestamp_bits=46 max_order=17 bucket_order=0
...
[    6.044904] ubi0: max/mean erase counter: 6/4, WL threshold: 4096, image sequence number: 1864024255
[    6.054012] ubi0: available PEBs: 0, total reserved PEBs: 2016, PEBs reserved for bad PEB handling: 38
[    6.063303] ubi0: background thread "ubi_bgt0d" started, PID 469
[    6.069584] Freeing unused kernel memory: 448K
[    6.097045] Run /init as init process
[    6.100691]   with arguments:
[    6.103641]     /init
[    6.105899]   with environment:
[    6.109028]     HOME=/
[    6.111372]     TERM=linux
[    6.278267] init: Console is alive
[    6.281745] init: - watchdog -

That is, for some reason the OpenWRT kernel wants to mount the system not from the initrd, but from flash memory (UBIFS).

3 Likes

I still managed to create a working OpenWRT-initrd image that loads normally into the device’s memory.
Download: https://drive.google.com/drive/folders/172Kyopi-ioart97Pcxtdp0cVz-P1uLcS?usp=sharing
This trx-image must be installed through the stock AsusWRT WEB-panel.
After installation, you need to change your IP-address to 192.168.1.1 and logon into OpenWRT LUCI.
Finally, you need to install the sysupgrade OpenWRT image.

4 Likes

Great work.

Would you have any idea how we could returning to OEM firmware from OpenWRT without the need for a serial connection?

Does it meann You can flash device without usb to ttl and opening device straight from Asus original software?

Could you share the repo with source code and minimal README ?

2 Likes