Mesh Potato Firmware How To
Introduction
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, chan_mp.so)
- 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
- The boot loader (and Linux serial console if compiled in) runs at 9600 baud, 8 data bits, 1 stop bit, no parity.
- The default Linux IP is 192.168.1.20. 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.
- 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.
- 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.
- 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.
- 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
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.
The two most important steps are to program the lfuse and flash the [[ https://villagetelco.svn.sourceforge.net/svnroot/villagetelco/david/avr/uart2spi.hex | 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:
redboot/ap61/ram/install/bin/redboot.elf redboot/ap61/rom/install/bin/redboot.rom
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 Sourceforge.net 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
Linux
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 192.168.1.20 - 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 192.168.1.20
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:
http://download.berlin.freifunk.net/sven-ola/area51/
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 http://downloads.open-mesh.org/mesh-potato/firmware-archive/. 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 : 192.168.1.114 Your MAC: 00:ba:be:ca:ff:ee Your IP : 192.168.1.0 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 192.168.1.20. 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:
CONFIG_SERIAL_8250=m
To:
$ tail target/linux/atheros/config-2.6.26 <snip> CONFIG_SERIAL_8250=y
2/ Edit build_dir/linux-atheros/linux-2.6.26.3/arch/mips/atheros/board.c
Around line 204 change:
//early_serial_setup(&s); }
To:
early_serial_setup(&s); }
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: 192.168.1.1/255.255.255.0, Gateway: 192.168.1.22 Default server: 192.168.1.2 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: 192.168.1.1/255.255.255.0, Gateway: 192.168.1.22 Default server: 192.168.1.2 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 2.6.26.3 (david@bunny) (gcc version 4.1.2) #3 Mon Jun 8 15:07:39 9memcfg: 0x141168 memsize: 0x1000000 SDRAM_DATA_WIDTH: 0x0 SDRAM_COL_WIDTH: 0x8 SDRAM_ROW_WIDTH: 0xb 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 <greearb@candelatech.com> All bugs added by David S. Miller <davem@redhat.com> 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 <maxk@qualcomm.com> 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% / root@OpenWrt:/#
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-2.6.26.3/drivers/serial/serial_core.ko 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 chan_mp.so 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() type=16550A 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.
Network
LAN
The default IP is 192.168.1.20. 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.
WiFi
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 10.0.0.1
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 10.0.0.1
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 10.0.0.2
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 10.0.0.1
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.
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
or
/etc/init.d/batmand stop
In case you want to start it by hand or via a script execute:
batmand ath0
or
/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 10.0.0.1 ath0
-> Like before, plus visualisation data will be sent to IP address 10.0.0.1
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
TODO.
Asterisk
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 OpenWrt.org START=50 DEST= DEFAULT=$DEST/etc/default/asterisk OPTIONS="" 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/asterisk.pid ] && kill $(cat $DEST/var/run/asterisk.p}
2. After rebooting you should see Asterisk running:
root@OpenWrt:~# ps x <snip> 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:
[default] 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 <markster@digium.com> 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. =- OpenWrt*CLI>
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.
[sipguest] type=friend context=default host=dynamic user=sipguest secret=sipguest canreinvite=no callerid=at530 disallow=all allow=ulaw
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.