thia was me with claude i happy to share it but answering question is hard for me so here the full journey Complete Guide: Particle Tachyon QCM6490 - Ubuntu 24.04 + 5G Modem + MPTCP Bonding
First documented setup of 5G modem working on Ubuntu 24.04 with MPTCP bonding on Particle Tachyon
What This Guide Covers
- Getting Ubuntu 24.04 running on Particle Tachyon (QCM6490)
- Making the 5G modem work (the hard part nobody documented)
- Building a custom kernel with MPTCP support
- Creating a WiFi hotspot that bonds WiFi + 5G traffic
- True bandwidth aggregation for connected devices
Hardware
- Device: Particle Tachyon
- SoC: Qualcomm QCM6490
- Storage: 128GB UFS
- Modem: Qualcomm X55 5G (integrated)
- WiFi: Qualcomm ath11k (WiFi 6E)
Part 1: The 5G Modem Problem (Ubuntu 24.04)
The Issue
Ubuntu 24.04's kernel doesn't create certain sysfs files that Particle's modem stack (particle-tachyon-rild) requires. The modem simply won't start.
Missing files:
/sys/devices/soc0/select_image
/sys/devices/soc0/image_crm_version
The Fix: Fake soc0 Overlay
Create fake soc0 files using overlayfs:
# /usr/local/bin/setup-fake-soc0.sh
#!/bin/bash
OVERLAY_DIR="/var/lib/soc0-overlay"
FAKE_SOC0="$OVERLAY_DIR/fake-soc0"
WORK_DIR="$OVERLAY_DIR/work"
mkdir -p "$FAKE_SOC0" "$WORK_DIR"
# Get real modem version
MODEM_VERSION=$(cat /sys/kernel/debug/qcom_socinfo/mpss/oem 2>/dev/null || echo "MPSS.LE.1.0")
# Create fake files
echo "0" > "$FAKE_SOC0/select_image"
echo "$MODEM_VERSION" > "$FAKE_SOC0/image_crm_version"
# Mount overlay
mount -t overlay overlay \
-o lowerdir=/sys/devices/soc0,upperdir=$FAKE_SOC0,workdir=$WORK_DIR \
/sys/devices/soc0
Systemd service:
# /etc/systemd/system/fake-soc0.service
[Unit]
Description=Mount fake soc0 overlay for modem
Before=particle-tachyon-rild.service
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/local/bin/setup-fake-soc0.sh
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
Part 2: Missing Libraries for rild
The Problem
particle-tachyon-rild requires Qualcomm libraries that exist in Ubuntu 20.04 but not 24.04.
The Fix: Copy from 20.04
Extract these from the Ubuntu 20.04 system image and copy to /lib/:
libql_ril.so
libril.so
libbinder.so.0
libsmspdu.so
libqmi_cci.so.1
libcutils.so.0
liblog.so.0
libql_misc.so
libloc_api_v02.so.1
libprotobuf-nanopb2.so.0
libutils.so.0
librilutils.so
libqmi_encdec.so.1
libqmi_common_so.so.1
libgps_utils.so.1
libloc_core.so.1
Extract from 20.04 image:
# Mount 20.04 system image
sudo mount -o ro /path/to/tachyon-ubuntu-20.04-image.ext4 /mnt/sysfs20
# Copy libraries
sudo cp /mnt/sysfs20/lib/libql_ril.so /lib/
sudo cp /mnt/sysfs20/lib/libril.so /lib/
# ... etc for all libraries
sudo ldconfig
Part 3: rmtfs Storage Symlinks
The Problem
rmtfs service can't find modem storage partitions.
The Fix
mkdir -p /persist/rmtfs
ln -sf /dev/disk/by-partlabel/modemst1 /persist/rmtfs/modemst1
ln -sf /dev/disk/by-partlabel/modemst2 /persist/rmtfs/modemst2
ln -sf /dev/disk/by-partlabel/fsc /persist/rmtfs/fsc
ln -sf /dev/disk/by-partlabel/fsg /persist/rmtfs/fsg
Systemd service:
# /etc/systemd/system/setup-modem-symlinks.service
[Unit]
Description=Setup modem storage symlinks
Before=rmtfs.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/setup-modem-symlinks.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Part 4: SIM Slot Selection
Tachyon has two SIM slots:
- Slot 1: Particle eSIM (limited/restricted)
- Slot 2: External physical SIM
# Check current slot
particle-tachyon-ril-ctl active_sim --get
# Switch to external SIM (slot 2)
particle-tachyon-ril-ctl active_sim --set 2
# Check modem state
particle-tachyon-ril-ctl state
# Connect
particle-tachyon-ril-ctl connect
Part 5: Custom Kernel with MPTCP
Clone Kernel Source
git clone https://github.com/particle-iot/tachyon-ubuntu-24.04-kernel
cd tachyon-ubuntu-24.04-kernel
Enable MPTCP in Config
Edit debian.particle/config/annotations:
CONFIG_MPTCP=y
CONFIG_MPTCP_IPV6=y
CONFIG_INET_MPTCP_DIAG=m
Fix BTF Build Errors
If building in QEMU/VM, disable BTF:
CONFIG_DEBUG_INFO_BTF policy<{'arm64': 'n'}>
CONFIG_DEBUG_INFO_BTF_MODULES policy<{'arm64': '-'}>
Build
./build.sh
# Or with Docker:
./build.sh --docker
Install
./install.sh --ssh root@<device-ip>
# Or manually:
scp linux-*.deb root@<device-ip>:/tmp/
ssh root@<device-ip> "dpkg -i /tmp/linux-*.deb && reboot"
Part 6: MPTCP Configuration
Enable MPTCP
# Persistent
echo "net.mptcp.enabled=1" >> /etc/sysctl.d/99-mptcp.conf
sysctl -p
Configure Endpoints
# /usr/local/bin/mptcp-setup.sh
#!/bin/bash
# Wait for interfaces
sleep 5
# Flush existing endpoints
ip mptcp endpoint flush
# Add WiFi endpoint
WIFI_IP=$(ip -4 addr show wlp1s0 | grep -oP "inet \K[\d.]+")
[ -n "$WIFI_IP" ] && ip mptcp endpoint add $WIFI_IP dev wlp1s0 subflow
# Add 5G endpoint
CELL_IP=$(ip -4 addr show qmapmux0.0 | grep -oP "inet \K[\d.]+")
[ -n "$CELL_IP" ] && ip mptcp endpoint add $CELL_IP dev qmapmux0.0 subflow
# Set limits
ip mptcp limits set subflows 2 add_addr_accepted 2
Part 7: WiFi Hotspot (Concurrent AP + STA)
The ath11k driver supports running AP and client simultaneously using a virtual interface.
Create Virtual AP
iw dev wlp1s0 interface add wlp1s0_ap type __ap
ip addr add 192.168.50.1/24 dev wlp1s0_ap
ip link set wlp1s0_ap up
hostapd Config
# /etc/hostapd/hotspot.conf
interface=wlp1s0_ap
driver=nl80211
ssid=MyHotspot
hw_mode=g
channel=6
country_code=US
ieee80211n=1
wmm_enabled=1
auth_algs=1
wpa=2
wpa_passphrase=mypassword
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
dnsmasq Config (DHCP only)
# /etc/dnsmasq.d/hotspot.conf
port=0
interface=wlp1s0_ap
dhcp-range=192.168.50.10,192.168.50.100,255.255.255.0,12h
dhcp-option=3,192.168.50.1
dhcp-option=6,8.8.8.8,8.8.4.4
NAT Setup
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlp1s0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o qmapmux0.0 -j MASQUERADE
Part 8: MPTCP Bonding for Hotspot Clients
The Challenge
MPTCP works at TCP level, not IP level. Hotspot clients use NAT - they can't directly use MPTCP.
The Solution: Shadowsocks + MPTCP Tunnel
[Hotspot Client] β [Tachyon NAT] β [Shadowsocks Client]
β
MPTCP Connection
ββββββββ΄βββββββ
β β
[WiFi] [5G]
ββββββββ¬βββββββ
β
[VPS: Shadowsocks Server]
β
[Internet]
VPS Setup (Shadowsocks Server)
# Install shadowsocks-rust
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-*.tar.xz
tar -xf shadowsocks-*.tar.xz -C /usr/local/bin/
# Config
cat > /etc/shadowsocks/config.json << 'EOF'
{
"server": "0.0.0.0",
"server_port": 8388,
"password": "your-secure-password",
"method": "aes-256-gcm",
"mptcp": true
}
EOF
# Run
ssserver -c /etc/shadowsocks/config.json
Tachyon Setup (Shadowsocks Client)
# Config
cat > /etc/shadowsocks/client.json << 'EOF'
{
"server": "YOUR_VPS_IP",
"server_port": 8388,
"local_address": "0.0.0.0",
"local_port": 1080,
"password": "your-secure-password",
"method": "aes-256-gcm",
"mptcp": true
}
EOF
# Run
sslocal -c /etc/shadowsocks/client.json
Transparent Proxy (redsocks)
apt install redsocks
# Config
cat > /etc/redsocks.conf << 'EOF'
base {
log_debug = off;
log_info = on;
log = "syslog:daemon";
daemon = on;
redirector = iptables;
}
redsocks {
local_ip = 0.0.0.0;
local_port = 12345;
ip = 127.0.0.1;
port = 1080;
type = socks5;
}
EOF
# Start
redsocks -c /etc/redsocks.conf
iptables Redirect
# Create chain
iptables -t nat -N REDSOCKS
# Exclude local addresses
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d YOUR_VPS_IP -j RETURN
# Redirect TCP to redsocks
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345
# Apply to hotspot interface
iptables -t nat -A PREROUTING -i wlp1s0_ap -p tcp -j REDSOCKS
Part 9: Verification
Check MPTCP Status
# MPTCP enabled?
sysctl net.mptcp.enabled
# Endpoints configured?
ip mptcp endpoint show
# Active MPTCP connections?
ss -M
Verify Both Paths Used
During an active download through the proxy:
ss -tnp dst YOUR_VPS_IP
Should show TWO connections (WiFi + 5G) with same fd/inode.
Check Interface Traffic
# Before download
cat /sys/class/net/wlp1s0/statistics/rx_bytes
cat /sys/class/net/qmapmux0.0/statistics/rx_bytes
# After download - both should increase
Part 10: 5G Source Routing (Public IP)
If your 5G has a public IP and you want incoming connections:
# Add routing table
echo "200 5g" >> /etc/iproute2/rt_tables
# Route 5G responses back through 5G
ip route add default via <5G_GATEWAY> dev qmapmux0.0 table 5g
ip rule add from <5G_PUBLIC_IP> table 5g
# Disable reverse path filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/qmapmux0.0/rp_filter
Interface Names Reference
| Interface |
Description |
| wlp1s0 |
Main WiFi (client mode) |
| wlp1s0_ap |
Virtual WiFi AP (hotspot) |
| qmapmux0.0 |
5G modem data |
| rmnet_ipa0 |
Modem base interface |
Modem Commands Reference
# Check state
particle-tachyon-ril-ctl state
# Connect/disconnect
particle-tachyon-ril-ctl connect
particle-tachyon-ril-ctl disconnect
# Power cycle
particle-tachyon-ril-ctl power off
particle-tachyon-ril-ctl power on
# SIM slot
particle-tachyon-ril-ctl active_sim --get
particle-tachyon-ril-ctl active_sim --set 2
# Get IP
curl --interface qmapmux0.0 ifconfig.me
Systemd Services Summary
| Service |
Purpose |
| fake-soc0.service |
Mount soc0 overlay for modem |
| mptcp-setup.service |
Configure MPTCP endpoints |
| hotspot.service |
Create AP, start hostapd + dnsmasq |
| ss-client.service |
Shadowsocks MPTCP client |
| mptcp-proxy.service |
Redsocks transparent proxy |
Troubleshooting
Modem Won't Start
- Check soc0 overlay:
ls /sys/devices/soc0/image_crm_version
- Check libraries:
ldd /usr/bin/particle-tachyon-rild
- Check rmtfs symlinks:
ls -la /persist/rmtfs/
- Check logs:
journalctl -u particle-tachyon-rild
No 5G IP
- Check SIM slot:
particle-tachyon-ril-ctl active_sim --get
- Try reconnect:
particle-tachyon-ril-ctl disconnect && particle-tachyon-ril-ctl connect
- Check APN settings in carrier config
MPTCP Not Working
- Check kernel:
cat /proc/sys/net/mptcp/enabled (should be 1)
- Check endpoints:
ip mptcp endpoint show
- Verify shadowsocks has
"mptcp": true in config
Hotspot Clients No Internet
- Check ip_forward:
cat /proc/sys/net/ipv4/ip_forward
- Check NAT rules:
iptables -t nat -L POSTROUTING
- Check redsocks running:
pgrep redsocks
Credits
- Setup done with assistance from Claude Code (AI)
- Hardware: Particle Tachyon (QCM6490)
- Based on: particle-iot/tachyon-ubuntu-24.04-kernel
Why This Matters
- First documented 5G modem on Ubuntu 24.04 for Tachyon
- Real MPTCP bonding - not load balancing, actual bandwidth aggregation
- Transparent to clients - any device on hotspot benefits, no app needed
- Open source - no Speedify subscription required
Questions?
This took many sessions of trial and error. Key insight: the soc0 overlay hack is what makes the modem work on 24.04. Without it, rild refuses to start.
Feel free to ask questions or share improvements!