D-Link DNS-323

The D-Link DNS-323 is a little 2-drive NAS box. I used to use one for our file & media server. This page documents things I’ve done for it and needed to figure out.

There are a couple of other sites with some good information about using the DNS-323:


The 323’s hardware is meager but adequate for many purposes:

  • 400-ish MHz ARMv5 CPU (Marvell Orion)
  • 64 MiB RAM
  • 1 USB (2.0?) port
  • 2 SATA drive bays
  • Serial header on the motherboard

I installed 2 320GB drives and a serial port. I did the 1/8” audio jack version of the serial port install, and connected to it with the TTL-232R-3V3-AJ USB-TTL serial cable.

Operating System

Debian runs great on this box, but unfortunately the last working kernel was from Squeeze (oldstable). Fortunately, it works to run Debian 7 (Wheezy) with the kernel from Squeeze; more details on configuring this below.

The hard disks are configured with software RAID 1 using mdadm. I’m using mdadm on the partitions, not on the raw disks; I have two arrays, md0 is the root filesystem (5GB) and md1 is a big storage filesystem.

Most other Linux distributions don’t pay much attention to the Orion SoC if they support ARM. Slackware, for example, supports Kirkwood but not the older Orion chips. The BSD’s sadly don’t have stable, advertised support for Orion chips. Not even NetBSD.


The installation guide worked fine. The Wheezy kernel doesn’t work (see next section), so you should install Squeeze. You can get the network install image from here; it is a firmware image that you can upload straight into the firmware update tool in the stock DNS-323 firmware. When you reboot, it will start up an SSH daemon with username installer and password install; SSH into that to begin the install. You can also talk with the installer over a serial port.


The reason I’m running the Squeeze kernel (2.6.32) is that newer kernels have various problems with the DNS-323 hardware. Most notably, they panic when scanning the MD disk array (#699667). Other kernel versions that fix that problem have I2C problems controlling the fan (#622325). And the 3.10 kernel in wheeze-backports and 3.11 kernel in Debian Testing (Jessie), have yet another error: they get stuck in a loop trying to talk to the hard drives, receiving errors (or messages they can’t parse) from the hard drives. So it really works best to stick with kernel 2.6.32.

Debian includes a flash-kernel program that you need to run to actually install a new kernel to the flash memory and have it booted. Debian Wheezy automatically runs this when you install a new kernel; Debian Squeeze does not. Just running sudo flash-kernel will flash the most recent kernel and its initramfs to the device’s flash memory. Unfortunately, there isn’t a way to make it flash an old kernel; you have to uninstall all newer kernels so just the one you want to flash is installed, then run it without arguments.

Upgrading to Wheezy

After installing with Squeeze, you can upgrade to Wheezy. To keep the old kernel, with updates from Squeeze (and its long-term support), there are a couple of things to do. First, have entries for both Debian versions in /etc/apt/sources.list:

deb http://debian.osuosl.org/debian/ wheezy main
deb http://debian.osuosl.org/debian/ squeeze main

deb http://security.debian.org/ wheezy/updates main
deb http://security.debian.org/ squeeze/updates main

deb http://debian.osuosl.org/debian/ wheezy-updates main
# no need for squeeze-updates

Then use /etc/apt/preferences to make Squeeze not-preferred, except for kernel packages, where it is strongly preferred:

Package: linux-image-* firmware-linux-*
Pin: release n=squeeze
Pin-Priority: 1001

Package: *
Pin: release n=squeeze
Pin-Priority: 50

# also un-prefer unstable
Package: *
Pin: release a=unstable
Pin-Priority: 50

This will keep your kernel up-to-date from Squeeze on an otherwise up-to-date Wheezy (or Wheezy + Backports) system.


I’ve had to get very good at recovering the 323 in the process of identifying a working kernel. Fortunately, the Debian instrutions work pretty well. These instructions are based heavily on those, with some more info to get them working well with newer environments.

To recover, you need a few things:

The firmware update image that you get from Debian (or from D-Link, if you want to recover the stock firmware) is a FrodoII firmware image. The dns323-firmware-tools let you extract separate uKernel and uRamdisk files from the firmware image that you can flash with Kermit.

New versions of the firmware tools do not work, in my experience. I have been able to get version 0.3 to work (it is tagged in git). Unfortunately, this version only works with Ruby 1.8. If you have a newer Ruby installed, the easiest path is to use JRuby. It maintains Ruby 1.8 compatibility.

So, extract the firmware:

$ git clone https://github.com/mpalmer/dns323-firmware-tools.git
$ (cd dns323-firmware-tools && git checkout 0.3)
$ jruby --1.8 dns323-firmware-tools/splitdns323fw \
    -k uKernel -i uRamdisk netinst.img

Then launch Kermit and set it up to talk to the DNS-323:

$ kermit -l /dev/ttyUSB0 -b 115200
C-Kermit> set carrier-watch off
C-Kermit> set flow-control none
C-Kermit> set handshake none
C-Kermit> set prefixing all
C-Kermit> set streaming off
C-Kermit> set parity none
C-Kermit> c

The last c command starts a serial console connection so you can watch for boot messages.

Boot the device. It will show a boot countdown; while this is going, enter <Space>1 to drop to a bootloader prompt. You then need to bounce back and forth between that prompt and Kermit to flash the firmware:

  1. Enter loadb k at the Marvell>> boot loader prompt.
  2. Hit C-\ c to escape back to Kermit.
  3. In Kermit, type send uKernel. It will send the kernel.
  4. Reconnect to the console with c; wait for the Marvell>> prompt again. If the console seems frozen, you can hit Enter.
  5. Enter loadb r at the Marvell>> prompt.
  6. Escape to Kermit wth C-\ c again
  7. Enter send uRamdisk in Kermit
  8. After the ramdisk is sent, type c to reconnect and wait for flashing to finish. The console often seems to hang on this for me; hitting Enter wakes it up.
  9. Once you have a Marvell>> prompt again, pull the power, plug it back in, and boot.

You now have the installer re-flashed. You can do an install (wiping out existing data) or use the installer image to recover. The Kermit console will let you monitor the installer boot; start into the installer, then hit ‘Go back’ when it starts asking you for passwords, to get to the main installer menu. This will let you do things like ‘Detect disks’, which will make sure the appropriate software to control the Software RAID (and therefore chroot into the real install) is installed.


The 323 has a little software-controlled fan. The fancontrol script is the usual way to control this fan. This is a shell script that watches the thermal sensors and controls the fan speed. Since it’s written in shell, though, it spawns a lot of processes to do its work (every time it wakes up, several are spawned). So I wrote fand, a small C daemon that does the same job. So far, this is the only hardware I have tested fand on. But it works pretty well. The system still gets a bit hot, though, when there is heavy disk activity.


The slow processor and limited RAM impose some significant limits on what the 323 can do. It can do quite a bit - SSH, decoding MP3s and Ogg Vorbis files in real time, etc. Decoding AAC is a bit too much for it, and if you turn on SSH compression, that bottlenecks file transfer.