The D-Link DIR-685 is some kind of high-profile product from D-Link, it is labelled a Xtreme N Storage Router whatever that means. It is based solely around the Gemini platform, and ARMv4 Faraday silicon design, and has the following features:
- Router: WAN+4 LAN
- 2xUSB ports
- Wireless card
- Mini SATA drive bay
- Small video screen (!)
Getting into it
You need to remove four screws on the bottom and then there are plastic snap locks around the edges, I open these with a credit card or a letter knife.
Circuit board photos
- D-Link DIR-685 opened up
- D-Link DIR-685 touch input PCB
- D-Link DIR-685 touchkeys close-up
- D-Link DIR-685 screen
- D-Link DIR-685 PCB front 1, 2
- D-Link DIR-685 PCB back
- D-Link DIR-685 Fan
- A Ilitek ILI9322 display controller for 320RGBx240 connected to a panel with the label LM918A01-1A SY-B4-091116-E0199 connected to the main PCB with a flat cable (we know this is driven by a ILI9322 from the boot messages)
- Touch input module PCB with a Cypress Semiconductor CY8C214 MCU, with a LED connected to it (the WPS flashing LED), connected to the main PCB with a flat cable
- A Sunon Maglev GM0502PFV2-8GN 0.4W fan connected to the main PCB, software controlled
- Alpha Networks WMP-N08 Mini-PCI RaLink RT2880F based wireless network card
- Main PCB:
- A blue LED indicating power on
- A Spansion S29GL256 256 Mbit (32MB) CFI NOR-flash memory
- A Hynix HY5DU121622DTP-D43 512 Mbit (64MB) SDRAM classed at 200MHz
- A soldered (!) RaLink RT2880 Mini-PCI wireless network card
- A Bothhand GST5009 LF 1000 Base-T magnetic module (galvanic isolator) facing the WAN port
- Two LFE9407 Delta LFE9407 LAN Filters (also galvanic isolators) facing the four LAN ports
- The Cortina CG3516 SoC ASIC is mounted in a shield box
- Apparently there is a RealTek RTL8366RB ethernet PHY/switch somewhere
- A TI SN54LVC14A schmitt-trigger array
Connecting a UART
J3 on the top is obviously the serial port. Helpfully there is even a header. There is some documentation I found online on the layout of the serial port:
PINS: o o o _ o | | | | | | | RX | | VCC | GND TX
The serial port configuration should be: 19200 baud, 8 bits, no parity, no flow control. After soldering a RS232 interface accordingly, the console works like a charm!
Booting a kernel
- The default image will drop you to a prompt so you can look around inside the D-Link firmware. It is not very bad, it is using Busybox v1.0 and the v2.
- At boot after turning on the power switch (on the cord), press CTRL+C and you
will be dropped into the boot loader which is called "Boot Menu"
and which seems to be a variant of the RedBoot boot loader. It looks like
Boot Menu ============================================================================== 0: Reboot 1: Start the Kernel Code 5: Enter Command Line Interface 6: Set IP Address 7: Set MAC Address 8: Show Configuration X: Upgrade Boot Y: Upgrade Kernel Z: Upgrade Firmware A: Upgrade Application R: Upgrade RAM Disk
- Typing 5 takes you to a command line interface where it is possible to load a kernel over Xmodem
- Load the kernel with Xmodem to 0x400000 (use minicom's CTRL+A then S) and execute it with:
sl-boot> load -m xmodem -b 0x400000 sl-boot> go 0x400000
- Obviously you should select the zImage and upload it using the xmodem protocol. With minicom this is done with CTRL+s then browse and push space over the zImage and ENTER.
- If you instead set up a TFTP server
(which I recommend, because it is faster) you need to set up the IP address
in the boot menu using alternative 6 to be 169.254.1.2, plug the ethernet crossed
cable into one of the LAN ports (not the WAN port!) and then you can use:
sl-boot> load -m tftp -b 0x400000 TFTP Server IP Address: 169.254.1.1 Image Path and name(e.g. /images/zImage): zImage TFTP Download zImage from 169.254.1.1 ....................................... Successful to download by TFTP! Size=4646107 sl-boot> go 0x400000
Compiling the kernel
Analyzing the vendor code
This bootlog from the unmodified firmware shows some kernel init and flash partitioning etc. A modified busybox binary was needed to get the dmesg out. It shows us that the kernel shipping in my router was compiled on march 25, 2010.
The vendor tree has a custom GPIO userspace access driver in boards/wrgns01/apps/nas_gpio_access/nas_gpio_access.c exposing GPIO in /proc/nas_gpio/gpio looking like this:
# cd nas_gpio/ # ls gpio # cd gpio/ # ls outen_pa_7 outen_pa_14 outen_pb_7 outen_pb_14 data_pa_13 data_pa_11 outen_pa_8 outen_pa_16 outen_pb_8 outen_pb_16 data_pb_6 data_pa_12 outen_pa_11 outen_pa_18 outen_pb_11 outen_pb_18 data_pa_7 outen_pa_12 outen_pa_6 outen_pb_12 outen_pb_6 data_pa_8
Inspecting the driver we see that for ports A and B it creates all the same output enable and data input/output files. So this means GPIO lines 6, 7, 8, 11, 12, 13, 14, 16, 18 are used on either port A or port B, and line 13 is only used as input.
There is further a userspace program for GPIO and LED control in boards/wrgns01/apps/fresetd.c where the use of different lines can be deduced. This illustrates that the blue and orange HD LEDs cannot be on at the same time.
After reverse-engineering the following is deducted:
- A7 controls the WPS LED
- A8 is input for the RESET button on the back
- A11 controls the blue HD LED
- A12 controls the orange HD LED
- A/B 14 ?
- A13 is input for the UNMOUNT button on the side
- A16 controls the backlight
- A/B 18 ?
- B6 controls the fan
14 and 18 are still unknown, we don't know which port they are used on or for what.
The vendor code also contains boards/wrgns01/apps/rtl8366/rtl8366rb a kernel module for controlling a RealTek RTL8366RB switch using GPIO. A compiled kernel module named switch.ko is in the directory and disassebling it hints that it is doing control of the switch over GPIO in response to custom ioctl() calls from userspace. It includes some kind of interrupt handler named linkInterruptHandle, setting link status, gpio_set_dir_bit, gpio_read_bit, gpio_write_bit, rtl8366rb_setEthernetPHY etc. 0x16 is passed to gpio_read_bit and 0x15 and 0x16 is passed to gpio_write_bit, so it is reasonable to assume that GPIOs 0x15 (21) and 0x16 (22) are used for controlling MDC and MDIO for the RTL8366RB SMI interface.
- Create a device tree for this platform (patch exists)
- Figure out the flash partitioning (part of the device tree)
- Enable backlight on GPIO 16 (works with just the standard GPIO backlight driver, part of the device tree)
- Create a driver for the RTL8366RB using the SMI interface
- Create a driver for the touchpad. There is a driver in the vendor kernel in drivers/i2c_alpha that uses bit-banged GPIO to emulate I2C on pins 5 (SDA) and 6 (SCL) and an interrupt on GPIO 17. It then provides ioctl()s to userspace.
- Create a driver for the fan. The vendor tree has a userspace driver in the code dump dir685.gpl.source.new0611/dir685/boards/wrgns01/apps/hdparm/smart_spindown.c that deals with this. It turns on the fan at 46 degrees and turns it off at 41 degrees (celsius). Since the device lacks a temperature sensor, this jacks into the hard disk SMART monitor, if and only if a hard disk is mounted.
Getting RT2880 wireless going
This needs kernel config CONFIG_RT2800_PCI to begin with.
- Get rt2860.bin from the Linux firmware repository, build and package into your rootfs, it needs to land in /lib/firmware/rt2860.bin
- ifconfig wlan0 192.168.1.64 netmask 255.255.255.0 up