OpenWrt sul TP-Link VX830v: guida completa al porting

TL;DR — Ho portato OpenWrt su un router TP-Link VX830v (firmware Wind Tre), normalmente bloccato e senza supporto community. WiFi 2.4 GHz + 5 GHz funzionanti, LAN 2.5 GbE, SFP GPON. In questo articolo racconto tutto il percorso, dall’apertura del case fino al boot dalla NAND.


Indice

  1. Il router
  2. Apertura e accesso seriale TTL
  3. Accesso a U-Boot
  4. Creazione del Device Tree (DTS)
  5. Compilazione di OpenWrt
  6. Boot via TFTP
  7. La caccia all’EEPROM WiFi
  8. Flash permanente sulla NAND
  9. Schema delle partizioni
  10. Ripristino del firmware originale
  11. Note e ringraziamenti

Il router

Il TP-Link VX830v è un router VDSL2/GPON fornito da Wind Tre in Italia. Sulla carta è un dispositivo di fascia alta:

Caratteristica Dettaglio
SoC MediaTek MT7986A (Filogic 830)
RAM 512 MiB DDR4
Flash SPI-NAND (NMBM)
WiFi MT7975 dual-band 802.11ax (WiFi 6)
LAN 3× GbE + 1× 2.5 GbE (Airoha EN8811H)
WAN 1× 2.5 GbE + SFP GPON combo
VoIP 2× FXS (Si3218x)
USB 1× USB 3.0

Peccato che il firmware Wind lo tenga completamente blindato. Nessun accesso SSH, nessuna personalizzazione. Tempo di cambiare le cose.

TP-Link VX830v - Vista esterna


Apertura e accesso seriale TTL

Il primo passo è stato aprire il case. Quattro clip plastiche sul fondo, niente viti nascoste. Una volta aperto, la PCB rivela subito i pad UART/TTL:

PCB del VX830v con pin TTL

Connessione seriale

Pin TTL Collegamento
GND GND dell’adattatore USB-TTL
TX RX dell’adattatore
RX TX dell’adattatore
VCC NON collegare (il router si alimenta da solo)

Parametri della seriale:

Baud rate: 115200
Data bits: 8
Stop bits: 1
Parity: None
Flow control: None

Software consigliato: PuTTY o Tera Term su Windows.


Accesso a U-Boot

All’accensione, il router mostra il boot log sulla seriale. Premendo un tasto entro 5 secondi si entra nella shell U-Boot. Da qui possiamo fare boot via rete (TFTP) senza toccare la NAND.

Layout delle partizioni NAND (originale)

mtd0: 00200000  "boot"        (U-Boot, 2 MiB)
mtd1: 00100000  "u-boot-env"  (Variabili U-Boot, 1 MiB)
mtd2: 00600000  "misc_ro"     (Factory data / EEPROM WiFi, 6 MiB)
mtd3: 00600000  "misc_rw"     (Configurazione TP-Link, 6 MiB)
mtd4: 02800000  "ubi0"        (Firmware slot A, 40 MiB)
mtd5: 02800000  "ubi1"        (Firmware slot B, 40 MiB)
mtd6: 00600000  "misc_rw_bak" (Backup config, 6 MiB)
mtd7: 00600000  "bflag"       (Boot flags, 6 MiB)
mtd8: 00600000  "misc_isp"    (Dati ISP, 6 MiB)

Il firmware originale usa uno schema A/B dual-firmware: due slot (ubi0 e ubi1) con fallback automatico in caso di upgrade fallito.


Creazione del Device Tree (DTS)

Ho estratto il DTS originale del firmware TP-Link e l’ho analizzato per capire il mapping hardware. Da lì ho creato il DTS per OpenWrt (mt7986a-tplink-vx830v.dts) con:

Punti critici del DTS

Il passaggio più delicato è stato il mapping dei PHY Airoha EN8811H. Questi PHY hanno bisogno che la linea di reset sia tenuta HIGH durante l’init del GPIO controller, altrimenti il firmware interno del PHY non si avvia. La soluzione è stata usare gpio-hog nel nodo &pio:

phy14_rst: phy14-rst-hog {
    gpio-hog;
    gpios = <6 GPIO_ACTIVE_HIGH>;
    output-high;
    line-name = "en8811h-a-reset";
};

Compilazione di OpenWrt

Prerequisiti

# Clona OpenWrt
git clone https://git.openwrt.org/openwrt/openwrt.git
cd openwrt

# Aggiorna i feed
./scripts/feeds update -a
./scripts/feeds install -a

Configurazione

make menuconfig

Selezionare:

Build

make -j$(nproc)

Il risultato sono due file:


Boot via TFTP

Setup

  1. Configurare un server TFTP sul PC (es. Tftpd64 su Windows)
  2. IP del PC: 192.168.1.2
  3. Copiare openwrt-mediatek-filogic-tplink_vx830v-initramfs-kernel.bin nella cartella TFTP
  4. Collegare il PC a una porta LAN del router via cavo ethernet

Comandi U-Boot

MT7986> tftpboot 0x46000000 openwrt-mediatek-filogic-tplink_vx830v-initramfs-kernel.bin
MT7986> bootm 0x46000000

Il router boota OpenWrt direttamente in RAM, senza toccare la NAND. Perfetto per i test.


La caccia all’EEPROM WiFi

Questa è stata la parte più complicata dell’intero porting. Il WiFi funzionava solo a metà — il 2.4 GHz partiva ma con dati di calibrazione default, il 5 GHz era completamente assente.

Il problema

Il kernel mostrava:

mt798x-wmac 18000000.wifi: eeprom load fail, use default bin
mt798x-wmac 18000000.wifi: Direct firmware load for mediatek/mt7986_eeprom_mt7975_dual.bin failed with error -2

Il DTS originale TP-Link indicava che l’EEPROM WiFi si trovava nella partizione misc_ro a offset 0x0. Ma leggendo il raw MTD si otteneva:

00000000  55 42 49 23 01 00 00 00  ...  |UBI#............|

UBI# è l’header UBI! La partizione misc_ro non contiene dati raw, è formattata come volume UBI con filesystem UBIFS dentro.


La scoperta

Montando il filesystem UBIFS:

mkdir -p /tmp/misc_ro
mount -r -t ubifs ubi1:misc_ro /tmp/misc_ro
ls -la /tmp/misc_ro/
-rw-r--r--  1 root root      96 Dec 31  2015 0x0034B300
-rw-r--r--  1 root root     176 Dec 31  2015 0x0034B500
...
----------  1 root root  655360 Dec 31  2015 0x003A0000   ← EEPROM WiFi!
-rw-r--r--  1 root root   35200 Jan 22 15:07 0x00440000

Il file 0x003A0000 (640 KiB) contiene l’EEPROM WiFi. I primi byte confermano:

00000000  86 79 06 00 00 0c 43 26  60 00 ...  |.y....C&`...|

86 79 = chip ID MT7986 in little-endian. Trovato!


La soluzione

I primi 4096 byte del file contengono i dati di calibrazione per entrambe le bande:

dd if=/tmp/misc_ro/0x003A0000 of=/lib/firmware/mediatek/mt7986_eeprom_mt7975_dual.bin bs=4096 count=1

Dopo aver ricaricato il driver WiFi:

echo 18000000.wifi > /sys/bus/platform/drivers/mt798x-wmac/unbind
sleep 2
echo 18000000.wifi > /sys/bus/platform/drivers/mt798x-wmac/bind

Risultato:

Wiphy phy2  →  Band 1 (2.4 GHz)  ✓
Wiphy phy3  →  Band 2 (5 GHz)    ✓

Entrambe le bande WiFi 6 funzionanti con i dati di calibrazione reali del dispositivo.

Automatizzazione nel firmware

Per rendere il tutto automatico al boot, ho modificato due script:

09_mount_cfg_part — monta il volume UBIFS misc_ro durante il preinit:

tplink,vx830v)
    mount_ubi_part "misc_ro" "misc_ro"
    ;;

11-mt76-caldata — copia l’EEPROM dal file montato quando il driver la richiede:

tplink,vx830v)
    dd if=/tmp/misc_ro/0x003A0000 of=/lib/firmware/$FIRMWARE \
        bs=4096 count=1 2>/dev/null
    ;;

Flash permanente sulla NAND

Una volta verificato che tutto funziona via initramfs, si può flashare il firmware sulla NAND:

sysupgrade -n openwrt-mediatek-filogic-tplink_vx830v-squashfs-sysupgrade.bin

Il comando riscrive ubi0 con i volumi OpenWrt (kernel, rootfs, rootfs_data). Al riavvio successivo, U-Boot carica OpenWrt direttamente dalla NAND senza bisogno di TFTP.

Variabili U-Boot

Per verificare/modificare lo slot di boot:

# Crea il config se non esiste
echo "/dev/mtd1 0x0 0x20000 0x20000" > /etc/fw_env.config

# Leggi
fw_printenv

# L'importante è: bootargs=ubi.mtd=ubi0

Schema delle partizioni

┌─────────────────────────────────────────────────────────┐
│  NAND Flash (SPI-NAND con NMBM)                        │
├──────────┬──────────┬───────────────────────────────────┤
│ 0x000000 │  2 MiB   │ boot (U-Boot)                    │
│ 0x200000 │  1 MiB   │ u-boot-env                       │
│ 0x300000 │  6 MiB   │ misc_ro (UBIFS: EEPROM WiFi)     │
│ 0x900000 │  6 MiB   │ misc_rw (UBIFS: config TP-Link)  │
│ 0xF00000 │ 40 MiB   │ ubi0 → OpenWrt (kernel+rootfs)   │
│ 0x3700000│ 40 MiB   │ ubi1 → Firmware TP-Link backup   │
│ 0x5F00000│  6 MiB   │ misc_rw_bak                      │
│ 0x6500000│  6 MiB   │ bflag                            │
│ 0x6B00000│  6 MiB   │ misc_isp                         │
└──────────┴──────────┴───────────────────────────────────┘

Ripristino del firmware originale

Il firmware TP-Link originale è preservato su ubi1. Per tornare indietro:

fw_setenv bootargs "ubi.mtd=ubi1 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000"
reboot

Per tornare a OpenWrt:

fw_setenv bootargs "ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000"
reboot

Note e ringraziamenti

Cosa funziona

Cosa non è stato testato

Hardware necessario


Pubblicato da Filippo — Marzo 2026