This is an old revision of the document!
Table of Contents
Raspberry Pi and Linux Kernel AX.25 support
This page documents how to set up a Raspberry Pi running Raspberry Pi OS Lite (32 bit).
Alternative reading:
Mike has also written up a guide on his own site for configuring all the bits.
There is also documentation in TLDP: https://tldp.org/HOWTO/Netrom-Node-5.html
Equipment
My setup consists of:
- Raspberry Pi 4b
- CG Antenna 2000 Radio Interface
- Behringer UMC202HD Audio Interface
- Tait 2010 VHF Radio
- ICOM IC7300 HF Radio
Software Prereqs
sudo apt install libax25 ax25-apps ax25-tools socat direwolf
Notes:
- make absolutely certain that you are using a 32bit kernel if you have 32bit user binaries. I somehow ended up with a 64bit kernel and things broke in very subtle ways. Check that
uname -m
returnsarmv7l
if you installed a 32bit OS! - you may need to use
rpi-update
to get the latest series 6 kernel
TNC
I use Direwolf to run the two radios. Here is my Direwolf config:
ADEVICE plughw:1,0 ACHANNELS 1 ADEVICE1 plughw:4,0 ACHANNELS 1 CHANNEL 0 MYCALL M0GZP MODEM 1200 PTT /dev/ttyUSB0 RTS CHANNEL 2 MYCALL M0GZP-1 MODEM 300 7@30 E PTT RIG 3073 /dev/ttyUSB1 IL2PTX AGWPORT 0 KISSPORT 8001 0 KISSPORT 8002 2
This sets up two channels:
CHANNEL 0
talks to sound cardplughw:1,0
(which is the UMC202HD) and does PTT on/dev/ttyUSB0
(which is the CG Antenna 2000)CHANNEL 1
talks to sound cardplughw:4,0
(which is the 7300) and does PTT on/dev/ttyUSB1
(which is the 7300)
It also disables AGW, and sets up two KISS listeners on port 8001 (assigned to channel 0) and 8002 (assigned to channel 2)
AX.25 Configuration Files
The config files are all in /etc/ax25
. Here is what I set up for the three key files:
axports
This file sets up two AX.25 ports, one for VHF and one for HF
v144 M0GZP-1 19200 236 4 144.375 Mhz 1k2bps HF M0GZP-2 19200 236 4 HF 300bps
nrports
This file sets up a NET/ROM port aliased as GZPNOD
netrom M0GZP-7 GZPNOD 236 Linux Switch Port
nrbroadcast
This file configures how our AX.25 ports will broadcast NET/ROM nodes. My VHF node sets all seen nodes to a default quality of 220, and will broadcast any node with a minimum quality of 200. The HF node on the other hand sets all nodes to a default quality of 199 (so as not to advertise HF nodes over VHF), and will broadcast nodes with a minimum quality of 199.
v144 5 220 200 1 HF 5 199 199 1
Startup Scripts
I wrote some scripts to start everything up.
/usr/sbin/startRadio.sh
This script will:
- Create two socat pseudo-tty interfaces, one to each of the network KISS ports
- Use
kissattach
to attach these interfaces to kernel ax.25 network interfaces - Load the
netrom
module and attach it to the port defined in nrports - Run the netrom userspace daemon which handles the netrom broadcasts
#!/bin/bash echo -n Creating socat sockets... socat pty,echo=0,link=/tmp/kiss8001,wait-slave tcp:127.0.0.1:8001 & socat pty,echo=0,link=/tmp/kiss8002,wait-slave tcp:127.0.0.1:8002 & sleep 1 echo Done echo -n Attaching KISS interfaces for direwolf... kissattach `ls -l /tmp/kiss8001 | awk '{ print $11 }'` v144 sleep 1 kissattach `ls -l /tmp/kiss8002 | awk '{ print $11 }'` HF sleep 1 echo Done echo -n 'Bringing up NET/ROM runtime...' modprobe netrom nrattach netrom netromd -i -l -d echo -n Restoring node tables... [ -x /etc/ax25/nodesave.sh ] && /etc/ax25/nodesave.sh echo Done
/usr/sbin/stopRadio.sh
This script does the opposite to startRadio, killing the processes and taking down the interfaces
#!/bin/bash echo Saving node tables... /usr/sbin/nodesave > /etc/ax25/nodesave.sh && chmod 755 /etc/ax25/nodesave.sh echo Killing all kissattach processes killall kissattach echo Killing all socat processes in case they do not end cleanly killall socat echo Killing the netromd process killall netromd echo Taking down the netrom interface ifconfig nr0 down echo Removing kernel modules rmmod netrom rmmod mkiss rmmod ax25 echo Taking down the AX.25 interfaces ifconfig ax0 > /dev/null 2>&1 && ifconfig ax0 down ifconfig ax1 > /dev/null 2>&1 && ifconfig ax1 down echo Done
/lib/systemd/system/ax25.service
This script registers the ax25 service with systemd
[Unit] Description=Start up radio processes [Service] Type=oneshot ExecStart=/usr/sbin/startRadio.sh ExecStop=/usr/sbin/stopRadio.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target
Time to run
To start things up, use systemctl start – then use status to see how it went:
szymon@radio:~ $ sudo systemctl start ax25 szymon@radio:~ $ sudo systemctl status ax25 ● ax25.service - Start up radio processes Loaded: loaded (/lib/systemd/system/ax25.service; disabled; vendor preset: enabled) Active: active (exited) since Wed 2023-04-12 22:16:27 BST; 4s ago Process: 2476 ExecStart=/usr/sbin/startRadio.sh (code=exited, status=0/SUCCESS) Main PID: 2476 (code=exited, status=0/SUCCESS) Tasks: 5 (limit: 4915) CPU: 151ms CGroup: /system.slice/ax25.service ├─2477 socat pty,echo=0,link=/tmp/kiss8001,wait-slave tcp:127.0.0.1:8001 ├─2478 socat pty,echo=0,link=/tmp/kiss8002,wait-slave tcp:127.0.0.1:8002 ├─2486 kissattach /dev/pts/4 v144 ├─2501 kissattach /dev/pts/2 HF └─2519 netromd -i -l -d Apr 12 22:16:25 radio startRadio.sh[2483]: AX.25 port v144 bound to device ax0 Apr 12 22:16:25 radio startRadio.sh[2486]: AX.25 port v144 bound to device ax0 Apr 12 22:16:26 radio startRadio.sh[2499]: AX.25 port HF bound to device ax1 Apr 12 22:16:26 radio startRadio.sh[2501]: AX.25 port HF bound to device ax1 Apr 12 22:16:27 radio startRadio.sh[2476]: Done Apr 12 22:16:27 radio startRadio.sh[2476]: Bringing up NET/ROM runtime... Apr 12 22:16:27 radio startRadio.sh[2512]: NET/ROM port netrom bound to device nr0 Apr 12 22:16:27 radio netromd[2519]: starting Apr 12 22:16:27 radio startRadio.sh[2476]: Restoring node tables...Done Apr 12 22:16:27 radio systemd[1]: Finished Start up radio processes. szymon@radio:~ $
You will see some new network interfaces on ifconfig (I've removed my normal interfaces):
ax0: flags=67<UP,BROADCAST,RUNNING> mtu 236 ax25 M0GZP-1 txqueuelen 10 (AMPR AX.25) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2 bytes 77 (77.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ax1: flags=67<UP,BROADCAST,RUNNING> mtu 236 ax25 M0GZP-2 txqueuelen 10 (AMPR AX.25) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2 bytes 77 (77.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 nr0: flags=193<UP,RUNNING,NOARP> mtu 236 netrom M0GZP-7 txqueuelen 1000 (AMPR NET/ROM) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
You can now use axcall
to contact another node, axlisten
to monitor traffic, etc.