Clone of OpenWrt repo with required changes and installable binaries. v24.10.0 (I'll add other releases as they become available, and patches can be adjusted for Snapshot but that's a moving target I don't want to keep up with):
Changes for device support are in a single commit. A second commit has the fan control daemon. Will merge those for future releases.
GitHub releases include flashable binaries, but building your own is straightforward (clone openwrt's repo, check out v24.10.0 and cherry-pick top two releases from here. This repo includes a diffconfig). Images + u-boot are for a D-Link DNS-320-A1. Other hardware versions (including A2) are untested and most probably will not work.
Any feedback or review comments welcome. The goal is to have a PR to add support to OpenWrt main with a non-zero chance for it to be accepted.
Status
Everything works.
BusyBox v1.36.1 (2025-02-03 23:09:37 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 24.10.0, r28427-6df0e3d02a
-----------------------------------------------------
dmesg
root@OpenWrt:~# dmesg
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 6.6.73 (builder@buildhost) (arm-openwrt-linux-muslgnueabi-gcc (OpenWrt GCC 13.3.0 r28427-6df0e3d02a) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 Mon Feb 3 23:09:37 2025
[ 0.000000] CPU: Feroceon 88FR131 [56251311] revision 1 (ARMv5TE), cr=0005397f
[ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[ 0.000000] OF: fdt: Machine model: D-Link DNS-320 NAS (Rev A1)
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=132768
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Kernel command line: console=ttyS0,115200 :::DB88FXX81:egiga0:none
[ 0.000000] Unknown kernel command line parameters ":::DB88FXX81:egiga0:none", will be passed to user space.
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 32480
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 118624K/131072K available (7193K kernel code, 593K rwdata, 1076K rodata, 1024K init, 235K bss, 12448K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[ 0.000000] clocksource: orion_clocksource: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 11467562657 ns
[ 0.000002] sched_clock: 32 bits at 167MHz, resolution 6ns, wraps every 12884901885ns
[ 0.000056] Switching to timer-based delay loop, resolution 6ns
[ 0.000263] Calibrating delay loop (skipped), value calculated using timer frequency.. 333.33 BogoMIPS (lpj=1666666)
[ 0.000302] CPU: Testing write buffer coherency: ok
[ 0.000456] pid_max: default: 32768 minimum: 301
[ 0.015107] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.015153] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.028892] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[ 0.029293] Setting up static identity map for 0x100000 - 0x10003c
[ 0.029787] mvebu-soc-id: MVEBU SoC ID=0x6281, Rev=0x3
[ 0.039334] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.039393] futex hash table entries: 256 (order: -1, 3072 bytes, linear)
[ 0.043246] pinctrl core: initialized pinctrl subsystem
[ 0.048638] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.049429] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.051622] thermal_sys: Registered thermal governor 'step_wise'
[ 0.051695] cpuidle: using governor ladder
[ 0.052295] Feroceon L2: Enabling L2
[ 0.052343] Feroceon L2: Cache support initialised.
[ 0.055788] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-temp-alarm
[ 0.055817] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-fan-tacho
[ 0.055840] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-present-sata1
[ 0.055863] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-present-sata0
[ 0.055886] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-power-back-on
[ 0.061732] No ATAGs?
[ 0.071316] SCSI subsystem initialized
[ 0.072202] libata version 3.00 loaded.
[ 0.072592] usbcore: registered new interface driver usbfs
[ 0.072654] usbcore: registered new interface driver hub
[ 0.072716] usbcore: registered new device driver usb
[ 0.075338] clocksource: Switched to clocksource orion_clocksource
[ 0.090661] NET: Registered PF_INET protocol family
[ 0.090953] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.092886] tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.092930] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 0.092953] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.092985] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[ 0.093030] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.093879] MPTCP token hash table entries: 512 (order: 0, 6144 bytes, linear)
[ 0.094231] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.094269] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.095532] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.095599] PCI: CLS 0 bytes, default 32
[ 0.101133] workingset: timestamp_bits=14 max_order=15 bucket_order=1
[ 0.103422] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.103436] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 0.114070] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[ 0.117612] kirkwood-pinctrl f1010000.pin-controller: registered pinctrl driver
[ 0.119955] gpio gpiochip0: Static allocation of GPIO base is deprecated, use dynamic allocation.
[ 0.120843] gpio gpiochip1: Static allocation of GPIO base is deprecated, use dynamic allocation.
[ 0.122058] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[ 0.127478] printk: console [ttyS0] disabled
[ 0.128001] f1012000.serial: ttyS0 at MMIO 0xf1012000 (irq = 25, base_baud = 10416666) is a 16550A
[ 0.128068] printk: console [ttyS0] enabled
[ 0.648861] f1012100.serial: ttyS1 at MMIO 0xf1012100 (irq = 26, base_baud = 10416666) is a 16550A
[ 0.659507] nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
[ 0.665890] nand: Samsung NAND 128MiB 3,3V 8-bit
[ 0.670491] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[ 0.678150] Scanning device for bad blocks
[ 0.786533] 3 fixed-partitions partitions found on MTD device orion_nand
[ 0.793214] Creating 3 MTD partitions on "orion_nand":
[ 0.798360] 0x000000000000-0x0000000e0000 : "u-boot"
[ 0.853219] 0x000000100000-0x000008000000 : "ubi"
[ 0.860925] 0x0000000e0000-0x000000100000 : "env"
[ 0.890307] mv643xx_eth: MV-643xx 10/100/1000 ethernet driver version 1.4
[ 1.656643] mv643xx_eth_port mv643xx_eth_port.0 eth0: port 0 with MAC address fc:75:16:01:74:db
[ 1.666356] rtc-mv f1010300.rtc: registered as rtc0
[ 1.671258] rtc-mv f1010300.rtc: setting system clock to 2025-02-08T01:28:09 UTC (1738978089)
[ 1.679919] i2c_dev: i2c /dev entries driver
[ 1.685943] orion_wdt: Initial timeout 25 sec
[ 1.707021] marvell-cesa f1030000.crypto: CESA device successfully registered
[ 1.716835] NET: Registered PF_INET6 protocol family
[ 1.725548] Segment Routing with IPv6
[ 1.729316] In-situ OAM (IOAM) with IPv6
[ 1.733438] NET: Registered PF_PACKET protocol family
[ 1.738553] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[ 1.751877] 8021q: 802.1Q VLAN Support v1.8
[ 1.824391] UBI: auto-attach mtd1
[ 1.827787] ubi0: attaching mtd1
[ 2.028049] ubi0: scanning is finished
[ 2.048232] ubi0: attached mtd1 (name "ubi", size 127 MiB)
[ 2.053732] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[ 2.060629] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[ 2.067325] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[ 2.074094] ubi0: good PEBs: 1016, bad PEBs: 0, corrupted PEBs: 0
[ 2.080191] ubi0: user volume: 3, internal volumes: 1, max. volumes count: 128
[ 2.087420] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 1738018409
[ 2.096537] ubi0: available PEBs: 0, total reserved PEBs: 1016, PEBs reserved for bad PEB handling: 20
[ 2.106300] ubi0: background thread "ubi_bgt0d" started, PID 364
[ 2.113036] block ubiblock0_1: created from ubi0:1(rootfs)
[ 2.118546] ubiblock: device ubiblock0_1 (rootfs) set to be root filesystem
[ 2.125802] clk: Disabling unused clocks
[ 2.140391] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
[ 2.151946] Freeing unused kernel image (initmem) memory: 1024K
[ 2.157889] Run /sbin/init as init process
[ 2.161972] with arguments:
[ 2.161979] /sbin/init
[ 2.161987] :::DB88FXX81:egiga0:none
[ 2.161995] with environment:
[ 2.162001] HOME=/
[ 2.162009] TERM=linux
[ 2.721344] init: Console is alive
[ 2.725077] init: - watchdog -
[ 3.213857] kmodloader: loading kernel modules from /etc/modules-boot.d/
[ 3.359300] orion-ehci f1050000.ehci: EHCI Host Controller
[ 3.364872] orion-ehci f1050000.ehci: new USB bus registered, assigned bus number 1
[ 3.372740] orion-ehci f1050000.ehci: irq 32, io mem 0xf1050000
[ 3.405369] orion-ehci f1050000.ehci: USB 2.0 started, EHCI 1.00
[ 3.412985] hub 1-0:1.0: USB hub found
[ 3.417412] hub 1-0:1.0: 1 port detected
[ 3.438174] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 3.456085] init: - preinit -
[ 6.995385] random: crng init done
[ 10.847919] mv643xx_eth_port mv643xx_eth_port.0 eth0: link up, 1000 Mb/s, full duplex, flow control disabled
[ 12.864419] UBIFS (ubi0:2): Mounting in unauthenticated mode
[ 12.901280] UBIFS (ubi0:2): background thread "ubifs_bgt0_2" started, PID 495
[ 13.033194] UBIFS (ubi0:2): UBIFS: mounted UBI device 0, volume 2, name "rootfs_data"
[ 13.041049] UBIFS (ubi0:2): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[ 13.050944] UBIFS (ubi0:2): FS size: 120637440 bytes (115 MiB, 935 LEBs), max 946 LEBs, journal size 6064128 bytes (5 MiB, 47 LEBs)
[ 13.062744] UBIFS (ubi0:2): reserved for root: 4952683 bytes (4836 KiB)
[ 13.069350] UBIFS (ubi0:2): media format: w5/r0 (latest is w5/r0), UUID C95E2155-3276-4E1E-80DC-576E9A1EA21B, small LPT model
[ 13.082085] mount_root: overlay filesystem has not been fully initialized yet
[ 13.090469] mount_root: switching to ubifs overlay
[ 13.633184] urandom-seed: Seed file not found (/etc/urandom.seed)
[ 13.811778] procd: - early -
[ 13.814894] procd: - watchdog -
[ 14.434418] procd: - watchdog -
[ 14.438022] procd: - ubus -
[ 14.524786] procd: - init -
[ 15.263587] urngd: jent-rng init failed, err: 11
[ 15.638784] kmodloader: loading kernel modules from /etc/modules.d/*
[ 15.931182] PPP generic driver version 2.4.2
[ 15.944062] NET: Registered PF_PPPOX protocol family
[ 15.974461] kmodloader: done loading kernel modules from /etc/modules.d/*
[ 29.317292] br-lan: port 1(eth0) entered blocking state
[ 29.322546] br-lan: port 1(eth0) entered disabled state
[ 29.327864] mv643xx_eth_port mv643xx_eth_port.0 eth0: entered allmulticast mode
[ 29.335503] mv643xx_eth_port mv643xx_eth_port.0 eth0: entered promiscuous mode
[ 31.586479] mv643xx_eth_port mv643xx_eth_port.0 eth0: link up, 1000 Mb/s, full duplex, flow control enabled
[ 31.596372] br-lan: port 1(eth0) entered blocking state
[ 31.601594] br-lan: port 1(eth0) entered forwarding state
Flashing
It is necessary to get dirty to install this. The original u-boot does not support UBI, and a common issue with these devices especially at this age is NAND bad blocks. UBI was therefore a must. If the bootloader was being replaced, so was the old partitioning scheme. Installing this means saying goodbye to stock firmware or Alt-F forever. I'm fine with that.
As scary as flashing the bootloader sounds, these kirkwood devices are unbrickable. Full disassembly, a CP210x USB to UART Bridge (or similar), and a ext2 -formatted USB (or FAT) are required. Most pages on the net about flashing this device consider soldering header pins to the port... I didn't bother and just used a few pieces of a paper clip and masking tape to maintain pressure/contact. That was good enough. That is how easy going these devices are.
(I bought this second hand years ago. Whoever had it before added those heat sinks. Not sure if they help, but they don't come off easily, so I'm letting them be.)
As insurance and nice to have, but not mandatory, it helps to have a working kwboot application, which lets the device to boot from serial. This allows to test a u-boot without flashing it first (that's how friendly and unbrickable it is). Most linux distributions have one, and precompiled versions are available online for Windows.
In best of theories, with kwboot
and u-boot plus the uImage it is possible to completely boot from USB without flashing anything. That requires some u-boot environment magic that I couldn't figure out. I already flashed so it's not valuable to me to go back to stock to document that, but it's an option.
Installation steps
These are from memory... will add specifics soon.
- Copy
u-boot.kwb
andopenwrt-24.10.0-kirkwood-generic-dlink_dns320-squashfs-factory.bin
to USB (rename the latter tofactory.bin
to make life easier. - Connect USB and TTL. Run a terminal on the computer (
minicom
worked great for me) - Interrupt the boot by hitting [space] and '1'. Should give a u-boot prompt.
- Load
u-boot.kwb
to memory and erate/write it to address 0x0, which is the start of NAND and where the bootloader lives. Unless you make a backup of NAND first, you will have no way back to stock firmware or ALT-F. Do areset
to restart the board with the new u-boot. - Again, interrupt the boot. Load
factory.bin
to RAM.erase.part ubi
(goodbye stock firmware, including mini-firmware, whatever you were) and write to address 0x100000 - add the MAC address of the adapter to the environment with
setenv ethaddr 'FC:75:16:xx:xx:xx'
(get it in advance from current firmware or from sticker on bottom) and persist withsaveenv
. reset
, cross fingers and enjoy the show.
After flash is done further upgrades are handled with sysupgrade or the LuCI UI. Works really well. Already tested ksmbd and netatalk and they both work. snmpd runs fine, and so does collectd. Everything installs via opkg or LuCI. 127MB UBI partition provides tons of free space.
In progress
- it should be possible to avoid disassembly by generating an image that allows flashing the new u-boot and a temporary kernel / root filesystem. Waiting for a small USB-TTL converter so I can permanently install it to the NAS to work on that.
Acknowledgements & reference: