About
This page contains notes and code related to installing the B.A.T.M.A.N. (Better Approach to Mobile Ad-Hoc Networking) mesh routing protocol on Guruplugs. There are already several Guruplug tutorials out there, most of which are better than this to get started. So this is probably only for you if you already have some Guruplug hacking experience and want to try to run B.A.T.M.A.N. on it.
For example, the following resources might be helpful:
Disclaimer: Some of the information on this page as well as on pages linked from this one can brick (i.e. make unusable) your Guruplug. I am not responsible for whatever happens as a consequence of the information presented here.
Initial Observations
I started with 4 Guruplugs (1 EU plug ordered from dureg GmbH, and 3 US plugs ordered from GlobalScale).
Turns out there were several differences between them:
|
EU Guruplug
|
US Guruplug
|
uname
|
Linux guruplug-debian 2.6.32-00007-g56678ec #1 PREEMPT
Mon Feb 8 03:49:55 PST 2010 armv5tel GNU/Linux
|
Linux guruplug-debian 2.6.33.7-dirty #2 PREEMPT
Wed Apr 20 22:14:16 EDT 2011 armv5tel GNU/Linux
|
U-Boot |
U-Boot 2009.11-rc1-00602-g8e6db3d (Dec 24 2009 - 03:11:17)
Marvell-Plug2
|
U-Boot 2010.03 (Oct 31 2011 - 15:23:58)
Marvell-GuruPlug
|
Wireless Adapter
|
Marvell 88W8688
device 0x9104
class 0x00
vendor 0x02df
CONFIG_LIBERTAS
|
Marvell 88W8787
device 0x9119
class 0x00
vendor 0x02df
CONFIG_MWIFIEX
|
lsmod
|
Module Size Used by
sco 8250 2
bridge 45638 0
stp 1342 1 bridge
llc 3298 2 bridge,stp
btmrvl_sdio 8556 0
btmrvl 11210 3 btmrvl_sdio
bnep 7676 2
rfcomm 34299 4
l2cap 30547 16 bnep,rfcomm
xt_tcpudp 2157 1
iptable_filter 1260 1
ipt_MASQUERADE 1380 2
iptable_nat 3408 1
nf_nat 12419 2 ipt_MASQUERADE,iptable_nat
nf_conntrack_ipv4 9402 3 iptable_nat,nf_nat
nf_conntrack 45794 4 ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4
nf_defrag_ipv4 897 1 nf_conntrack_ipv4
ip_tables 9273 2 iptable_filter,iptable_nat
x_tables 11588 4 xt_tcpudp,ipt_MASQUERADE,iptable_nat,ip_tables
uap8xxx 44492 1
ipv6 238227 20
libertas_sdio 6683 0
libertas 81304 1 libertas_sdio
bluetooth 55429 9 sco,btmrvl,bnep,rfcomm,l2cap
|
Module Size Used by
sco 8548 2
bridge 46686 0
stp 1330 1 bridge
llc 3222 2 bridge,stp
bnep 7848 2
bt8xxx 31070 3
mbtchar 10208 0
rfcomm 34661 4
l2cap 31716 16 bnep,rfcomm
bluetooth 55817 9 sco,bnep,bt8xxx,rfcomm,l2cap
xt_tcpudp 2153 1
iptable_filter 1260 1
ipt_MASQUERADE 1404 2
iptable_nat 3568 1
nf_nat 12823 2 ipt_MASQUERADE,iptable_nat
nf_conntrack_ipv4 9514 3 iptable_nat,nf_nat
nf_conntrack 45994 4 ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4
nf_defrag_ipv4 909 1 nf_conntrack_ipv4
ip_tables 9693 2 iptable_filter,iptable_nat
x_tables 11216 4 xt_tcpudp,ipt_MASQUERADE,iptable_nat,ip_tables
sd8xxx 149211 1
mlan 194689 1 sd8xxx
ipv6 243993 18
sata_mv 26043 0
mv_cesa 4798 0
|
So this means that the EU and US Guruplugs shipped with different kernels, different bootloaders, and different wireless adapters.
On the filesystem, some scripts and configuration files were also different.
Plan and Prerequisites
One problem with the custom kernels is that it is not possible to build modules (e.g. B.A.T.M.A.N.) for them without the correct matching kernel sources.
After some research, I came to the conclusion that the best way forward was to:
- Build a custom kernel from the official source. I tried several version and eventually ended up using 3.3.0-rc4.
- Build a custom bootloader (U-Boot), since apparently the shipped versions are not compatible with all kernels.
- Only use the official kernel sources. Out there, you can find Guruplug patches for the kernel, the proprietary Guruplug wireless driver, and the latest B.A.T.M.A.N. sources. After experimenting with different ideas, I eventually ended up not using any of this, only the official kernel source tree. The downside of this is that the open source wireless drivers don't support Access Point mode (only the proprietary uap8xxx one).
The rest of this page assumes you have and know how to use the following:
- A JTAG cable to connect to your Guruplug via USB
- A terminal program such as minicom
- A Linux machine on which you can build the bootloader and kernel
- A cross-compiler for the Guruplug's ARM environment (e.g. CodeSourcery)
- A TFTP server on your Linux machine to serve files to the Guruplug
Cheat Sheet
Here are some quick tricks I needed many times in the process of setting everything up.
These things are better described in other Guruplug guides.
How to build the custom bootloader:
git clone git://git.denx.de/u-boot-marvell.git u-boot-marvell.git
cd u-boot-marvell.git
git checkout -b testing origin/testing
make mrproper
make guruplug_config
make u-boot.kwb CROSS_COMPILE=~/codesourcery/arm-2011.09/bin/arm-none-linux-gnueabi-
cp tools/mkimage /usr/bin
This will create the mkimage tool (later needed to build the kernel image), and the actual bootloader u-boot.kwb which can be flashed on the Guruplug.
How to build the custom kernel:
make mrproper
make ARCH=arm kirkwood_defconfig
make ARCH=arm menuconfig
--> System Type / Guruplug
--> Enable loadable module / Forced module loading
--> Device Drivers / Memory Technology Device / UBI
--> File Systems / Miscellaneous / UBI
--> Device Drivers / Network device / Wireless / Marvell Libertas 8688 AS MODULE
--> Device Drivers / Network device / Wireless / Marvell Wifi-Ex 8787 AS MODULE
--> Networking Support / Bluetooth subsystem support / Bluetooth device drivers / Marvell BT over SDIO AS MODULE
--> Networking Support / Networking options / Network packet filtering / Core Netfilter configuration / EVERYTHING AS MODULE
--> Networking Support / Networking options / Network packet filtering / IP Netfilter configuration / EVERYTHING AS MODULE
--> Networking Support / Networking options / IP: advanced router
--> Networking Support / Networking options / BATMAN AS MODDULE
--> Networking Support / Networking options / IPv6 protocol AS MODULE
--> Networking Support / Networking options / 802.1d bridging AS MODULE
make -j4 ARCH=arm CROSS_COMPILE=~/codesourcery/arm-2011.09/bin/arm-none-linux-gnueabi- uImage
cp arch/arm/boot/uImage ~/output/
make -j4 ARCH=arm CROSS_COMPILE=~/codesourcery/arm-2011.09/bin/arm-none-linux-gnueabi- modules
make -j4 ARCH=arm CROSS_COMPILE=~/codesourcery/arm-2011.09/bin/arm-none-linux-gnueabi- INSTALL_MOD_PATH=~/output/ modules_install
This will create the uImage kernel image and modules which can be flashed on the Guruplug.
How to flash the bootloader:
tftp 0x6400000 u-boot.kwb
nand erase 0x0 0x100000
nand write.e 0x6400000 0x0 0x100000
How to flash the kernel:
tftp 0x6400000 uImage
nand erase 0x100000 0x400000
nand write.e 0x6400000 0x100000 0x400000
Misc Steps
After flashing the custom bootloader and kernel, you still need to copy the kernel modules into /lib/modules.
You also need to run depmod -a and then reboot.
Setting up network interfaces
Insert the wireless driver and B.A.T.M.A.N. driver:
modprobe mwifiex
modprobe batman_adv
Set up the bat0 interface on top of mlan0:
ifconfig mlan0 mtu 1528
iwconfig mlan0 mode ad-hoc essid "peacenet" channel 1
./batctl if add mlan0
ifconfig mlan0 up
Next step is to configure IP addresses. I set my Guruplugs up on eth0 AND bat0, for easier debugging. Although a meaningful setup would probably somehow involve a DHCP server, I decided to configure all interfaces statically, with IP addresses derived from eth0's hardware address. I disabled ifplugd, udhcpd and dnsmasq and used a "set_ips.sh" script to set IP addresses on eth0 and bat0.
I used the 172.16.0.0/16 for eth0, 172.18.0.0/16 for mlan0, and 172.17.0.0/16 for bat0. The final IP address layout is as follows:
|
eth0
|
mlan0
|
bat0 |
EU
|
172.16.90.193/16
(00:50:43:01:5a:c1)
|
172.18.90.193/16
(00:24:23:1f:a5:cb)
|
172.17.90.193/16 |
US1
|
172.16.218.193/16
(f0:ad:4e:00:da:c1)
|
172.18.218.193/16
(00:24:23:77:ff:63)
|
172.17.218.193/16 |
US2
|
172.16.217.183/16
(f0:ad:4e:00:d9:b7)
|
172.18.217.183/16
(00:24:23:78:06:fb)
|
172.17.217.183/16 |
US3
|
172.16.217.243/16
(f0:ad:4e:00:d9:f3)
|
172.18.217.243/16
(00:24:23:78:09:09)
|
172.17.217.243/16 |
Another problem I ran into was that the wireless interfaces did not automatically agree on a Cell ID for the mesh network, even though they had the same ESSID. Apparently, this can be traced back to buggy drivers. As a solution, I wrote a "scan_cells.sh" script to periodically scan for the numerically lowest Cell ID within range and adjusted the local one accordingly.
Results
Interfaces
List of interfaces on the US1 Guruplug:
root@guruplug-debian:~# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether f0:ad:4e:00:da:c1 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: mlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1528 qdisc pfifo_fast state UP qlen 1000
link/ether 00:24:23:77:ff:63 brd ff:ff:ff:ff:ff:ff
5: bat0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 12:e6:e8:73:af:a0 brd ff:ff:ff:ff:ff:ff
root@guruplug-debian:~# ip addr list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether f0:ad:4e:00:da:c1 brd ff:ff:ff:ff:ff:ff
inet 172.16.218.193/16 brd 172.16.255.255 scope global eth0
inet6 fe80::f2ad:4eff:fe00:dac1/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: mlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1528 qdisc pfifo_fast state UP qlen 1000
link/ether 00:24:23:77:ff:63 brd ff:ff:ff:ff:ff:ff
inet6 fe80::224:23ff:fe77:ff63/64 scope link
valid_lft forever preferred_lft forever
5: bat0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 12:e6:e8:73:af:a0 brd ff:ff:ff:ff:ff:ff
inet 172.17.218.193/16 brd 172.17.255.255 scope global bat0
inet6 fe80::10e6:e8ff:fe73:afa0/64 scope link
valid_lft forever preferred_lft forever
Pinging
They were all able to ping each other, both on the 172.16.0.0/16 eth0 subnet, and on the 172.17.0.0/16 bat0 subnet.
E.g. Guruplug US2 pinging Guruplug US1 on eth0, on bat0 (level 3), and on bat0 (level 2):
root@guruplug-debian:~/guruplug# ping 172.16.218.193
PING 172.16.218.193 (172.16.218.193) 56(84) bytes of data.
64 bytes from 172.16.218.193: icmp_seq=1 ttl=64 time=0.224 ms
64 bytes from 172.16.218.193: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 172.16.218.193: icmp_seq=3 ttl=64 time=0.104 ms
root@guruplug-debian:~/guruplug# ping 172.17.218.193
PING 172.17.218.193 (172.17.218.193) 56(84) bytes of data.
64 bytes from 172.17.218.193: icmp_seq=1 ttl=64 time=0.974 ms
64 bytes from 172.17.218.193: icmp_seq=2 ttl=64 time=1.40 ms
64 bytes from 172.17.218.193: icmp_seq=3 ttl=64 time=1.38 ms
root@guruplug-debian:~/guruplug# ./batctl p 00:24:23:77:ff:63
PING 00:24:23:77:ff:63 (00:24:23:77:ff:63) 20(48) bytes of data
20 bytes from 00:24:23:77:ff:63 icmp_seq=1 ttl=50 time=0.85 ms
20 bytes from 00:24:23:77:ff:63 icmp_seq=2 ttl=50 time=1.65 ms
20 bytes from 00:24:23:77:ff:63 icmp_seq=3 ttl=50 time=0.88 ms
B.A.T.M.A.N.
The output of the batctl tool on the US1 Guruplug looked like this:
root@guruplug-debian:~/guruplug# ./batctl if
mlan0: active
root@guruplug-debian:~/guruplug# ./batctl o
[B.A.T.M.A.N. adv 2012.0.0, MainIF/MAC: mlan0/00:24:23:77:ff:63 (bat0)]
Originator last-seen (#/255) Nexthop [outgoingIF]: Potential nexthops ...
00:24:23:78:09:09 0.980s (250) 00:24:23:78:09:09 [ mlan0]: 00:24:23:78:09:09 (250) 00:24:23:78:06:fb (212)
00:24:23:78:06:fb 0.380s (240) 00:24:23:78:09:09 [ mlan0]: 00:24:23:78:09:09 (240) 00:24:23:78:06:fb (234)
00:24:23:1f:a5:cb 0.480s (245) 00:24:23:78:09:09 [ mlan0]: 00:24:23:78:09:09 (245) 00:24:23:78:06:fb (228)
4 Guruplugs happily talking to each other:
00:24:23:1f:a5:cb
Comments (0)
You don't have permission to comment on this page.