Sunday, May 17, 2015

freebsd-wifi-build, or "wait, you can run freebsd on atheros MIPS access points? where do I get that?"

I've been running FreeBSD at home as my primary internet/wifi access for a few years now. It's cheap, it's easy to do, and I've tried very hard to wrap up the whole process into a mostly-simple build system that spits out a useful image to use.

It's pretty simple in concept - I take FreeBSD-HEAD, build it with some cut-down options, create a custom filesystem image with some custom boot scripts and a custom configuration file, and provide an image that you can TFTP (using a serial console and ethernet cable) or upload directly to the AP if it supports it.

The supported hardware list is here:

Now, it's not a huge list like OpenWRT, but that's mostly because I don't have an infinite supply of Atheros MIPS based routers. I think I'll get some of the TP-Link Archer series stuff next.

Building it is pretty simple:

You checkout the build repo, check out FreeBSD-HEAD, install a couple of packages, and run the build for your board. Once it's done, the images for your board appear in ../tftpboot/. There's a wiki page for each of the supported boards with a walkthrough with how to get FreeBSD going on it.

It comes up on with 'user' and 'root' users, with no password. So, the first thing you should do after installation is telnet in, configure /etc/cfg/rc.conf with your actual LAN IPs, set the user/root passwords, and then 'cfg_save' to save things. Then, reboot and voila!

The configuration file format looks like FreeBSD but it isn't. I'm keeping it somewhat hierarchical-looking in naming but flat in implementation so I can migrate it to something like a sqlite or luci backend in the future.

It's good enough for me to be able to set up an AP to be a bridge with a management IP address and configure the ethernet switch. Others have added ipfw support to do NAT and firewalling - I'm going to add configuration rules for NAT, IPFW and routing soon so it's all integrated.

It's FreeBSD, all the way through:

$ uname -a
FreeBSD tl-wdr3600 11.0-CURRENT FreeBSD 11.0-CURRENT #0 r282406M: Wed May  6 22:27:16 PDT 2015     adrian@lucy-11i386:/usr/home/adrian/work/freebsd/head-embedded/obj/mips/mips.mips/usr/home/adrian/work/freebsd/head-embedded/src/sys/TL-WDR4300  mips
$ ifconfig wlan0 list sta
18:ee:69:15:f4:12    2    1  26M 37.0   45   2703  51888 EPS  AQEHTRM RSN HTCAP WME
04:e5:36:0d:1b:0d    1    1  19M 23.0   15   1524  47072 EPS  AQEPHTR RSN HTCAP WME
cc:3a:61:0e:33:a0    3    1  19M 32.0   30   2585  43072 EPS  AQEPHTR RSN HTCAP WME
40:0e:85:1a:f1:69    4    1  19M 25.0   30   1138  54800 EPS  AQEPHTR RSN HTCAP WME
00:0f:13:97:14:54    5    1  54M 30.0   45   1808  57424 EPS  AE      RSN
00:22:fa:c2:d1:20    6    1  26M 24.5    0    574  57776 EPS  AQEHTRS RSN HTCAP WME

So if you'd like a FreeBSD based device to act as your home gateway, this is where you can start. It's not pfsense, but it's designed to run on things much smaller than pfsense supports and it's a good introduction into the world of FreeBSD embedded.


  1. Any idea if this would work on the super-cheap ($22 free shipping) TL-WR703N? It's an Atheros MIPS, AR9331/AR7240 chipset/CPU combo. I have one and can test if you think it's likely to work.

    What I'm hoping to do is use these with a cheap-but-good USB DAC like the $15 EL-D01, and build wifi audio streaming endpoints for my house.

  2. We definitely run on the unit, but we can't fit FreeBSD in 4MB of flash.

    I'm using the base system libraries and binaries, which are all very large. OpenWRT uses a much more cut down set of libraries/binaries explicitly designed for smaller footprint.

    The smallest footprint so far is:

    -rw-r--r-- 1 adrian wheel 4431360 May 18 01:16 tl-wr1043nd.factory.bin

    .. which is still too big for the unit, and doesn't leave you any room to grow. :(

    You can compile a kernel that'll boot from NOR flash and run off of a USB drive, but then you'll need a USB hub to run both the drive and the DAC from.

    1. I see. A USB flash drive and a hub is just over $6 total, so that's definitely an option. Do you have a link to a tutorial for running off a USB drive?

  3. Hi! Yes, please file a bug at and I'll go write a tutorial about it.

    Almost all the work is already done; I just need to tidy it up and make sure the kernel configuration change is documented (right now the kernels boot off of NOR flash; they don't try to boot off of USB at all.)

  4. I wonder if MT7620 support would be viable, there are some really cheap devices ( comes to mind, $15 on AliExpress). I know this is a different series, but would make this a bit more widely useful, though the small TP-Link routers are cheap too. I might look into running this on my WR1043ND v1 in the meanwhile, it's currently running FreeBSD but this would be a good way for me to learn more about how it works under the hood I feel.

  5. I'm working on getting things trimmed down enough to run on

    I just need to be able to be an ipv4 dhcp client and have drivers for the u340g

    I'm just getting started so I'll try and keep everyone posted

  6. ## Giving linux memsize in MB, 32

    Starting kernel ...

    U-Boot args (from 0 args):
    entry: mips_init()
    Cache info:
    picache_stride = 4096
    picache_loopcount = 8
    pdcache_stride = 4096
    pdcache_loopcount = 4
    cpu0: MIPS Technologies processor v76.150
    MMU: Standard TLB, 32 entries
    L1 i-cache: 4 ways of 256 sets, 32 bytes per line
    L1 d-cache: 4 ways of 128 sets, 32 bytes per line
    Physical memory chunk(s):
    0x3e2000 - 0x1ffffff, 29483008 bytes (7198 pages)
    Maxmem is 0x2000000
    KDB: debugger backends: ddb
    KDB: current backend: ddb
    Copyright (coffee) 1992-2015 The FreeBSD Project.
    Copyright (coffee) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
    The Regents of the University of California. All rights reserved.
    FreeBSD is a registered trademark of The FreeBSD Foundation.
    FreeBSD 11.0-CURRENT #0 r283754: Fri May 29 21:36:50 UTC 2015
    shelbyr@vultr:/usr/obj/mips.mipsel/usr/src/head/sys/RT305X mips
    gcc version 4.2.1 20070831 patched [FreeBSD]
    Preloaded elf kernel "kernel" at 0x803dbb20.
    real memory = 33554432 (32768K bytes)
    Physical memory chunk(s):
    0x0046e000 - 0x01f41fff, 28131328 bytes (6868 pages)
    avail memory = 27725824 (26MB)
    ULE: setup cpu 0
    wlan: <802.11 Link Layer>
    random: entropy device infrastructure driver
    random: selecting highest priority adaptor
    random: SOFT: yarrow init()
    random: selecting highest priority adaptor
    nfslock: pseudo-device
    nvram2env0: base=0xbf030000 sig=0xe5e60a74 maxsize=0x00002000 flags=0x00000003
    nvram2env1: base=0xbf032000 sig=0x5a045e94 maxsize=0x00004000 flags=0x00000003
    clock0: on nexus0
    Timecounter "MIPS32" frequency 192000000 Hz quality 800
    Event timer "MIPS32" frequency 192000000 Hz quality 800
    obio0 at mem 0x10000000-0x1fffffff on nexus0
    rt305x_sysctl0: at mem 0x10000000-0x100000ff irq 0 on obio0
    Chip ID: "RT5350 "
    GE0 mode 0
    Big Endian
    Boot from 0
    Bootstrap test code 48
    SRAM_CS mode 0
    8mA SDRAM_CLK driving
    I2S clock is internal 15.625MHz
    I2S clock divider 40
    PCM clock is internal 15.625MHz
    PCM clock divider 60
    rt305x_ic0: at mem 0x10000200-0x100002ff on obio0
    gpio0: at mem 0x10000600-0x100006ff irq 6 on obio0
    gpio0: Use reset_gpio 10
    gpiobus0: on gpio0
    gpiobus0: at pin(s) 0
    gpiobus0: at pin(s) 7
    gpioled0: at pin(s) 8 on gpiobus0
    gpioled1: at pin(s) 9 on gpiobus0
    gpiobus0: at pin(s) 10
    gpiobus0: at pin(s) 11
    gpioled2: at pin(s) 14 on gpiobus0
    gpioc0: on gpio0
    uart1: at mem 0x10000c00-0x10000cff irq 12 on obio0
    uart1: console (115200,n,8,1)
    uart1: fast interrupt
    rt0: at mem 0x10100000-0x1010ffff irq 3 on nexus0
    rt0: RT305XF Ethernet MAC (rev 0x00000000)
    rt0: use hardcoded 00:18:e7:d5:83:90 macaddr
    rt0: bpf attached
    rt0: Ethernet address: 00:18:e7:d5:83:90
    Device configuration finished.
    Timecounters tick every 10.000 msec
    vlan: initialized, using hash tables with chaining
    tcp_init: net.inet.tcp.tcbhashsize auto tuned to 512
    lo0: bpf attached
    bootpc_init: wired to interface 'rt0'

    I get this far then nothing, I don't know the first thing about debugging FreeBSD, I could send the you the hardware if you're interested? is the device. Thanks!

    1. I'll see about getting one!

    2. I could send you a few if you would like? You will need to solder on the 3v TTL to USB adapter, based on your posts I'm sure that's no issue for you! It would be cool to get a -sysupgrade.bin file put together to flash from within openWRT

    3. Hi! Sorry I didn't see this! Sure, I'd be happy to receive a couple so I can bring it up!

  7. Sure, drop me an email!

  8. This comment has been removed by a blog administrator.