OpenWrt support for Xiaomi AX9000

hello

I finally installed the KMods after Robi released his latest update, and installed the tethering packages for iphone and it worked, but i have one problem and its that i only get 90 to 100 mbps because the usb connects as usb2 not usb3, tried and uninstalled usb2 kmod packages but still the same, is there any workaround to fix that?
as i know usb2 is capable of 480mbps speed but i only get around 90mbps thats why i think usb2 may not be the only cause.

and here is the log u see that i have usb with two speeds 480 and 5000 and it chooses the slower one by default, but when i connect through the computer i get around 700mbps using iperf speed test but on AX9000 i get around 90 to 100 using iperf

root@OpenWrt:~# cat /sys/kernel/debug/usb/devices

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1

B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0

D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1

P: Vendor=1d6b ProdID=0002 Rev= 5.15

S: Manufacturer=Linux 5.15.85 xhci-hcd

S: Product=xHCI Host Controller

S: SerialNumber=xhci-hcd.1.auto

C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA*

I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub*

E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms

T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=480 MxCh= 0

D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 4

P: Vendor=05ac ProdID=12a8 Rev=14.03

S: Manufacturer=Apple Inc.

S: Product=iPhone

S: SerialNumber=********************

C: #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=500mA

I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=

E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=64ms

C: #Ifs= 3 Cfg#= 2 Atr=c0 MxPwr=500mA

I: If#= 0 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=00 Driver=

I: If#= 1 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=00 Driver=

I: If#= 1 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=

E: Ad=81(I) Atr=01(Isoc) MxPS= 192 Ivl=1ms

I: If#= 2 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=

E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=125us

C: #Ifs= 2 Cfg#= 3 Atr=c0 MxPwr=500mA

I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=

E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=64ms

I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=fe Prot=02 Driver=

E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

C: #Ifs= 3 Cfg#= 4 Atr=c0 MxPwr=500mA*

I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=(none)*

E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=64ms

I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=fe Prot=02 Driver=usbfs*

E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

I: If#= 2 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=fd Prot=01 Driver=ipheth

I: If#= 2 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=fd Prot=01 Driver=ipheth*

E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

I: If#= 2 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=fd Prot=01 Driver=ipheth

E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=5000 MxCh= 1

B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0

D: Ver= 3.00 Cls=09(hub ) Sub=00 Prot=03 MxPS= 9 #Cfgs= 1

P: Vendor=1d6b ProdID=0003 Rev= 5.15

S: Manufacturer=Linux 5.15.85 xhci-hcd

S: Product=xHCI Host Controller

S: SerialNumber=xhci-hcd.1.auto

C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA*

I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub*

E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms

autocore and few other things

pm me bro..my fw img can support usb tethering usb 3.0 and usb 2.0..using 5g phone as usb tethering to ax9000 can reach 500Mbps+++

1 Like

Robimarko is now sharing a nonshared packages repository feed, available for releases of its experimental firmware, on 26-12-2022 and onwards.

Was also added on the wiki supporting activities: https://openwrt.org/inbox/toh/xiaomi/ax9000#supporting_activities

A much appreciated service for those who don't have the resources or knowledge to get their hands on a self-compiled fully featured firmware image. :+1:

2 Likes

Single rootfs has been pushed, please check:

1 Like

Works! Very nice. :grinning:

I have the International version of AX9000.

I have followed the instructions about extending the partitions in Robi's repo. After the reboot no ethernet interfaces are active and I have to get back to OEM fw with tftp.

I have used the
nvram set atf="1"
nvram commit
(avoid the secureboot)

Any extended partition succes stories with International version ?
Do we need a special version with secureboot avoidance code for international version ?
Help really appreciated.

It should be exactly the same plus the atf trick

What am I doing wrong ?

root@XiaoQiang:~# nvram get flag_boot_rootfs
0
root@XiaoQiang:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00020000 "0:SBL1"
mtd1: 00100000 00020000 "0:MIBIB"
mtd2: 00080000 00020000 "0:BOOTCONFIG"
mtd3: 00080000 00020000 "0:BOOTCONFIG1"
mtd4: 00300000 00020000 "0:QSEE"
mtd5: 00300000 00020000 "0:QSEE_1"
mtd6: 00080000 00020000 "0:DEVCFG"
mtd7: 00080000 00020000 "0:DEVCFG_1"
mtd8: 00080000 00020000 "0:APDP"
mtd9: 00080000 00020000 "0:APDP_1"
mtd10: 00080000 00020000 "0:RPM"
mtd11: 00080000 00020000 "0:RPM_1"
mtd12: 00080000 00020000 "0:CDT"
mtd13: 00080000 00020000 "0:CDT_1"
mtd14: 00080000 00020000 "0:APPSBLENV"
mtd15: 00100000 00020000 "0:APPSBL"
mtd16: 00100000 00020000 "0:APPSBL_1"
mtd17: 00080000 00020000 "0:ART"
mtd18: 00080000 00020000 "bdata"
mtd19: 00080000 00020000 "crash"
mtd20: 00080000 00020000 "crash_syslog"
mtd21: 03800000 00020000 "rootfs"
mtd22: 03800000 00020000 "rootfs_1"
mtd23: 00100000 00020000 "cfg_bak"
mtd24: 07d80000 00020000 "overlay"
mtd25: 005ef000 0001f000 "kernel"
mtd26: 02017000 0001f000 "ubi_rootfs"
mtd27: 00ae6000 0001f000 "rootfs_data"
mtd28: 03013000 0001f000 "data"
root@XiaoQiang:~# nvram get atf
1
root@XiaoQiang:~# ubiformat /dev/mtd22 -y -f /tmp/openwrt-ipq807x-generic-xiaomi
_ax9000-initramfs-factory.ubi -s 2048 -O 2048 && nvram set flag_boot_rootfs=1 &&
 nvram set flag_last_success=1 && nvram commit
ubiformat: mtd22 (nand), size 58720256 bytes (56.0 MiB), 448 eraseblocks of 1310                                                   72 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 447 -- 100 % complete
ubiformat: 316 eraseblocks have valid erase counter, mean value is 0
ubiformat: 132 eraseblocks are supposedly empty
ubiformat: warning!: only 316 of 448 eraseblocks have valid erase counter
ubiformat: mean erase counter 0 will be used for the rest of eraseblock
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: flashing eraseblock 97 -- 100 % complete
ubiformat: formatting eraseblock 447 -- 100 % complete
root@XiaoQiang:~# nvram get flag_boot_rootfs
1
root@XiaoQiang:~# nvram get flag_last_success
1
root@XiaoQiang:~# reboot

Dont see anything obviously wrong?

You have UART by any chance?

Nope. Not an 1.8V version. Need to get one.

hello robi..i build my own image based on your latest repo..try to sysupgrade after boot from your own img intframs.ubi..it doesn't work..compat version not the same..mine still stuck version 1 i think..when i forced upgrade ax9000 became brick..but when sysupgrade using your own img sysupgrade.bin it worked and i can see storage expanded..did i miss something while building my own img based on your repo???tq

If it complains about the compat_version, then your build doesn't contain the necessary changes (too old, wrong branch, 3rd party lagging behind).

ok..later I'll check what i missed..tq u for advise

Hi Guys!

Can I get some advice how to recover my device?

I was on openwrt with 2 partition layout and flashed https://feed.robimarko.eu/openwrt-ipq807x-generic-xiaomi_ax9000-initramfs-factory.ubi
But for some reason it was bootlooping, only orange led for couple of seconds, then off, and repeat..

So I thought: "okay, re-flash stock fw with tftp, and re-do the exploit then try again"
And here comes the problem, when I first used the browser F12 script exploit to gain ssh access, I changed the country code to CN, and after factory resetting the device I couldn't get past the first country selection screen, because it gave the error: "Unknown error. Please try again later"
The exploit worked, it enabled telnet, but didn't accept the password generated from S/N.
So I opened the router to access UART, and from there I could flash OpenWRT, all good.

But now when I TFTP restored stock FW it disabled ssh, telnet, uart, and I have the same error as before, can not get past "Unknown error. Please try again later", but this time UART RX isn't working so I can not do anything.

I can access the web UI after getting the stok from browser F12 console, but so far everything that I tried gives 403 Forbidden error, the only thing working is renaming the router, and logout.

Is there something I can do? or is it a full brick?

Is this chinese model or international one?

Did you patch the bdata with fw_setsys to permanently enable UART, etc as otherwise flashing stock FW will reset the U-boot env to bdata

Had a similar problem. Also changed the country and couldn't complete the stock setup. While the Wiki info says you can change the country I think it may lead such issues and a warning should be in place.

I was able to complete the setup by using a simple python proxy server, pointing the browser to the proxy which made sure to mask the country error and return the browser a status code that all is all. You may have a different issue but give it a shot and maybe tweak to your specific issue:

python3 script

import requests
import signal
import sys
import urllib.parse
from http.server import BaseHTTPRequestHandler, HTTPServer

class ApiProxy:
    def start_server(self):
        class ProxyHTTPRequestHandler(BaseHTTPRequestHandler):
            protocol_version = "HTTP/1.0"

            def do_GET(self):
                self._handle_request("get", requests.get)

            def do_DELETE(self):
                self._handle_request("delete", requests.delete)

            def do_POST(self):
                self._handle_request("post", requests.post)

            def do_PUT(self):
                self._handle_request("put", requests.put)

            def do_PATCH(self):
                self._handle_request("patch", requests.patch)

            def _handle_request(self, method, requests_func):
                url = self._resolve_url()
                if (url is None):
                    print(f"Unable to resolve the URL {self.path}")
                    self.send_response(404)
                    self.send_header("Content-Type", "application/json")
                    self.end_headers()
                    return

                print(self.headers)
                body=None
                if 'content-length' in self.headers:
                        body = self.rfile.read(int(self.headers["content-length"]))
                headers = dict(self.headers)
                if 'Connection' in headers: del headers['Connection']

                resp = requests_func(url, data=body, headers=headers)
                if resp.status_code == 500:
                        self.send_response(200)
                        content = b'{"code":0}'
                        del headers['Content-Length']
                else:
                        self.send_response(resp.status_code)
                        content = resp.content
                for key in headers:
                    self.send_header(key, headers[key])
                self.end_headers()
                self.wfile.write(content)

            def _resolve_url(self):
                return self.path

        server_address = ('', 8001)
        self.httpd = HTTPServer(server_address, ProxyHTTPRequestHandler)
        print('proxy server is running')
        self.httpd.serve_forever()


def exit_now(signum, frame):
    sys.exit(0)

if __name__ == '__main__':
    proxy = ApiProxy()
    signal.signal(signal.SIGTERM, exit_now)
    proxy.start_server()

Sorry forgot to mention, its the international version.
No, I just uploaded the 3 generated exploit .bin files.

I dont have any experience with those, only used the exploit JS to enable telnet.
But, I have a feeling its messing with things it shouldn't do, also the atf=1 variable must be set in U-boot env

create_exploit script sets these env variables:

	bdata["boot_wait"] = "on";
	bdata["uart_en"] = "1";
	bdata["telnet_en"] = "1";
	bdata["ssh_en"] = "1";
	bdata["CountryCode"] = prompt("Enter country code", bdata["CountryCode"]) ?? bdata["CountryCode"];