Mesh Potato Firmware How To


This page describes how to to build and install the Mesh Potato firmware. The following firmware components are required:

  • Xilinx CPLD JED file (e.g. fxsinterface.jed)
  • Atmega firmware (e.g. uart2spi.hex)
  • RedBoot boot loader (e.g. redboot.rom)
  • Board configuration data (e.g. dir_300_MAC022B04203E3_board_config.bin)
  • Linux Kernel and root file system (e.g. openwrt-atheros-vmlinux.lzma and openwrt-atheros-root.squashfs)
  • Network configuration, and optionally Wifi and B.A.T.M.A.N. (/etc/config/network etc)
  • FXS Interface drivers (mp.ko, 8250mp.ko,
  • Asterisk configuration (extensions.conf, sip.conf etc)

You probably don't have to compile any of your own firmware - just grab pre-compiled firmware files from [1] (currently off-line), or [2]. However if you would like to build any firmware the first step is check out the Village Telco software.

The Village Telco software is based on a recent OpenWRT distribution. We have added several directories to support the Mesh Potato development. Each of these directories will have a README or README.txt with detailed documentation. Here is the top level README for the Village Telco software.

Important Notes and Gotchas

  1. The boot loader (and Linux serial console if compiled in) runs at 9600 baud, 8 data bits, 1 stop bit, no parity.
  2. The default Linux IP is Just after flashing Linux you can use telnet with no username or password. After you set the password (using the passwd command) telnet will be disabled and ssh enabled.
  3. The reset button currently doesn't do anything (its function is determined by software that is not written yet). Power cycle the MP to reset it.
  4. The Xilinx CPLD needs to be flashed before the MP will boot correctly, as it routes serial console signals. If the CPLD is not flashed then the serial console may be "one way" - you will be able to see serial output but not type any commands. The Atmega firmware is only required for FXS port functionality, e.g. Linux will boot OK without it.
  5. The board configuration data sets the MAC address and should therefore be edited for each MP. The boot loader will run without the board configuration data however Linux will not boot without it (you will get a seg fault just after the kernel complains about no board configuration data). At this stage, the board configuration data must be written via JTAG. In the future we hope to be able to use RedBoot to write configuration data.
  6. The Linux serial console is not enabled by default on the Mesh Potato, so you won't see the normal serial boot sequence. Here are instructions on how to re-enable it.

Know Your Potato

Mesh Potato Connectors

Mesh Potato with FXS Module and RS232 Daughter Board

Xilinx CPLD Compile and Flash

In the Villagetelco Subversion directory change to david/cpld and execute make. To compile the Xilinx CPLD sources the software iverilog must be installed. The Ubuntu/Debian package named verilog contains iverilog.

Flashing instructions are here

Atmega Compile and Flash

In the Villagetelco Subversion directory change to david/avr and perform make. To compile the Atmel AVR sources the software packages (Ubuntu/Debian) avr-gcc and avr-libc must be installed.

Full instructions are here

The two most important steps are to program the lfuse and flash the [[ | Atmega uart2spi.hex firmware]]:

# avrdude -c igloo -p m8 -U lfuse:w:0xff:m
# avrdude -c igloo -p m8 -e -U flash:w:uart2spi.hex

Note the shorting link J1 should be removed while programming at Atmega to avoid interference between the SPI clock and the 2.048MHz clock oscillator. Replace the link after programming the Atmega.

Boot Loader

The RedBoot boot loader is used for the Mesh Potato. Our boot loader is very similar to the code used for other Atheros SoCs, with some slight modifications for the 8M flash and default GPIO configuration needed for the MP (e.g. GPIO=0 to tell the CPLD to enable the RS232 console at boot time).

Full instructions on compiling and testing the boot loader are here. The following sections provide some additional notes and a summary of the key steps.

Compiling and Testing the Boot Loader

Check out the villagetelco subversion repository, enter the redboot subdirectory and perform:

$ make ap61

There are two images we are interested in:


The examples below assume you have a Mesh Potato with a version of Redboot running, the Mesh Potato ip addresses are configured (ip_address command), and the redboot.elf and redboot.rom files have been copied to your tftp server.

The redboot.elf image can be tested using an existing Redboot:

RedBoot> load redboot.elf
RedBoot> go

The redboot.rom image can be flashed to upgrade Redboot:

RedBoot> load -r -b %{FREEMEMLO} redboot.rom
RedBoot> fis create -l 0x30000 -e 0xbfc00000 RedBoot
RedBoot> reset

Be careful - if there is a bug or an error in the flashing process you may lose you boot loader entirely. If this happens you can use a JTAG cable (see below) to recover.

Ecos Setup

NOTE Ecos Setup is not necessary for the compiling the Mesh Potato boot loader - we have included the toolchain in SVN. This information is provided only for completeness.

Redboot is a based on Ecos. To compile the Redboot sources we need to install the Ecos mipsisa32 toolchain. Prior to this step we have to install the tcl, tk, and libstdc++5 libraries, if they are not installed already. From a normal user account on your Linux system (read: non-root!) download the ecos-installer file and execute it:

$ sh ecos-install.tcl

Follow the instructions, the installer program is user-friendly. The installer will create a script that correctly sets up the paths to the toolchain(s). This must be executed before you can use the toolchain every time you log into a new terminal again.

Flashing the Boot Loader using JTAG

Full instructions on for JTAG flashing are are here. The following sections provide some additional notes and a summary of the key steps.

If you have a new MP01 which has no boot loader, or you have accidentally lost your boot loader you can use a simple DIY JTAG cable to flash the boot loader and board configuration information. As long as the hardware is not physically damaged you can always revive the MP this way.

Prerequisites Get a working JTAG cable, compile jtagspi and get the PCs parallel port working.

Unbuffered cable

The easiest and cheapest way is to solder a unbuffered JTAG adaptor cable that connects to a PCs parallel port. All you need is a male DB-25 connector and a couple of 100 Ohm resistors and the plugs that fit the pins on the JTAG connector.

pin 2--->100 ohms ---> TDI

pin 3--->100 ohms ---> TCK

pin 4--->100 ohms ---> TMS

pin 5--->100 ohms ---> nTRST

pin 11--->100 ohms ---> TDO

pin 25-------GND------> GND

You might solder the resistors straight to a DB-25 plug. It is recommended to keep the cable short, some people have reported problems using cables exceeding 50cm length.

Buffered "Wiggler compatible" cable

You can also build a buffered "Wiggler compatile" JTAG cable which is slightly more complicated. One advantage is that it has a nSRST (System RESET) pin - hence it can be used for in-system-debugging with suitable software. Also cable length should be less critical. I have used the Wiggler-compatible schematic here on the Openwrt page (currently offline, so this link aims to the page in the Internet archive, which is usually slow)

The main difference is that the buffered cable features a 74HC244 TTL buffer chip on board and a NPN transistor to invert the nSRST signal. I have soldered the circuit to a breadboard. The DB-25 socket pins don't fit into the 2.54mm grid of a normal breadboard without bending. For my first JTAG cable I have bend the pins, for the second I bought a breadboard that was prepared for mounting two DB-25 sockets. You may be able to get it in your favorite electronics store, too.

Setting up the jtapgspi software package

To use JTAG we are using jtagspi. You can get it from the Mesh-Potato subversion repository at If you have checked out the Villagetelco Subversion repository, you already have a local copy. We have modified the header file tjtag.h so it matches the schematics of the unbuffered and "Wiggler-compatible" cables we are using. If you need to change the pinout for a different JTAG cable you'll find this is well documented in the header file.

All you have to do to compile is to perform "make" in the jtagspi directory, further instructions are in the jtagspi README.

I have noticed that on my laptop running Kubuntu 9.04 the module lp is loaded. It is recommend to unload this module using rmmod. You need to be the root user to use the jtag software.

Pinout description and location of MP JTAG header are described in the jtagspi README.

Flashing the Mesh Potato Using JTAG

This section contains the basic steps to flash the MP using JTAG, for more detailed instructions see the jtagspi README.

Check the cable detects the board OK:

# ./tjtagspi -probeonly

Flash the boot loader:

# cp redboot.rom CUSTOM.BIN
# ./tjtagspi -flash:custom /start:0 /length:25ed0 /window:0

This takes about 45 minutes on my PC. NOTE the length parameter must match the length of redboot.rom, check with a Hex calculator.

Flash the board configuration data.

# cp dir_300_MAC022B04203E3_board_config.bin CUSTOM.BIN
# ./tjtagspi -flash:custom /start:7f0000 /length:10000 /window:0

Note that the MAC address should be changed for every Mesh Potato by editing the board config data file before flashing. The dir_300 file above is provided as a starting point. The board config data also contains radio calibration data that may need editing for each Mesh Potato.

Editing the MAC address

To change the MAC address of a MP we need to edit the board configuration data file then (re) flash it:

First make a copy of the board config file:

cp dir_300_MAC022B04203E3_board_config.bin board_config.bin

Then use a hex editor (I used hexedit in Linux), to set the 6 bytes for 0x60 (WLAN) and 0x66 (LAN), for example this is my MP01-001 setting:

00000060   00 09 45 56  AC 2E 00 09  45 56 AC 2F  00 80 C8 53 

WLAN MAC: 00 09 45 56 AC 2E
LAN MAC.: 00 09  45 56 AC 2F

Use jtagspi utility to write the board config to flash:

# cp board_config.bin CUSTOM.BIN
# ./tjtagspi -flash:custom /start:7f0000 /length:10000 /window:0


Check out the Village Telco software

Build Linux for the Mesh Potato

Flashing Linux Images from Redboot

Copy openwrt-atheros-vmlinux.lzma and openwrt-atheros-root.squashfs to your tftp server, then:

RedBoot> fis init
RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma
RedBoot> fis create -e 0x80041000 -r 0x80041000 vmlinux.bin.l7
RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-root.squashfs
RedBoot> fis create rootfs
RedBoot> fconfig -d
Run script at boot: true
Boot script:
Enter script, terminate with empty line
>> fis load -l vmlinux.bin.l7
>> exec
RedBoot> reset

For upgrades you can omit the fconfig -d step. Typing all of the above can be painful - I copy from this page and paste into my terminal emulator (minicom).

For more information the DIR-300 Page has a dump of an actual Redboot session.

The default Linux IP is - try ping and telnet. When you set the password (using passwd) telnet will be disabled and ssh enabled.

Flashing Linux Images from Linux

This has the advantage of not requiring boot loader or serial access.

1. scp images to the box.

[david$host ]$ scp bin/openwrt-atheros-vmlinux.lzma root@mp:/tmp
[david$host ]$ scp bin/openwrt-atheros-root.squashfs root@mp:/tmp

2. look up flash blocks

root@OpenWrt:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00030000 00010000 "RedBoot"
mtd1: 000b0000 00010000 "vmlinux.bin.l7"
mtd2: 00300000 00010000 "rootfs"
mtd3: 000c0000 00010000 "rootfs_data"
mtd4: 0000f000 00010000 "FIS directory"
mtd5: 00001000 00010000 "RedBoot config"
mtd6: 00010000 00010000 "boardconfig"

3. write kernel image:

root@OpenWrt:/tmp# mtd write /tmp/openwrt-atheros-vmlinux.lzma vmlinux.bin.l7

4. write rootfs:

root@OpenWrt:/tmp# mtd write /tmp/openwrt-atheros-root.squashfs rootfs

5. reboot:

root@OpenWrt:/tmp# reboot

NOTE when you reflash the rootfs network settings will return to default, e.g. an IP of

Testing Linux images without Flashing

Copy bin/openwrt-atheros-vmlinux.elf to your tftp server.

At the boot loader prompt:

RedBoot> load openwrt-atheros-vmlinux.elf
RedBoot> go

Linux should boot immediately.

During development you can automate this procedure using a boot script:

RedBoot> fconfig -d
Run script at boot: true
Boot script:
Enter script, terminate with empty line
>> load openwrt-atheros-vmlinux.elf
>> go

To start a new version of Linux copy the openwrt-atheros-vmlinux.elf file to your tftp server and simply power cycle the Mesh Potato.

Flashing Linux Images with AP51 Flash Utility

This is perhaps the easiest and most reliable way to flash your Mesh Potato. For Ubuntu users, it has the added bonus of ignoring the NetworkManager which under other circumstances will try to re-assert control over the ethernet port. The EasyFlash utility is downloadable from:

1) Download the command-line utility and save it somewhere in your path. I chose /usr/local/bin.

2) Run chmod +x on the file to make is executable.

3) Now pick up the most recent MP firmware images from You will need the .squashfs file and the .lzma file.

4) Make sure you are in the directory where you downloaded the firmware and make sure your Mesh Potato is currently unplugged.

5) Connect an ethernet cable from your PC/laptop to the Mesh Potato

6) You will need to execute the following command as root so that the utility can take control of the ethernet port.

# sudo ap51-flash eth0 openwrt-atheros-root-rv233.squashfs openwrt-atheros-vmlinux-rv233.lzma

where eth0 is your ethernet port, substitute as appropriate and of course the appropriate file name for the version of the firmware that you have downloaded. After running the ulitity, you should see the following:

Reading rootfs file openwrt-atheros-root-rv233.squashfs with 4325376 bytes...
Reading kernel file openwrt-atheros-vmlinux-rv233.lzma with 720896 bytes...
rootfs(0x006f0000) + kernel(0x000b0000) + nvram(0x00000000) sums up to
0x007a0000 bytes
No packet.
No packet.
No packet.
No packet.

7) Power up your Mesh Potato

8) You should see the repeated No Packet. No packet. lines change to:

No packet.
No packet.
Peer MAC: 00:09:45:57:a8:23
Peer IP :
Your MAC: 00:ba:be:ca:ff:ee
Your IP :
Setting IP address...
Loading rootfs...
Sending rootfs, 8448 blocks...
Initializing partitions...
Flashing rootfs...
Loading kernel...
Sending kernel, 1408 blocks...
Flashing kernel...
Setting boot_script_data...
Done. Restarting device...

During the flashing process the PWR and LINK leds should be lit and you may see the occasional flash from the ACT led. The whole process should take a couple of minutes. Obviously, under no circumstances should you power off or disconnect the ethernet cable at this point.

9) Wait for the WIFI led to start flashing (this may take a while) and then look for your Mesh Potato on Any previous settings you may have had have now been replaced by the default settings of the firmware.

Linux Serial Console Support

On the Mesh Potato Linux serial console support is not compiled into the kernel by default, as the RS232 UART is used for the FXS port. The serial console still works with Redboot, and the Linux boot log is still dumped out of the serial port, however no interactive Linux serial console is available after Linux starts.

To re-enable the Linux serial console:

1/ Edit the file target/linux/atheros/config-default:

Change the last line:



$ tail target/linux/atheros/config-2.6.26

2/ Edit build_dir/linux-atheros/linux-

Around line 204 change:




4/ Then rebuild Linux, and boot with the new kernel.

Typical Linux Boot Sequence - Serial Support Not Compiled in

The default MP kernel does not have serial support compiled in, so the serial port is ominously quiet during booting. You can re-enable serial support with these instructions.

+Ethernet eth0: MAC address 00:09:45:56:ac:2f
IP:, Gateway:
Default server:

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Non-certified release, version v1.3.0 - built 14:07:19, Jun  9 2009

Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

Board: ap61
RAM: 0x80000000-0x81000000, [0x8003dd50-0x80fe1000] available
FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
== Executing boot script in 5.000 seconds - enter ^C to abort
RedBoot> fis load -l vmlinux.bin.l7
Image loaded from 0x80041000-0x80259086
RedBoot> exec
Now booting linux kernel:
 Base address 0x80030000 Entry 0x80041000
 Cmdline :

Despite this lack of information the network should come up after a little while and respond to ping/telnet/ssh.

Typical Linux Boot Sequence - Serial Support Compiled in

+Ethernet eth0: MAC address 00:22:b0:42:03:e4
IP:, Gateway:
Default server:

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Non-certified release, version v1.3.0 - built 16:59:11, Jun  8 2009

Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

Board: ap61
RAM: 0x80000000-0x81000000, [0x8003dd50-0x80fe1000] available
FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
== Executing boot script in 5.000 seconds - enter ^C to abort
RedBoot> load openwrt-atheros-vmlinux.elf
Using default protocol (TFTP)
Entry point: 0x801f8850, address range: 0x80041000-0x80262086
RedBoot> go
Linux version (david@bunny) (gcc version 4.1.2) #3 Mon Jun 8 15:07:39 9memcfg: 0x141168  memsize: 0x1000000
CPU revision is: 00019064 (MIPS 4KEc)
Determined physical RAM map:
 memory: 01000000 @ 00000000 (usable)
Initrd not found or empty - disabling initrd
Zone PFN ranges:
  Normal          0 ->     4096
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0:        0 ->     4096
Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 4064
Kernel command line: console=ttyS0,9600 rootfstype=squashfs,jffs2 init=/etc/pretPrimary instruction cache 16kB, VIPT, 4-way, linesize 16 bytes.
Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 16 bytes
PID hash table entries: 64 (order: 6, 256 bytes)
console [ttyS0] enabled
Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 13692k/16384k available (1773k kernel code, 2692k reserved, 289k data, )SLUB: Genslabs=6, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Mount-cache hash table entries: 512
net_namespace: 644 bytes
NET: Registered protocol family 16
WARNING: broken board data detected
Radio config found at offset 0xf8(0x1f8)
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP reno registered
NET: Registered protocol family 1
ar531x: Registering GPIODEV device
squashfs: version 3.0 (2006/03/15) Phillip Lougher
Registering mini_fo version $Id$
JFFS2 version 2.2. (NAND) (SUMMARY)  .. 2001-2006 Red Hat, Inc.
msgmni has been set to 26
io scheduler noop registered
io scheduler deadline registered (default)
gpiodev: gpio device registered with major 254
gpiodev: gpio platform device registered with access mask FFFFFFFF
Serial: 8250/16550 driver $Revision: 1.90 $ 1 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0xb1100003 (irq = 37) is a 16550A
eth0: Atheros AR231x: 00:22:b0:42:03:e4, irq 4
ar2313_eth_mii: probed
eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=0:01)
cmdlinepart partition parsing not available
Searching for RedBoot partition table in spiflash at offset 0x7d0000
6 RedBoot partitions found on MTD device spiflash
Creating 6 MTD partitions on "spiflash":
0x00000000-0x00030000 : "RedBoot"
0x00030000-0x000e0000 : "vmlinux.bin.l7"
0x000e0000-0x007d0000 : "rootfs"
mtd: partition "rootfs" set to be root filesystem
mtd: partition "rootfs_data" created automatically, ofs=330000, len=4A0000
0x00330000-0x007d0000 : "rootfs_data"
0x007d0000-0x007df000 : "FIS directory"
0x007df000-0x007e0000 : "RedBoot config"
0x007e0000-0x00800000 : "boardconfig"
Registered led device: gpio1
Registered led device: gpio2
Registered led device: gpio3
Registered led device: gpio4
Registered led device: wlan
TCP vegas registered
NET: Registered protocol family 17
802.1Q VLAN Support v1.8 Ben Greear <>
All bugs added by David S. Miller <>
VFS: Mounted root (squashfs filesystem) readonly.
Freeing unused kernel memory: 120k freed
Please be patient, while OpenWrt loads ...
eth0: Configuring MAC for full duplex
Algorithmics/MIPS FPU Emulator v1.5
- preinit -
Press CTRL-C for failsafe
jffs2 not ready yet; using ramdisk
mini_fo: using base directory: /
mini_fo: using storage directory: /tmp/root
- init -

Please press Enter to activate this console. device eth0 entered promiscuous moebr-lan: port 1(eth0) entering learning state
br-lan: topology change detected, propagating
br-lan: port 1(eth0) entering forwarding state
PPP generic driver version 2.4.2
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky <>
ip_tables: (C) 2000-2006 Netfilter Core Team
nf_conntrack version 0.5.0 (1024 buckets, 4096 max)
ipt_time loading
wlan: trunk
ath_hal: module license 'Proprietary' taints kernel.
ath_hal: 2008-10-02 (AR5212, AR5312, RF5111, RF5112, RF2316, RF2317, REGOPS_FUN)ath_rate_minstrel: Minstrel automatic rate control algorithm 1.2 (trunk)
ath_rate_minstrel: look around rate set to 10%
ath_rate_minstrel: EWMA rolloff level set to 75%
ath_rate_minstrel: max segment size in the mrr set to 6000 us
wlan: mac acl policy registered
ath_ahb: trunk
Atheros HAL provided by OpenWrt, DD-WRT and MakSat Technologies
wifi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
wifi0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 3swifi0: turboG rates: 6Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: H/W encryption support: WEP AES AES_CCM TKIP
ath_ahb: wifi0: Atheros 2317 WiSoC REV1: mem=0xb0000000, irq=3
jffs2_scan_eraseblock(): End of filesystem marker found at 0x0
jffs2_build_filesystem(): unlocking the mtd device... done.
jffs2_build_filesystem(): erasing all blocks after the end marker... done.
mini_fo: using base directory: /
mini_fo: using storage directory: /jffs

BusyBox v1.11.2 (2009-05-18 13:36:36 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 KAMIKAZE (bleeding edge, r91) -------------------
  * 10 oz Vodka       Shake well with ice and strain
  * 10 oz Triple sec  mixture into 10 shot glasses.
  * 10 oz lime juice  Salute!
root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                    2.3M      2.3M         0 100% /
/dev/root                 2.3M      2.3M         0 100% /rom
tmpfs                     6.7M     60.0k      6.7M   1% /tmp
tmpfs                   512.0k         0    512.0k   0% /dev
mini_fo:/tmp/root         2.3M      2.3M         0 100% /tmp/root
/dev/mtdblock3            4.6M    268.0k      4.4M   6% /jffs
mini_fo:/jffs             2.3M      2.3M         0 100% /

FXS Interface Drivers

1. If you haven't already done so build Linux for the Mesh Potato. This will create many of the support files (toolchain, kernel, Asterisk) required for the next steps.

2. Download the serial_core driver:

[david@bunny villagetelco]$ scp build_dir/linux-atheros/linux- root@mp:

3. Build and download the kernel mode drivers:

[david@host villagetelco]$ cd david/drivers
[david@host driver]$ make
[david@host david]$ scp mp.ko 8250mp.ko root@mp:

4. Build and download the Asterisk channel mode driver:

[david@host driver]$ cd ../asterisk
[david@host asterisk]$ make
[david@host driver]$ scp root@mp:/usr/lib/asterisk/modules/

5. On the Mesh Potato create this file and set up a link so it is called at boot time

root@OpenWrt:~# vi /etc/init.d/mp
mknod -m 666 /dev/8250mp c 33 0
mknod -m 666 /dev/mp c 34 0
insmod /root/serial_core.ko
insmod /root/8250mp.ko
insmod /root/mp.ko

root@OpenWrt:~# chmod a+x /etc/init.d/mp
root@OpenWrt:~# ln -s /etc/init.d/mp /etc/rc.d/S95mp

You can start this script manually or reboot the MP. Looking at dmesg, you should see something like this when the drivers start:

Registered 8250mp char driver on major 33
Serial: 8250/16550 driver for the Mesh Potato 1 ports, IRQ sharing disabled
ttyS0: autoconf (0x0000, 0xb1100003): iir=3 iir1=6 iir2=6 serial8250_clear_fifos()
serial8250: ttyS0 at MMIO 0xb1100003 (irq = 37) is a 16550A
mask: 0xbd
CR: 0xbd
INT: 0xc6
mp: checking reg0 of 3215:
mp:  reg0.....: 0x3
mp:  part number: 0x0
mp:  revision...: 0x0
ProSLIC module is Si3215
Start manual calibration
Module 0: Installed -- AUTO FXS
Registered mp char driver on major 34

Measure the voltage across the outer 2 pins of the 3 pin FXS module connector. The voltage should be around 48V. An analog telephone connected to the MP should be alive but fairly quiet (e.g. DTMF dialing should work). Dial tone will appear when Asterisk is started.



The default IP is On a freshly flashed MP you can telnet in, after setting the password you must use ssh. To reconfigure the LAN simply edit /etc/config/network.


The Mesh-Potato is based on a Atheros SoC (System on a chip) and thus uses the Madwifi wireless driver. One day we will use the Atheros drivers shipped in the Linux kernel, but Atheros SoCs are not yet supported by the Linux wireless drivers and they are not yet as stable as Madwifi.

The Madwifi driver creates a main control interface for each Atheros Wifi interface (wifi0 for the first Wifi interface, wifi1 for the second Wifi interface) and so on. Since the MP01 has only one interface you'll see just one wireless interface if you execute iwconfig on the command line. In order to use this Wifi interface you have to create at least one virtual interface, which are called VAPs (Virtual Access Points). Calling the virtual interfaces VAPs is rather confusing because they can do much more than just being an Accesspoint (AP). You can create VAPs that are master mode (Access-Point mode), station mode (client mode), ad-hoc mode, ad-hoc demo mode, monitor mode and WDS mode (Wireless Distribution System mode). And you can create combinations of VAPs as well - for example you can create one VAP in ad-hoc demo mode and one VAP in monitor mode at the same time. Beware: Not all combinations of VAPs are possible or will work flawlessly without crashing the system.

Hence you can run your MP as an AP (how boring), AP client station (thats what your WiFi enabled phone, laptop, PDA usually does) and so on. But the real thing is mesh networking - why would we call the Mesh-Potato the Mesh-Potato if we'd use it to run a stupid AP or AP-client. However - feel free to use it as you wish, naturally!

There are two ways to set up the Madwifi interface:

  • Openwrt Kamikaze (the meta Linux distribution that the MP firmware is based on) by default uses UCI (unified configuration interface). The idea is to unify the way the system communicates with interfaces and programs. This adds another layer between the actual programs and the configuration so you have to know how to set things the UCI-way. The advantage clearly lies in its unification effort that should make remote administration more easy. Also there are web frontends like LUCI which are based on UCI.
  • The generic Linux command line interface way. You can perform the commands step by step in the way they work in all Linux environments and thus bypass the detour via UCI. Once you are satisfied with the result you can automate things just by copying the list of commands into a script file located in /etc/init.d, make it executable and link to it from the /etc/rc.d directory. Being a Madwifi user for a long time I tend to hesitate getting accustomed to yet another layer between me and the wireless programs to control the interface so I'm currently still following this way for now. Once we switch to a LUCI based web interface we'll have to use UCI for everything which can be controlled by the user.

Setting up ad-hoc interfaces for mesh networking

Let's set up a VAP for mesh networking first. Due to the multipoint-to-multipoint topology of a mesh this must be either ad-hoc mode or ad-hoc demo mode. The following command will create a VAP in ahdemo mode.

This mode works rock solid (I can run it for weeks without any hiccups) in a mesh and it doesn't send beacons (hence adhoc-demo mode) which is a bliss, because beacons are sent at lowest data rate and create noise in the mesh and hence consume a lot of airtime. The disadvantage is that other non-mesh devices may not detect our mesh network since they can't detect any beacons. It is also possible to mix ad-hoc and ad-hoc demo mode devices.

 wlanconfig ath0 create wlandev wifi0 wlanmode ahdemo 

In case we want to delete a VAP interface we can perform:

wlanconfig ath0 destroy 

In order to use the "normal" ad-hoc mode with beacons (IBSS mode) the command to create the VAP interface is slightly different:

wlanconfig ath0 create wlandev wifi0 wlanmode adhoc nosbeacon

Note the nosbeacon option - this will force the interface not to synchronize hardware timers to timestamps received via beacons which can result in hardware clock skewes. Using this option is important, otherwise we will like face instabilities (notably stuck beacons and stuck transmit queues)

We can now use the iwconfig command to configure the VAP wireless interface. In this example I use wireless channel 11, name the wireless cell "villagetelco" and set the IBSS-ID (the cell-ID number - somewhat similar to a MAC address - which must be provided and the same at all ad-hoc and ad-hoc demo nodes in the wireless network to 00:CA:FF:EE:BA:BE)

iwconfig ath0 essid villagetelco
iwconfig ath0 channel 11
iwconfig ath0 ap 00:CA:FF:EE:BA:BE
ifconfig ath0

Hence the full script for our first MP01 device would be:

# Lines beginning with # are comments

# Create ahdemo VAP interface
wlanconfig ath0 create wlandev wifi0 wlanmode ahdemo

# Set essid (wireless cell name)
iwconfig ath0 essid villagetelco

# Select channel
iwconfig ath0 channel 11

# Set Cell-ID of the wireless cell
iwconfig ath0 ap 00:CA:FF:EE:BA:BE

# Configure IP address of the VAP interface
ifconfig ath0

Save this script to /etc/init.d and name it meshnetwork. Make it executable:

chmod +x /etc/init.d/meshnetwork 

Change into the directory /etc/rc.d and create a link:

cd /etc/rc.d
ln -s ../init.d/meshnetwork S90meshnetwork

Setting up more MP devices is easy. Just copy the script and the steps, but change the IP address. The IP addresses must be individual. Hence I would put this script in MP01 number 2.

# Lines beginning with # are comments

# Create ahdemo VAP interface
wlanconfig ath0 create wlandev wifi0 wlanmode ahdemo

# Set essid (wireless cell name)
iwconfig ath0 essid villagetelco

# Select channel
iwconfig ath0 channel 11

# Set Cell-ID of the wireless cell
iwconfig ath0 ap 00:CA:FF:EE:BA:BE

# Configure IP address of the VAP interface
ifconfig ath0

Setting up wireless interfaces for accesspoint mode

The only difference is that we create a VAP with a different mode in the script and we don't need to set the Cell-ID since it is identical with the MAC address of the wireless interface. For more details read the previous section.

wlanconfig ath0 create wlandev wifi0 wlanmode ap
iwconfig ath0 essid my_new_accesspoint
iwconfig ath0 channel 11
ifconfig ath0

Setting up wireless interfaces for station (accesspoint client) mode

That's the normal mode for consumer client devices. You can connect to a AP with the MP. Note that you usually have to run a DHCP client to get the IP settings. A dhcp client program is not included in the firmware but can be installed via the package management system.

wlanconfig ath0 create wlandev wifi0 wlanmode sta
iwconfig ath0 essid the_accesspoint_I_want_to_connect_to

Adding a monitor VAP wireless interface to monitor raw wireless packages

This is an interesting mode for the "War-Drivers" and wireless network admins out there. Especially nice when you dump traffic with tcpdump and analyze it with the Wireshark program. Note that we are adding the monitoring VAP interface ath1 to an existing VAP interface ath0

wlanconfig ath1 create wlandev wifi0 wlanmode monitor
ip link set ath1 up


B.A.T.M.A.N. is the official name of the mesh routing protocol used in the Mesh-Potato firmware. (Don't bother too much about the correct use of the dots :) The routing protocol is implemented in a program (daemon) called batmand. The daemons basic functionality is to act as a wireless relay to form a meshed network with other wireless relays. Thus MPs running batmand form a robust and organically growing net of interconnected nodes. If MPs are added to the network they are automatically integrated. The mesh network is based on mutual aid - MPs help each other to communicate. As long as the B.A.T.M.A.N. protocol can locate a chain of working wireless links between two MPs they can phone each other. If a MP disappears from the cloud the protocol will detect the failure and find alternative communication paths if they exist. Hence it is recommended to keep the MP running all the time. This should be communicated with the users. The power consumption of the MP is very low.

Batmand can be configured via the UCI configuration file /etc/config/batmand or via a script. I know UCI fans may wish to kill me but I'll stick to the generic Linux way again ;)

MPs acting as mesh relay station

The basic functionality of batmand is routing traffic. Batmand will do this once it is started and the MP firmware will start it by default via the Kamikaze startup script /etc/init.d/batmand. Batmand will detect whether the wireless interface ath0 is available and begin to use it.

In case you want to stop it by hand or via a script execute:

 killall batmand 


 /etc/init.d/batmand stop 

In case you want to start it by hand or via a script execute:

 batmand ath0 


 /etc/init.d/batmand start 

-> The latter option will read the UCI batmand configuration file, so you have to change the UCI configuration file if you want to modify the batmand configuration.

The default interval for sending out protocol update messages is 1000msec (1 second). In order to reduce protocol overhead and CPU load for large mesh networks the intervall can be increased with the switch -o:

 batmand -o 5000 ath0 

-> This will set the protocol update interval to 5 seconds.

Using the visualisation server option

MPs can send their local view of the network topology and link quality to a visualisation server. The visualisation server can be set up anywhere in the mesh. It is also possible to use multiple visualisation servers because visualisation servers are capable to sync their data via the mesh. Sending visualisation data is optional and can be enabled with the -s switch.

 batmand -o 5000 -s ath0 

-> Like before, plus visualisation data will be sent to IP address

MPs acting as mesh gateway

A MP can act as a wireless internet gateway. In order to do this the way that batmand is started has to be changed. Batmand supports gateway classes - a gateway can announce the speed of the Internet connectivity it has to offer. The switch to enable gateway functionality is -g. Downlink/Uplink speed information must be provided.

 batmand -g 64kbit/64kbit -o 5000 ath0 

-> Announces a gateway with 64kbit downlink/uplink speed, protocol updates are sent every 5 seconds.

Note that operating a gateway usually also needs to set up network address translation (NAT) using iptables towards the uplink interface. Here is what you should add to your meshnetwork startup script:

 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 

MPs acting as gateway clients



1. The default OpenWRT init file does not start Asterisk correctly, edit the file and reboot:

root@OpenWrt:~# vi /etc/init.d/asterisk

#!/bin/sh /etc/rc.common
# Copyright (C) 2006


start() {
        [ -f $DEFAULT ] && . $DEFAULT
        [ -d $DEST/var/run ] || mkdir -p $DEST/var/run
        [ -d $DEST/var/log/asterisk ] || mkdir -p $DEST/var/log/asterisk
        [ -d $DEST/var/spool/asterisk ] || mkdir -p $DEST/var/spool/asterisk
        [ -d /var/spool/asterisk ] || mkdir -p /var/spool/asterisk
        [ -h $DEST/usr/lib/asterisk/astdb ] || ln -sf /var/spool/asterisk/astdb
#       $DEST/usr/sbin/asterisk $OPTIONS
        /usr/sbin/asterisk -f 2>&1 > /dev/null &

stop() {
        [ -f $DEST/var/run/ ] && kill $(cat $DEST/var/run/asterisk.p}

2. After rebooting you should see Asterisk running:

root@OpenWrt:~# ps x

  604 root     19380 S    /usr/sbin/asterisk -f
  605 root     19380 S    /usr/sbin/asterisk -f
  606 root     19380 S    /usr/sbin/asterisk -f
  607 root     19380 S    /usr/sbin/asterisk -f
  608 root     19380 S    /usr/sbin/asterisk -f
  609 root     19380 S    /usr/sbin/asterisk -f
  610 root     19380 S    /usr/sbin/asterisk -f
  611 root     19380 S    /usr/sbin/asterisk -f
  612 root     19380 S    /usr/sbin/asterisk -f
  613 root     19380 S    /usr/sbin/asterisk -f
  614 root     19380 S    /usr/sbin/asterisk -f
  615 root     19380 S    /usr/sbin/asterisk -f
  616 root     19380 S    /usr/sbin/asterisk -f
  617 root     19380 S    /usr/sbin/asterisk -f
  618 root     19380 S    /usr/sbin/asterisk -f

3. Plug in an analog phone and take it off hook, you should here dial tone.

4. To test the system we can add some dialplan script to /etc/extensions.conf. Use vi to add this code to the [default] section of extensions.conf. While vi is in command mode type /[def to jump to the [default] section:

exten => 4000,1,Dial(MP/1)
exten => 4001,1,Answer
exten => 4001,2,Echo
exten => 4002,1,Dial(SIP/sipguest)

Due to the slow speed of the serial flash it's a good idea to turn off logging. Use vi to edit logger.conf and comment out the "messages" line:

;debug => debug
console => notice,warning,error
;console => notice,warning,error,debug
;messages => notice,warning,error
;full => notice,warning,error,debug,verbose 

5. Start and Asterisk console and load the modified dialplan:

root@OpenWrt:~# asterisk -r
Asterisk 1.4.11, Copyright (C) 1999 - 2007 Digium, Inc. and others.
Created by Mark Spencer <>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
Connected to Asterisk 1.4.11 currently running on OpenWrt (pid = 547)
OpenWrt*CLI> dialplan reload
OpenWrt*CLI> show dialplan 4000
There is no existence of '4000' context
The 'show dialplan' command is deprecated and will be removed in a future release. Please use 'dialplan show' instead.
OpenWrt*CLI> show dialplan de
default  demo
OpenWrt*CLI> show dialplan default
[ Context 'default' created by 'pbx_config' ]
  '4000' =>         1. Dial(MP/1)                                 [pbx_config]
  '4001' =>         1. Answer()                                   [pbx_config]
                    2. Echo()                                     [pbx_config]
  '4002' =>         1. Dial(SIP/sipguest)                         [pbx_config]
  Include =>        'demo'                                        [pbx_config]

-= 3 extensions (4 priorities) in 1 context. =-

Now try dialing 4001. It should answer almost immediately and echo anything you say with a short delay.

6. Extension 4002 is for a SIP device. Place the following at the end of /etc/asterisk/sip.conf. In vi command mode G is useful to jump to the end of the file.


7. Configure your SIP device to have username/password sipguest/sipguest. At the Asterisk CLI:

OpenWrt*CLI> sip reload

Power cycle your SIP device and after a few seconds it should register. No try dialing 4000 from the SIP device to make the MP phone ring.