Deeper dive into the Ubiquiti USW Flex Mini
![[Image of a switch PCB (the USW Flex Mini) in a slight angle. Behind is a breadbord visible with a corner of a rp pico.]](/posts/unifree/usw-flex-mini/pcb_angle_hu_6dbabf6d1dc45e89.webp)
Table of Contents
A while ago a friend of mine (ember) discovered that the firmware names of some of the small Ubiquiti
switches (mostly USW flex) contains the string ESP32. This lead to an investigation for what they
contain an ESP.
(Most of the events described here are already a while back as we are currently focusing most of the
reverse engineering/development effort on the USW-Ultra but though it's still useful to write it down
and we plan to eventually pick the USW-Flex-Mini up again, though missing useful support in zephyr
for the used MCU does not make it easier.)
Public available info
We quickly found tech notes from jade.wtf detailing some pictures about the used ICs in
the USW-Flex-Mini.
The tech notes detailed some looking into firmware extracted from the firmware image available to
download from the ui website.
Noticeable that it seems to be some sort of ARM, while Jade deducted that it has to be some sort of
ARMv8-M and not some sort of M0 or M4 (through finding usage of BLXNS instruction) this later
seemed to be false.
Jade further goes into gaining access to the firmware through a UART header and the available cli commands offered there.
Hardware
The MCU (and the switch IC)
The board has a chip that looks like the MCU of the board but this chip only has the marking
Nuvoton / UB10 (or U810), which does not help as there is no trace of the chip
online (except Jades blog).
The used switch IC is the RTL8367RB which has no official public documentation but LCSC has the chip,
including a datasheet which just states internal :).
Using this datasheet it was easy to discover where there are likely connections from the switch IC to
the (at this point still unidentified) MCU using the MII / RMII interface.
Using SWD I dumped the firmware through a connected gdb an dump binary memory as I did not
yet have a discovered flash driver I could use to directly access the Flash. At Some point I also hacked
together a OpenOCD that works with both Nuvoton and the pico debugprobe though not sure when this
was. I dumped the image using the Flash configuration table the Bootloader prints to UART while
booting, so I had a rough idea (based on the names) what to expect in which section.
Flash Configurations:
FLASH_APPLICATION_SIZE : 0x6d000
FLASH_APPLICATION_ADDRESS : 0x10000
FLASH_DATA_ADDRESS : 0x7d000
-- FLASH_TLS_ADDRESS : 0x7d000
-- FLASH_ENV_ADDRESS : 0x7e000
-- FLASH_SIGNED_IMAGE_ADDRESS: 0x7f000Using this pin information I found the M467SJHAN (not the chip) from Nuvoton online which seemed
like it would be a good fit, having pins for a EMAC and SWD in the correct places. With this guess for a
chip I started to open the bootloader of the firmware in binaryninja which quickly confused me,
as theEMAC registers did not match the Technical Reference Manual of that chip/family at all
(more on firmware RE later). This then prompted me to search through the Nuvoton website again
and find the M487SIDAE which had all pins at a correct looking place and even more than that,
the register map did match (as far as I discovered) what I expected.
At this point I also had the idea if maybe SWD can help me find out which chip is used
(I never used OpenOCD to reverse engineer MCUs, only to flash/debug them).
After hacking around an openocd version that works with both Nuvoton and the pico debugprobe
(as this is the only SWD flasher I easily have access to) I used this to read the SWD DPIDR
which further confirmed this is an ARM Cortex-M4.
Pins
A quick overview over the pins we found.

(All of this is also available in a zephyr devicetree which we plan to use for the firmware: https://cyberchaos.dev/kloenk/unifree/-/blob/main/boards/unifree/usw_flex_mini/usw_flex_mini.dts)
Debug headers
With the Ethernet ports at the bottom going from top to bottom
UART header
UART is on the upper header with +3V3 furthest away from the ethernet ports.
This was already described by Jades blog which made it much easier to get the correct RX/TX direction.
| +3V3 |
| UART_RX |
| UART_TX |
| GND |
SWD header
The next header contains SWD on the following pins.
| SWDIO |
| SWDCLK |
| n_RST |
| GND |
RTL to MCU
We likely did not find all pins connected from the switch IC to the MCU yet, specificaly
the USW-Ultra has a reset pin for the switch which likely exists here as well.
| MCU pin | RTL pin |
|---|---|
| 2 | 62 (M1M_TXCLK) |
| 3 | 60 (M1M_TXD0) |
| 4 | 59 (M1M_TXD1) |
| 5 | 61 (M1M_TXEN) |
| 60 | 93 (MDC) |
| 61 | 94 (MDIO) |
| 62 | 65 (M1M_RXD0) |
| 63 | 66 (M1M_RXD1) |
| 64 | 64 (M1M_RXDV) |
Firmware
We poked around a bit further in the bootloader of the original firmware, identifying some config structs but then decided to not waste to much time on reverse engineering the firmware as we just want our own firmware that can be used without a unifi controller and that has the same codebase for multiple switches.
The firmware dump looked like it could get interesting later and maybe we even bring the bootloader to update to our firmware without opening the enclosure. But all this is a thing to discover later.
Zephyr
I pretty much from the start said I wanted to use zephyr as I quite like the RTOS and it also should
enable us to use mostly the same firmware on the USW-Flex-Mini and other ESP32 based switches.
Wanting to use zephyr I sadly had to realize that there is not reasonable support for the M487SIDAE
which means we have to create this including clock controller driver and everything we need.
Not wanting to do board/MCU bringup on a board I have no clear grasp on, I therefore looked if there is
a EVT kit for the chip family and found the numaker_pfm_m487 but being somewhat short on money
(for this project) I tried to find some way to maybe get it sponsored asking around both on fedi,
but also trying to contact Nuvoton directly with the idea that they could maybe give it to me for using
my free time to write support for the board in zephyr.
Trying to contact Nuvoton failed as their official support form (which they link to get access to evaluation kits) and also their live chat bot is just misconfigured (the chat bot just tells me to contact the owner to fix the configuration, but how though).
In the end I decided to spend my own money and get a board from DigiKey, which gave me the joy of seeing the packaging Nuvoton came up with. Which is a way to small non ESD plastic packaging which successfully ripped of a component of the board, but DigiKey was very easy to contact and they replaced it after seeing the pictures without any other questions.