OpenWrt Forum Archive

Topic: Building trunk on D-Link DIR-615 C2 using Mac OS X to add gpsd

The content of this topic has been archived on 27 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

After attempts at buying a GPS-equipped cellular router for a vehicular communications project fell through, I spent the weekend trying to find an alternative based on a standard Ethernet router. The process uncovered lots of new and poorly documented tasks so I hope my notes will save someone else a whole heap of time and frustration.

My first target was the Asus WL-500GL, after reading of success with oleg's firmware and gpsd. Unfortunately, combing all the local electronic retailers in my city (Newcastle, Australia) for Asus routers turned up only strange looks and zero routers. In desperation I found that the Linksys WRT54GL was a possibility, having good support for OpenWrt and at least one available serial port. However, to my dismay I found hundreds of WRT54G2, which despite the similar name, lack critical features that the unavailable WRT54GL sports.

Of the routers that were actually available, the only remaining glint of hope I found was in the D-Link DIR-615. The OpenWrt docs claim support for the C1 model, but the closest I could find was C2. Options were running dry fast, so I took the plunge on the C2 model.

Setup was straightforward. The router bag was sealed with large sticker and plenty of warnings that the software from the CD must be installed before connecting the router. I ignored them. I don't have a Windows machine handy and the CD only contains a compressed installer image. With the router up and running, it was time to create the build environment.

I'm running Mac OS X 10.6.3 (Snow Leopard) with the Developer Tools installed. I'll indicate commands for the host terminal with the prefix '$' and commands for the router terminal with the prefix '%'.

I used MacPorts to get some dependencies:

$ sudo port install coreutils
$ sudo port install gawk
$ sudo port install wget
$ sudo port install findutils

coreutils installs fileutils and findutils installs the GNU version of find, necessary when creating the build images.

The build system requires a case-sensitive filesystem, so I used Disk Utility to create a 4GB (yes, >3GB to compile sources!) Mac OS Extended (Case-sensitive) disk image, then used terminal to navigate to it.

$ cd /Volumes/OpenWrt/

I checked out the OpenWrt trunk source. I actually spent the first 6 hours working with the 8.09 branch (as suggested by the compatible hardware list) but found many problems, including lack of DIR-615 profiles, file too big problems and linker errors "Nonrepresentable section on output". So I switched to trunk and everything started to work. For what it is worth, I pulled trunk on the 4th April, 2 days after Backfire 10.03-rc3 was posted.

$ svn co svn://
$ cd trunk
$ make prereq
$ make menuconfig

If make prereq succeeds, it may run menuconfig automatically. In any case, once I was in menuconfig I had to be very careful not to press an arrow key! It appears the arrow keys aren't escaped properly, and generally cause menuconfig to quit. Instead, I navigated using the accelerators, enter, esc, plus, minus, 'y', 'n' and spacebar.

I used menuconfig to:
* Change Target System to Atheros AR71xx
* Change Profile to D-Link DIR-615 C1

To save the config I pressed Esc from the main menu and then Enter to select "Yes". Then I built the configuration:

$ make

This took around 30 minutes on a 2.8GHz Intel Core 2 Duo. Once it was complete, my bin/ar71xx directory contained the following (preceded by file size):

3866648 openwrt-ar71xx-dir-615-c1-squashfs-factory.bin
2555908 openwrt-ar71xx-dir-615-c1-squashfs-sysupgrade.bin
2752512 openwrt-ar71xx-root.jffs2-128k
2621440 openwrt-ar71xx-root.jffs2-64k
1703936 openwrt-ar71xx-root.squashfs
1646596 openwrt-ar71xx-root.squashfs-4k
2005637 openwrt-ar71xx-rootfs.tgz
1183055 openwrt-ar71xx-uImage-gzip.bin
852722  openwrt-ar71xx-uImage-lzma.bin
2619896 openwrt-ar71xx-vmlinux.bin
2686288 openwrt-ar71xx-vmlinux.elf
1245184 openwrt-ar71xx-vmlinux.gz
917504  openwrt-ar71xx-vmlinux.lzma

And I was ready for the first flashing. This is where things get nervous. It turns out the DIR-615 has a ~200KB boot space reserved for the boot loader and the flash image takes up the remaining 3.8MB. That should make it pretty hard to brick the router, and I didn't have any problems, but you never know.

After mucking around with the router's "emergency upgrade flash" mode (accessed by holding the reset button for 30 seconds until power light flashes amber) for a couple of hours, trying all manner of hardware IDs, I gave up and used the D-Link web interface instead. Under Tools there should be a "Upgrade Firmware" link. I used this, uploaded "openwrt-ar71xx-dir-615-c1-squashfs-factory.bin" and away it went!

In just 14 hours I had OpenWrt running on the DIR-615!

To restore access to the router I set my network settings to manual IP, then logged in:

$ telnet
% passwd
% vi /etc/config/network

I changed the lan option ipaddr to so it didn't clash with my existing network.

% reboot

Remember to change manual IP to to suit new subnet.

$ ssh root@

And we're in! The router automatically picked up a WAN address from my ADSL modem and everything worked as expected. I even tried commenting out "open disabled 1" in /etc/config/wireless and found that wireless worked without a hitch.

With the default OpenWrt kernel installed I was able to run opkg to install gpsd which worked well. In order to test the system however, I really needed some more software. At first I investigated modifying the gpsd package to include gpsfake, but after discovering that it requires python which is a large package itself, I decided to include my own software instead.

I found the easiest way to include my own software was to create a basic package and stick it in trunk/package:

$ cd package
$ mkdir gpssim
$ cd gpssim
$ touch Makefile
$ mkdir src
$ touch src/gpssim.c
$ touch src/Makefile

Most of the packages actually download their source from the Internet, but a neat trick in the package Makefile allows the source to be included locally. My Makefile looks like this:

include $(TOPDIR)/


include $(INCLUDE_DIR)/

define Package/gpssim
    TITLE:=Simulate a dumb GPS receiver serving on port 2947

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/

define Build/Configure

define Build/Compile

define Package/gpssim/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/gpssim $(1)/bin/

$(eval $(call BuildPackage,gpssim))

The src directory then, contains a simple c source file and a very small Makefile. Both can be developed in the native host environment before including in OpenWrt.

While I was adding software to the kernel image, it made sense to add gpsd as well.

$ cd package
$ svn co svn://
$ svn co svn://

Adding the uclibc++ dependency now saves a lot of wasted time later!

menuconfig automatically picks up the new packages:

$ cd ..
$ make menuconfig

This time I entered Network and hit 'y' for gpsd and gpssim. I also entered Libraries and noted that uclibc++ had been added as a required build. Esc and Enter to exit and save menuconfig.


This time the openwrt-ar71xx-dir-615-c1-squashfs-factory.bin image was created with the extra packages included. Now how to flash the new image, since we've lost the D-Link web interface? At first I tried many permutations of mtd after deciphering /proc/mtd and dmesg, but couldn't get past this:

$ scp bin/ar71xx/openwrt-ar71xx-dir-615-c1-squashfs-factory.bin root@
% mtd -e firmware -r write /tmp/images/openwrt-ar71xx-dir-615-c1-squashfs-factory.bin firmware
[e]Failed to erase block

So I tried tftp instead:

$ cd bin/ar71xx
$ tftp
> binary
> rexmt 1
> timeout 60
> trace

At this point I power cycled the router and immediately began issuing this command over and over again:

> put openwrt-ar71xx-dir-615-c1-squashfs-factory.bin

Eventually the "sendto: No route to hose" message doesn't come back, and the following appears instead:

tftp> put openwrt-ar71xx-dir-615-c1-squashfs-factory.bin
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
tftp: sendto: No route to host
tftp> put openwrt-ar71xx-dir-615-c1-squashfs-factory.bin
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
sent WRQ <file=openwrt-ar71xx-dir-615-c1-squashfs-factory.bin, mode=octet>
tftp: sendto: No route to host

The router then automatically reboots and loads the new firmware. It also resets itself to, so to get it back I switched my manual IP to and then:

$ telnet
% passwd
% exit
$ ssh root@
% vi /etc/config/network

Change ipaddr back to…

% reboot

Change manual IP back to…

$ ssh root@

And we're done! A working OpenWrt install complete with custom software, ready to try to get gpsd to work. The first thing I did was add enable gpsd at boot by creating /etc/init.d/gpsd with the following contents:

% cat /etc/init.d/gpsd 
#!/bin/sh /etc/rc.common

start() {
    gpsd -G /dev/ttyS0

stop() {
    killall gpsd

So far I've done some preliminary tests to find and enable the serial port. I've found that the 4 vias near the bottom left of this photo are likely serial suspects.

The top via is ground, the next two are Rx and Tx (I'll check which is which using an oscilloscope tomorrow) and the bottom is 3.3V. I've confirmed I can send and receive data (albeit, unreliably) via this interface by sticking a paper clip between the middle two vias, running "% cat < /dev/ttyS0" in one session and "echo 'Hello, world!' > /dev/ttyS0" in another.

What remains is to dump the information I've found about this router for Google fodder and also in case someone wants to update the wiki!

* Another shot of the internals appears below, but the FCC also have photos from their tests on their website.

* It turns out the C2 hardware version I have actually has a circuit board with C1 stamped on it inside. So I do not know what the difference between C1 and C2 is.

* Filesystem:

root@OpenWrt:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                 1408      1408         0 100% /rom
tmpfs                    14792        36     14756   0% /tmp
tmpfs                      512         0       512   0% /dev
/dev/mtdblock4            1472       204      1268  14% /overlay
mini_fo:/overlay          1408      1408         0 100% /

* cpuinfo:

# less /proc/cpuinfo
system type        : Atheros AR9130 rev 2
machine            : D-Link DIR-615 rev. C1
processor        : 0
cpu model        : MIPS 24Kc V7.4
BogoMIPS        : 266.24
wait instruction    : yes
microsecond timers    : yes
tlb_entries        : 16
extra interrupt vector    : yes
hardware watchpoint    : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ff8]
ASEs implemented    : mips16
shadow register sets    : 1
core            : 0
VCED exceptions        : not available
VCEI exceptions        : not available

* Chips on board:
** AR9130-BC1E
** W9425G6EH-5: 4M, 16 BITS DDR SDRAM (there seems to be confusion about 4MB/8MB - it only has 4MB but each location is 16 bits)
** AR8216: Ethernet switch
** MX25l3205: 32Mbit CMOS Flash (RAM and FLASH sizes are reported backwards in some docs)
** RT9183H: Linear Regulator

* The router comes with DIR-615_3.01-tomizone-1.0.2 firmware. This version does not appear to be on, but is available from It looks like tomizone support is the difference between C1 and C2. Given the trouble I had getting the emergency flash upgrade page to accept any images, it may be difficult to return to router to D-Link firmware.

More to come as I work on interfacing a Garmin GPS 18x OEM LVC to the serial port.

Hi, LightYear:

This is a really excellent post! Thanks for the details.


I'm finally back to update the article with GPS information. As is often the case with these hacks, all was not straight forward!

The Garmin GPS 18x OEM LVC is not quite as it seems. The documentation is a little ambiguous, but specifically claims it "transmits voltage levels from ground to the input voltage". It does nothing of the sort and instead both transmits and receives plain old RS-232, at about +/- 5V.

My communication with Garmin to try to sort this out beforehand was laughable - in order to even send a support email I had to select my product from the list, and naturally enough the LVC was absent, so I picked the 18 Serial instead and tried to make it clear I actually wanted information on the LVC. The response:

Garmin wrote:

I am happy to assist you with your question regarding the GPS-18 serial. Unfortunately, I will not be able to fully answer you question as Garmin is not able to support custom configurations of the unit. The GPS 18 serial was designed for the personal computer for consumer level applications. I do not have any advanced information regarding voltage levels that I can share with you.

So based on the documentation I started by building a level converter and inverter based on the IRF7910 dual mosfet chip.

The next challenge was to get the LVC to work at all. At first nothing seemed to happen - I applied 5V to the power lines and monitored the other lines. The device drew a small amount of current, the Tx line was held at -5V (worrying at odds with the documentation and suggestive of a reverse polarity!) and the Rx and PPS lines were silent. I tried all manner of physical locations, gave the device lots of time to acquire a signal, tried sending commands on the Rx line, tried reversing the Tx and Rx line, but all was in vain. The device seemed dead.

In desperation I pulled the device apart, looking for a wire break. What I found instead was an internal battery, glued in place. In my poking around I managed to dislodge the battery and had to secure it back in place. And guess what? It suddenly started working. Some how in the process of pulling it apart the device burst into life. It's likely the problem was a run down battery and the act of removing it temporarily allowed the internal circuits to reset. Now suddenly data was appearing on the Rx line and with time, a PPS appeared as well.

It was still not clear how to communicate to the thing, so I tried my IRF7910 level converter/inverter. I was able to receive data from the device, but was not convinced it was receiving anything I was sending. It was becoming more apparent that the LVC had nothing to do with TTL at all (despite the documentation), and that it actually spoke RS232. To test that I used a USB-RS232 converter from FTDI and ran the SNSRXCFG "GARMIN X-Series Sensor Configuration Software" available for download from Garmin's site.

Finally I had a GPS signal! I used Garmin's software to set the baud rate to 115200 (the DIR-615 default) and turned off a few extraneous messages. Then I turned my attention back to the router serial comms.

Having learnt that the LVC is a RS-232 device, I decided to jetison the level converter and use a full blown RS232 driver instead.

My RS232 driver is based on a MAX3221 chip and looks like this:

I soldered a pin header to the serial port in the router, and then soldered the driver circuit board to the pin header. Amazingly, it all fit under the router's cover. I had all sorts of trouble trying to solder the ground pin of the four pin serial port - unlike the other pin, the ground pin did not slip through the board to be soldered on the underside. It appears the via is blocked by a mesh layer in the board. Further, the copper on the surface of the board is covered by some sort of insulation and will not take to solder. I ended up running a wire to a ground elsewhere, but if I were to do it again I'd scratch or drill the board until I definitely had a good electrical surface to solder to.

The wires from the LVC go to the ground, Rx, Tx ports of the RS-232 driver board, while an extra ground and the 5V power wire are soldered to appropriate spots near the DC power jack of the router. The PPS wire I've taped out of the way.

And voila! The rest was easy - with gpsd installed on the router a client could log in and immediately start to receive data from the GPS.

And so, for about $200 in parts, plus about 30 hours getting it all working, we have a GPS-enabled network router.

(Last edited by LightYear on 19 May 2010, 14:32)

Holy crap! Thank you so much for documenting this process. I want you to know it is truly appreciated.


Something caught my eye when I re-read your original post... you set your environment up on OS X 10.6.3 (Snow Leopard). In 10.5 or even in 10.6.2, I did not have any issues with ncurses. With the update to 10.6.3, ncurses is broken so applications like make menuconfig don't work anymore. Does make menuconfig work for you? If so, why?


menuconfig was very broken! I was able to use it, but could not use the arrow keys and some things weren't drawn correctly. Great to hear there's a reason!

marca56 wrote:


Something caught my eye when I re-read your original post... you set your environment up on OS X 10.6.3 (Snow Leopard). In 10.5 or even in 10.6.2, I did not have any issues with ncurses. With the update to 10.6.3, ncurses is broken so applications like make menuconfig don't work anymore. Does make menuconfig work for you? If so, why?


Not to completely troll this conversation off of thread, but I found this when searching Google high and low to figure out why make menuconfig is bombing out. I've even tried compiling in alternate ncurses support (including from MacPorts) with no such luck, and am having a heckuva' time trying to get Asterisk compiled on Snow Leopard Server w/ all the latest updates applied. (Sigh)

Earlier you said you used the accelerator keys? What is that, how do you use it, and did this give you the equivalent of using arrow keys?

Besides this URL, the only other one that I've found is … r-mac.html

Any help would be greatly appreciated!

thanks, and have a great night,

macrocode: I got by by pressing the highlighted letter in each menu option, rather than navigating the menu using the arrow keys. For example, in the screenshot below (taken from Wikipedia, and not specific to OpenWrt) the "accelerator keys" are highlighted in blue and referred to as "hotkeys". From memory if the hotkey appears twice you can press it twice to reach the second one. Once you're at the right option you can use the other command keys (eg. 'Y' and 'N') to perform actions. It was far from perfect but with some experimentation I was able to get through.

(Last edited by LightYear on 23 May 2010, 23:35)

very helpful!

Thanks... I will try that later today.


Awesome, and thank you!

So is this a problem that's in Snow Leopard's Xcode itself, or would I be able to patch in from the ncurses package in MacPorts? If I can patch in from MacPorts, do you have any suggestions, as I can't seem to make it play nice with --with-ncurses=/path/to/MacPorts/goes/here

The discussion might have continued from here.