[openwrt/openwrt] mvebu: add support for Turris MOX

LEDE Commits lede-commits at lists.infradead.org
Sun Nov 30 15:33:30 PST 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/ea6ee930601cfc260e6477f573513850f1806012

commit ea6ee930601cfc260e6477f573513850f1806012
Author: Tomáš Macholda <tomas.macholda at nic.cz>
AuthorDate: Thu Sep 18 13:08:52 2025 +0200

    mvebu: add support for Turris MOX
    
    Adds support for Turris MOX, a modular router extendable by board modules (MOX B-G).
    
    You can explore the idea behind the modules at: https://mox-configurator.turris.cz/
    
    More information about Turris MOX can be found here: https://docs.turris.cz/hw/mox/intro/
    
    Also works with Turris Shield (Turris MOX A and C with a simplified OS UI).
    
    Specifications:
    -----------------------
    
    MOX A
    - SoC: Marvell Armada 3720
    - RAM: 512/1024 MB, DDR3
    - Memory:
        - 8 MB SPI NOR Flash for U-Boot and rescue system
        - SD card slot
    - 1x RJ-45, 1Gbps
    - 1x USB 3.0
    - 1x activity LED
    - 1x reset button
    - SDIO header
    - misc pin header (UART, GPIO, JTAG, ...)
    
    MOX B, G
    - 1x mPCIe slot
    - 1x SIM slot
    
    MOX C
    - 4x RJ-45, 1Gbps
    
    MOX D
    - SFP, 2.5Gbps
    
    MOX E
    - 8x RJ-45, 1Gbps
    
    MOX F
    - 4x USB 3.0
    
    Module support:
    -----------------------
    
    Additional packages are needed for some modules.
    
    MOX A (core)
    - works as is
    
    MOX B, G (mPCIe, mPCIe passthrough)
    - works as is
    
    MOX C, E (4x, 8x RJ-45)
    - kmod-dsa
    - kmod-dsa-mv88e6xxx
    
    MOX D (SFP)
    - kmod-sfp
    - kmod-phy-marvell-10g
    
    MOX F (4x USB 3.0)
    - works as is
    
    Wi-Fi 5, 3x3 card (WLE900VX)
    - kmod-ath10k
    - ath10k-board-qca988x
    - ath10k-firmware-qca988x
    
    Wi-Fi 6, DBDC, 2x2 card (MT7915DAN)
    - kmod-mt7915e
    - kmod-mt7915-firmware
    
    Interface naming:
    -----------------------
    
    - MOX A's RJ-45 is assigned to `eth0`.
    - MOX C, E (4x, 8x RJ-45) are assigned to `lan<number>@eth1`
    - If MOX D (SFP) is connected directly to MOX A, the resulting interface
      is `eth1`. If it's connected through MOX E (8x RJ-45), the resulting
      interface is `sfp at eth1`.
    
    Quirks:
    -----------------------
    
    - MOX is sensitive to the order of connected modules. Verify that the
      confguration is valid at: https://mox-configurator.turris.cz/
    - `CONFIG_MOXTET` and `CONFIG_GPIO_MOXTET` need to be enabled in kernel
      config. Moxtet is a bus protocol needed to discover and configure MOX
      modules. It must be compiled into the kernel for the modules to work.
      Though it's very small so it won't bloat up the kernel image.
    
    Flashing instructions:
    -----------------------
    
    1. Download `openwrt-*-ext4-sdcard.img.gz` and `gunzip` it.
    2. Insert an SD card and flash the image to it using dd:
       dd if=openwrt-*-ext4-sdcard.img.gz of=/dev/mmcblk0 bs=4096 conv=fsync
    3. Plug the SD card into MOX.
    
    Troubleshooting:
    -----------------------
    
    - https://docs.turris.cz/hw/serial/#turris-mox
    - https://docs.turris.cz/hw/mox/rescue-modes/
    
    Signed-off-by: Tomáš Macholda <tomas.macholda at nic.cz>
    Link: https://github.com/openwrt/openwrt/pull/20356
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 package/boot/uboot-mvebu/Makefile                  |  8 ++++
 .../mvebu/cortexa53/base-files/etc/board.d/01_leds |  3 ++
 .../cortexa53/base-files/etc/board.d/02_network    | 12 ++++++
 target/linux/mvebu/cortexa53/config-6.12           |  2 +
 target/linux/mvebu/image/cortexa53.mk              | 10 +++++
 target/linux/mvebu/image/turris-mox.bootscript     | 50 ++++++++++++++++++++++
 6 files changed, 85 insertions(+)

diff --git a/package/boot/uboot-mvebu/Makefile b/package/boot/uboot-mvebu/Makefile
index f3009d0e7c..85df6a22ce 100644
--- a/package/boot/uboot-mvebu/Makefile
+++ b/package/boot/uboot-mvebu/Makefile
@@ -22,6 +22,13 @@ define U-Boot/Default
   HIDDEN:=1
 endef
 
+define U-Boot/mox
+  NAME:=CZ.NIC Turris Mox
+  BUILD_DEVICES:=cznic_turris-mox
+  BUILD_SUBTARGET:=cortexa53
+  UBOOT_CONFIG:=turris_mox
+endef
+
 define U-Boot/clearfog
   NAME:=SolidRun ClearFog A1
   BUILD_DEVICES:=solidrun_clearfog-base-a1 solidrun_clearfog-pro-a1
@@ -69,6 +76,7 @@ define U-Boot/rb5009
 endef
 
 UBOOT_TARGETS:= \
+	mox \
 	clearfog \
 	helios4 \
 	omnia \
diff --git a/target/linux/mvebu/cortexa53/base-files/etc/board.d/01_leds b/target/linux/mvebu/cortexa53/base-files/etc/board.d/01_leds
index 4dce204f14..035fa4933b 100644
--- a/target/linux/mvebu/cortexa53/base-files/etc/board.d/01_leds
+++ b/target/linux/mvebu/cortexa53/base-files/etc/board.d/01_leds
@@ -7,6 +7,9 @@ board_config_update
 board=$(board_name)
 
 case "$board" in
+cznic,turris-mox)
+        ucidef_set_led_heartbeat "wan" "MOX A" "mox:red:activity"
+        ;;
 glinet,gl-mv1000)
 	ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan"
 	;;
diff --git a/target/linux/mvebu/cortexa53/base-files/etc/board.d/02_network b/target/linux/mvebu/cortexa53/base-files/etc/board.d/02_network
index 6789edb861..c70af063ce 100644
--- a/target/linux/mvebu/cortexa53/base-files/etc/board.d/02_network
+++ b/target/linux/mvebu/cortexa53/base-files/etc/board.d/02_network
@@ -10,6 +10,18 @@ board_config_update
 board=$(board_name)
 
 case "$board" in
+cznic,turris-mox)
+	mox_lan_interfaces=""
+	for net in /sys/class/net/lan*; do
+		[ -e "$net" ] || continue
+		append mox_lan_interfaces "${net##*/}"
+	done
+	if [ -z "$mox_lan_interfaces" ]; then
+		ucidef_set_interface_lan "eth0"
+	else
+		ucidef_set_interfaces_lan_wan "$mox_lan_interfaces" "eth0"
+	fi
+	;;
 glinet,gl-mv1000|\
 globalscale,espressobin|\
 globalscale,espressobin-emmc|\
diff --git a/target/linux/mvebu/cortexa53/config-6.12 b/target/linux/mvebu/cortexa53/config-6.12
index 253c441519..15a63334a6 100644
--- a/target/linux/mvebu/cortexa53/config-6.12
+++ b/target/linux/mvebu/cortexa53/config-6.12
@@ -54,12 +54,14 @@ CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_GENERIC_CSUM=y
 CONFIG_GENERIC_IOREMAP=y
 CONFIG_GENERIC_PINCONF=y
+CONFIG_GPIO_MOXTET=y
 CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
 CONFIG_MAILBOX=y
 # CONFIG_MAILBOX_TEST is not set
 CONFIG_MFD_SYSCON=y
 CONFIG_MMC_SDHCI_XENON=y
 CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MOXTET=y
 CONFIG_MVEBU_GICP=y
 CONFIG_MVEBU_ICU=y
 CONFIG_MVEBU_ODMI=y
diff --git a/target/linux/mvebu/image/cortexa53.mk b/target/linux/mvebu/image/cortexa53.mk
index 67bff6c0b2..25ec3d3f81 100644
--- a/target/linux/mvebu/image/cortexa53.mk
+++ b/target/linux/mvebu/image/cortexa53.mk
@@ -1,3 +1,13 @@
+define Device/cznic_turris-mox
+  $(call Device/Default-arm64)
+  DEVICE_VENDOR := CZ.NIC
+  DEVICE_MODEL := Turris MOX
+  DEVICE_PACKAGES := kmod-usb2 kmod-gpio-button-hotplug kmod-rtc-ds1307 kmod-i2c-pxa
+  SOC := armada-3720
+  BOOT_SCRIPT := turris-mox
+endef
+TARGET_DEVICES += cznic_turris-mox
+
 define Device/glinet_gl-mv1000
   $(call Device/Default-arm64)
   DEVICE_VENDOR := GL.iNet
diff --git a/target/linux/mvebu/image/turris-mox.bootscript b/target/linux/mvebu/image/turris-mox.bootscript
new file mode 100644
index 0000000000..8cef275ade
--- /dev/null
+++ b/target/linux/mvebu/image/turris-mox.bootscript
@@ -0,0 +1,50 @@
+if part uuid ${devtype} ${devnum}:${distro_bootpart} bootuuid; then
+	if test "${bootfstype}" = "btrfs"; then
+		# Original BTRFS partition layout
+		rootdev="PARTUUID=${bootuuid}"
+		rootflags="commit=5,subvol=@"
+		bootpath="/@/boot"
+	else
+		# OpenWrt default ext4 bootpart + rootpart layout
+		rootdev="/dev/mmcblk0p2"
+		rootflags="commit=5"
+		bootpath="/"
+	fi
+
+	load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${bootpath}/armada-3720-turris-mox.dtb
+	if test "$filesize" != "0"; then
+		has_dtb=1
+	else
+		setenv has_dtb 0
+		echo "Cannot find device tree binary!"
+	fi
+
+	if test $has_dtb -eq 1; then
+		load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} ${bootpath}/Image
+		if test "$filesize" = "0"; then
+			echo "Failed to load ${bootpath}/Image"
+			echo "Now trying ${bootpath}/Image.lzma"
+			tmp_addr_r=0x10000000
+			load ${devtype} ${devnum}:${distro_bootpart} ${tmp_addr_r} ${bootpath}/Image.lzma
+			if test "$filesize" != "0"; then
+				if lzmadec ${tmp_addr_r} ${kernel_addr_r}; then
+					echo "Successfully decompressed Image.lzma"
+				else
+					echo "Failed decompressing Image.lzma"
+					filesize=0
+				fi
+			else
+				echo "Failed to load ${subvol}/boot/Image.lzma"
+			fi
+		fi
+		if test "$filesize" != "0"; then
+			setenv bootargs "earlyprintk console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000 rootfstype=${bootfstype} root=${rootdev} rootflags=${rootflags} rootwait ${contract} rw cfg80211.freg=${regdomain} ${quirks}"
+			booti ${kernel_addr_r} - ${fdt_addr_r}
+			echo "Booting Image failed"
+		else
+			echo "Cannot load kernel binary"
+		fi
+	fi
+
+	env delete bootuuid rootpart
+fi




More information about the lede-commits mailing list