Adding OpenWrt support for Xiaomi AX3600 (Part 1)

I tested "ath11k: backport RX decap offload" but can't measure any difference in CPU usage.
In all firmware versions tested "restart", "backports" and "castiel652:ath11k-decap" with frame_mode=2 and without I am getting about 46% sirq usage at 790Mbits/sec iperf3 upload from phone to LAN server.

And still can't understand how in "backports" branch this speed drops to 0 at about 3 meters from router.

One of the major changes in the backport branch was the mac80211 update to 5.15 which could have something to do with it.

btw, @robimarko, how do you think, maybe it is worth to rework uboot config a bit and merge both "rootfs" partitions together before merging IPQ...-backports back in OpenWRT repo?

Anyway I didn't find any way to make it to boot from another partition without access to the booted system or manual intervention through UART.
So this "duplcation" seems pretty useless, if swithing boot partition is only possible through UART and booted system, but it "eats" 35M, which can be used to increase the space available for flashing custom rootfs, and leave remaining for overlay.

// btw, as far as I calculated, for now overlay partition have size of ~30M (0x01ec0000 == 32243712, dividing it to 1024^2 gives 30.75), but df -h on image from /releases says it is only 15.1M O_o

UPD: Btw, I've also summed all the sizes from /proc/mtd and result is 112.75M, while spec AX3600 page on Wiki says there should be 256M.
So, it seems too big space is disappeared to blame it on inaccuracies of all the kind :man_shrugging:
(and even if there is a typo and real flash size is 128M, then 15M (128-113) is still too big amount (~10%) to blame it on inaccuracies :man_shrugging:

BTW kernel will print the NAND size during boot, it should be 256MB in total.

Look, you are free to rework the upgrade logic to utilize overlay as well and make a PR.
You cant change the U-boot behavior easily as it reads the partition table exclusively from MIBIB.
Also, you can use fw_printenv/fw_setenv to change U-boot variables and toggle partition from which to boot.

Also, you can use fw_printenv/fw_setenv to change U-boot variables and toggle partition from which to boot.

Yeah, if I do have access to booted system.

And in case if it kinda booted (blue LED), but it doesn't respond no any network stuff (even pings) after flashing, and there is no soldered wires on UART pins, there is no way to make it switch the boot partition, as far as I looked the things on the internets...

So, it doesn't look like useful thing, if it doesn't protect from unsuccessfull upgrade/reflash, and you can only switch the partitions by entering commands.

So, I considering second rootfs as useless waste of space (or a toy for lovers of dualbooting with multiple firmwares).

Or, maybe it should be possible to make (or it already exist, but I failed to find a mention about it) some trigger for U-boot to react on pressing reset button in some pattern, to switch the partitions...

I seriously don't get how would you add a trigger for U-boot without recompiling from the source.

Well, yeah you need a booted system, otherwise, only a bootloader with decent logic can protect you by switching to the second rootfs.
This is probably half-implemented by Xiaomi, but still dual-fw is not something you get rid of just like that because you personally dont like it.

afaik they use some type of watchdog that sets the bit if the system can't bootup.... we can consider adding something like that but really not a priority....

(btw this thing can write tons of data on kernel crash in the rpm logs so i assume they use that to understand if the system is in a crashing state or not.... using some type of preinit script)

but still dual-fw is not something you get rid of just like that because you personally dont like it.

Well, you're right, but... well, actually, it is just frustration about having so little space to fill it with useful software, after buying device with such a big flash (and no USB!).

// btw, I just looked in dmesg and found this:

[    1.114356] nand: device found, Manufacturer ID: 0xc8, Chip ID: 0xaa
[    1.115768] nand: ESMT GD9FS2G8F2A
[    1.122371] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 128

So, it is really 256M flash, but... Where all of that space?

Btw, it is intersted, that looking in bootlog on wiki, gives that:

[    1.291965] nand: Winbond W29N02GZ
[    1.298422] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64

which makes me think like they solder random flashes on random devices O_o

They most likely changed the NAND with a compatible one they could get due to shortage, thankfully ONFI NAND is interchangeable as long as the block size and ECC settings are the same.

Can you copy/paste the partitions from dmesg so I dont have to search for them?

yeah, sure:

[    1.114356] nand: device found, Manufacturer ID: 0xc8, Chip ID: 0xaa
[    1.115768] nand: ESMT GD9FS2G8F2A
[    1.122371] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 128
[    1.125827] 16 qcomsmem partitions found on MTD device qcom_nand.0
[    1.133126] Creating 16 MTD partitions on "qcom_nand.0":
[    1.139373] 0x000000000000-0x000000100000 : "0:sbl1"
[    1.146049] 0x000000100000-0x000000200000 : "0:mibib"
[    1.150938] 0x000000200000-0x000000500000 : "0:qsee"
[    1.157319] 0x000000500000-0x000000580000 : "0:devcfg"
[    1.160530] 0x000000580000-0x000000600000 : "0:rpm"
[    1.165495] 0x000000600000-0x000000680000 : "0:cdt"
[    1.170268] 0x000000680000-0x000000700000 : "0:appsblenv"
[    1.175148] 0x000000700000-0x000000800000 : "0:appsbl"
[    1.181027] 0x000000800000-0x000000880000 : "0:art"
[    1.185719] 0x000000880000-0x000000900000 : "bdata"
[    1.190502] 0x000000900000-0x000000980000 : "crash"
[    1.195345] 0x000000980000-0x000000a00000 : "crash_syslog"
[    1.200198] 0x000000a00000-0x000002dc0000 : "rootfs"
[    1.209146] random: fast init done
[    1.232540] mtd: device 12 (rootfs) set to be root filesystem
[    1.232812] mtdsplit: no squashfs found in "rootfs"
[    1.237280] 0x000002dc0000-0x000005180000 : "rootfs_1"
[    1.268488] 0x000005180000-0x000007040000 : "overlay"
[    1.291391] 0x000007040000-0x0000070c0000 : "rsvd0"

// and yeah, I already calculated, 0x0000070c0000 == 118226944 == 112.75M :man_shrugging:

Thanks, yeah I completely forgot that the stock partition table only utilizes less than the half of NAND.
But this is kind of good as it means that we can just add one or two RW rootfs partitions and only keep kernel in the rootfs and rootfs_1 partitions

Or something similar, just to actually utilize the full NAND

When making any changes don't forget AX6 has only half memory. And now it has exactly same partitions

[    0.700656] nand: device found, Manufacturer ID: 0xc8, Chip ID: 0x61
[    0.702170] nand: ESMT PSR1GA30DT
[    0.708767] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    0.712211] 16 qcomsmem partitions found on MTD device qcom_nand.0
[    0.719429] Creating 16 MTD partitions on "qcom_nand.0":
[    0.725589] 0x000000000000-0x000000100000 : "0:sbl1"
[    0.732440] 0x000000100000-0x000000200000 : "0:mibib"
[    0.737320] 0x000000200000-0x000000500000 : "0:qsee"
[    0.744021] 0x000000500000-0x000000580000 : "0:devcfg"
[    0.746832] 0x000000580000-0x000000600000 : "0:rpm"
[    0.751782] 0x000000600000-0x000000680000 : "0:cdt"
[    0.756572] 0x000000680000-0x000000700000 : "0:appsblenv"
[    0.761445] 0x000000700000-0x000000800000 : "0:appsbl"
[    0.767410] 0x000000800000-0x000000880000 : "0:art"
[    0.772038] 0x000000880000-0x000000900000 : "bdata"
[    0.776786] 0x000000900000-0x000000980000 : "crash"
[    0.781671] 0x000000980000-0x000000a00000 : "crash_syslog"
[    0.786515] 0x000000a00000-0x000002dc0000 : "rootfs"
[    0.796243] random: fast init done
[    0.823555] mtd: device 12 (rootfs) set to be root filesystem
[    0.823900] mtdsplit: no squashfs found in "rootfs"
[    0.828299] 0x000002dc0000-0x000005180000 : "rootfs_1"
[    0.865200] 0x000005180000-0x000007040000 : "overlay"
[    0.892992] 0x000007040000-0x0000070c0000 : "rsvd0"

why o.O they don't trust the quality of the nand for bad blocks?

Actually, @tomakava's comment made me think it is because of firmware unification :man_shrugging:

Yeah, probably recycling code with the lowest common denominator being AX6 here.
This is that AX6 can remain the same, it can have its own upgrade method.

@Ansuel I doubt it, most likely just reusing the same bootloader and code as in AX6

aaaaargh! it did it again!
I just sysupgrade'd /release image to the one I've just built using config from .github/workflow as base + added some additional packages, and it again doesn't respond on pings or anything network related. It don't even asks for DHCP on WAN!

I'm totally frustrated and can't understand neither how, nor why?

// still I'm not ready to solder UART on it to take a look in the bootlog, since it is not even a single week left from the day when I bought it and it is still chances I'll return it :angry: (and anyway I have no 1.8v capable USB-TTL adapter yet (just ordered it on Ali), but only bunch of 5v/3v ones).

btw, I'm again on old-stock and just looked for their two-partitions magic, and it still looks strange and incomplete, but @Ansuel's idea of making watchdog in pre-init script (assuming kernel will start fine and will normally run initramfs) looks promising.

intersting part of Xiaomi magic:

/etc/init.d/key_services_boot_check:    local system_current=$(nvram get flag_boot_rootfs)
/etc/init.d/key_services_boot_check:    nvram set flag_try_sys$(($system_current+1))_failed=1
/etc/init.d/key_services_boot_check:    nvram set flag_ota_reboot=0
/etc/init.d/key_services_boot_check:    nvram set flag_recover_config=1
/etc/init.d/boot_check: upgrad_flag=`nvram get flag_upgrade_push`
/etc/init.d/boot_check:         nvram set flag_show_upgrade_info=1
/etc/init.d/boot_check:         nvram unset flag_upgrade_push
/etc/init.d/boot_check:        flg_init_pwd=`nvram get flag_init_root_pwd`
/etc/init.d/boot_check:                nvram unset flag_init_root_pwd
/etc/init.d/boot_check: nvram set flag_ota_reboot=0
/etc/init.d/boot_check: nvram set flag_boot_success=1
/etc/init.d/boot_check: nvram set flag_try_sys1_failed=0
/etc/init.d/boot_check: nvram set flag_try_sys2_failed=0
/etc/init.d/boot_check: local system_current=$(nvram get flag_boot_rootfs)
/etc/init.d/boot_check:         nvram set flag_last_success=$system_current

and here is the whole code of that files:

2 Likes

yes i remember something like that as i reversed the logic at times with the dual partition selection by the bl

1 Like

I need help. Please.
I totally can't understand what's going on that my AX3600 doesn't properly boots up with self-built firmware.

  1. I'm git-cloning IPQ-backports branch of @robimarko's repo. (git clone ... -b IPQ.....)
  2. I'm looking in https://github.com/robimarko/openwrt/blob/IPQ807x-5.10-backports/.github/workflows/ipq807x.yaml and just copypasting all the commands from run sections...

// actually, initially I tryied to build images with software and kernel modules I need, like I usually did with other routers, but having the same problem, so I decided to do EXACTLY what happens in CI when "working" image builds

  1. I'm getting the images (factory and sysupgrade) about ~11M.

There is two scenarios I trying next:

==================

4a) I'm scp'ing factory image to /tmp on old-factory FW, checking md5sum of the file, and doing

ubiformat /dev/mtd1{2,3} -f /tmp/openwrt-ipq807x-generic-xiaomi_ax3600-squashfs-nand-factory.ubi -s 2048 -O 2048
nvram set flag_last_success={1,0}
nvram set flag_boot_rootfs={1,0}
nvram commit
reboot

==================

4b.0) I'm downloading ax3600 image from /releases on repo, doing all the same like in 4a, but using downloaded factory image
4b.1) router boots perfectly (!)
4b.2) I'm scp'ing sysupgrade image on router (which uses 192.168.1.1 as expected), and doing sysupgrade -n /tmp/openwrt-ipq807x-generic-xiaomi_ax3600-squashfs-nand-sysupgrade.bin

==================

After any of that, I anyway leading to:

  1. router rebooting, behaving like it is all "okay": blinks yellow "system" led, then enables the blue "system" led, like it finished booting, but actually it looks like it has totally disabled network on all the interfaces:
  • it doesn't respond to DHCP requests on LAN
  • doesn't request anything with DHCP on WAN
  • totally ignores pings/curl/whatever on 192.168.1.1 (which it should use) and even on 192.168.31.1 (as in stock), end even on 192.168.0.1 (just in case).

Although, it do respond on long pressing "reset" button and reboots (but it doesn't help at all).

=========

I did it many times already and it doesn't want to boot with my images, despite of they should be identical internally :man_shrugging:

Please, help me! I'm totally out of ideas already...

looks like problem is in missing nss_packages feed that I overlooked in in-repo feeds.conf.default (although, doesn't default and not having cp/mv'ing that file in workflow.yaml mentioned means it should be applied automatically?..