Clone of OpenWrt repo with required changes and installable binaries. v25.12.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 including a fan control daemon.
GitHub releases include flashable binaries, but building your own is straightforward (clone openwrt's repo, check out v24.10.5 and cherry-pick top release 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.37.0 (2026-03-03 00:14:15 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 25.12.0, r32713-f919e7899d Dave's Guitar
-----------------------------------------------------
OpenWrt recently switched to the "apk" package manager!
OPKG Command APK Equivalent Description
------------------------------------------------------------------
opkg install <pkg> apk add <pkg> Install a package
opkg remove <pkg> apk del <pkg> Remove a package
opkg upgrade apk upgrade Upgrade all packages
opkg files <pkg> apk info -L <pkg> List package contents
opkg list-installed apk info List installed packages
opkg update apk update Update package lists
opkg search <pkg> apk search <pkg> Search for packages
------------------------------------------------------------------
For more information visit:
https://openwrt.org/docs/guide-user/additional-software/opkg-to-apk-cheatsheet
dmesg
root@OpenWrt:~# dmesg
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 6.12.71 (builder@buildhost) (arm-openwrt-linux-muslgnueabi-gcc (OpenWrt GCC 14.3.0 r32713-f919e7899d) 14.3.0, GNU ld (GNU Binutils) 2.44) #0 Tue Mar 3 00:14:15 2026
[ 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] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
[ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Kernel command line: console=ttyS0,115200 mtdparts=orion_nand:0x0e0000@0x0(uboot)ro,0x20000@0x0e0000(ubootenv)ro,0x7f00000@0x100000(ubi) :::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: 32768
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=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.000003] sched_clock: 32 bits at 167MHz, resolution 6ns, wraps every 12884901885ns
[ 0.000056] Switching to timer-based delay loop, resolution 6ns
[ 0.000271] Calibrating delay loop (skipped), value calculated using timer frequency.. 333.33 BogoMIPS (lpj=1666666)
[ 0.000314] CPU: Testing write buffer coherency: ok
[ 0.000475] pid_max: default: 32768 minimum: 301
[ 0.014551] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.014599] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.029349] Setting up static identity map for 0x100000 - 0x10003c
[ 0.029783] mvebu-soc-id: MVEBU SoC ID=0x6281, Rev=0x3
[ 0.030487] Memory: 118196K/131072K available (7385K kernel code, 585K rwdata, 1136K rodata, 1024K init, 242K bss, 12452K reserved, 0K cma-reserved)
[ 0.040245] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.040297] futex hash table entries: 256 (order: 0, 3072 bytes, linear)
[ 0.050299] pinctrl core: initialized pinctrl subsystem
[ 0.055289] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.056110] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.058087] thermal_sys: Registered thermal governor 'step_wise'
[ 0.058234] cpuidle: using governor ladder
[ 0.058947] Feroceon L2: Enabling L2
[ 0.058999] Feroceon L2: Cache support initialised.
[ 0.062784] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-temp-alarm
[ 0.062816] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-fan-tacho
[ 0.062841] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-present-sata1
[ 0.062865] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-present-sata0
[ 0.062888] /ocp@f1000000/pin-controller@10000: Fixed dependency cycle(s) with /ocp@f1000000/pin-controller@10000/pmx-power-back-on
[ 0.068772] No ATAGs?
[ 0.092680] SCSI subsystem initialized
[ 0.093568] libata version 3.00 loaded.
[ 0.094013] usbcore: registered new interface driver usbfs
[ 0.094091] usbcore: registered new interface driver hub
[ 0.094193] usbcore: registered new device driver usb
[ 0.097015] clocksource: Switched to clocksource orion_clocksource
[ 0.112354] NET: Registered PF_INET protocol family
[ 0.112796] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.114731] tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.114775] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 0.116143] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.116182] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[ 0.116230] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.117073] MPTCP token hash table entries: 512 (order: 1, 6144 bytes, linear)
[ 0.117408] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.117448] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.118684] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.118752] PCI: CLS 0 bytes, default 32
[ 0.123070] workingset: timestamp_bits=14 max_order=15 bucket_order=1
[ 0.125425] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.125443] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 0.130726] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[ 0.134068] kirkwood-pinctrl f1010000.pin-controller: registered pinctrl driver
[ 0.136341] gpio gpiochip0: Static allocation of GPIO base is deprecated, use dynamic allocation.
[ 0.137363] gpio gpiochip1: Static allocation of GPIO base is deprecated, use dynamic allocation.
[ 0.140233] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[ 0.145510] printk: legacy console [ttyS0] disabled
[ 0.146043] f1012000.serial: ttyS0 at MMIO 0xf1012000 (irq = 25, base_baud = 10416666) is a 16550A
[ 0.146106] printk: legacy console [ttyS0] enabled
[ 0.683958] f1012100.serial: ttyS1 at MMIO 0xf1012100 (irq = 26, base_baud = 10416666) is a 16550A
[ 0.694594] nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
[ 0.700982] nand: Samsung NAND 128MiB 3,3V 8-bit
[ 0.705591] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[ 0.713235] Scanning device for bad blocks
[ 0.821706] 3 cmdlinepart partitions found on MTD device orion_nand
[ 0.827978] Creating 3 MTD partitions on "orion_nand":
[ 0.833107] 0x000000000000-0x0000000e0000 : "uboot"
[ 0.863654] 0x0000000e0000-0x000000100000 : "ubootenv"
[ 0.870159] 0x000000100000-0x000008000000 : "ubi"
[ 0.890935] mv643xx_eth: MV-643xx 10/100/1000 ethernet driver version 1.4
[ 1.618297] mv643xx_eth_port mv643xx_eth_port.0 eth0: port 0 with MAC address fc:75:16:01:85:bd
[ 1.628097] rtc-mv f1010300.rtc: registered as rtc0
[ 1.633007] rtc-mv f1010300.rtc: setting system clock to 2026-03-22T19:25:26 UTC (1774207526)
[ 1.641684] i2c_dev: i2c /dev entries driver
[ 1.647629] orion_wdt: Initial timeout 25 sec
[ 1.657085] marvell-cesa f1030000.crypto: CESA device successfully registered
[ 1.666688] NET: Registered PF_INET6 protocol family
[ 1.675293] Segment Routing with IPv6
[ 1.679132] In-situ OAM (IOAM) with IPv6
[ 1.683225] NET: Registered PF_PACKET protocol family
[ 1.688376] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[ 1.701768] 8021q: 802.1Q VLAN Support v1.8
[ 1.753249] UBI: auto-attach mtd2
[ 1.756602] ubi0: attaching mtd2
[ 1.956878] ubi0: scanning is finished
[ 1.975919] ubi0: attached mtd2 (name "ubi", size 127 MiB)
[ 1.981466] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[ 1.988354] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[ 1.995042] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[ 2.001823] ubi0: good PEBs: 1016, bad PEBs: 0, corrupted PEBs: 0
[ 2.007921] ubi0: user volume: 3, internal volumes: 1, max. volumes count: 128
[ 2.015121] ubi0: max/mean erase counter: 5/3, WL threshold: 4096, image sequence number: 1766005702
[ 2.024248] ubi0: available PEBs: 0, total reserved PEBs: 1016, PEBs reserved for bad PEB handling: 20
[ 2.033996] ubi0: background thread "ubi_bgt0d" started, PID 362
[ 2.040769] block ubiblock0_1: created from ubi0:1(rootfs)
[ 2.046254] ubiblock: device ubiblock0_1 (rootfs) set to be root filesystem
[ 2.053538] clk: Disabling unused clocks
[ 2.067152] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
[ 2.078606] Freeing unused kernel image (initmem) memory: 1024K
[ 2.084541] Run /sbin/init as init process
[ 2.088664] with arguments:
[ 2.088676] /sbin/init
[ 2.088687] :::DB88FXX81:egiga0:none
[ 2.088697] with environment:
[ 2.088705] HOME=/
[ 2.088714] TERM=linux
[ 2.796558] init: Console is alive
[ 2.800410] init: - watchdog -
[ 3.553009] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[ 3.678417] gpio_button_hotplug: loading out-of-tree module taints kernel.
[ 3.706672] orion-ehci f1050000.ehci: EHCI Host Controller
[ 3.712292] orion-ehci f1050000.ehci: new USB bus registered, assigned bus number 1
[ 3.720156] orion-ehci f1050000.ehci: irq 35, io mem 0xf1050000
[ 3.737053] orion-ehci f1050000.ehci: USB 2.0 started, EHCI 1.00
[ 3.744278] hub 1-0:1.0: USB hub found
[ 3.748444] hub 1-0:1.0: 1 port detected
[ 3.770456] sata_mv f1080000.sata: version 1.28
[ 3.771269] sata_mv f1080000.sata: slots 32 ports 2
[ 3.782082] scsi host0: sata_mv
[ 3.787665] scsi host1: sata_mv
[ 3.791431] ata1: SATA max UDMA/133 irq 36 lpm-pol 0
[ 3.796399] ata2: SATA max UDMA/133 irq 36 lpm-pol 0
[ 4.277045] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl F300)
[ 4.285692] ata1.00: ATA-7: ST3320820AS, 3.CHN, max UDMA/100
[ 4.291389] ata1.00: 625142448 sectors, multi 0: LBA48 NCQ (depth 31/32)
[ 4.302720] ata1.00: configured for UDMA/100
[ 4.307634] scsi 0:0:0:0: Direct-Access ATA ST3320820AS N PQ: 0 ANSI: 5
[ 4.317984] sd 0:0:0:0: [sda] 625142448 512-byte logical blocks: (320 GB/298 GiB)
[ 4.325556] sd 0:0:0:0: [sda] Write Protect is off
[ 4.330385] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[ 4.330491] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 4.339678] sd 0:0:0:0: [sda] Preferred minimum I/O size 512 bytes
[ 4.362376] sda: sda1 sda2
[ 4.365617] sd 0:0:0:0: [sda] Attached SCSI disk
[ 9.867028] ata2: link is slow to respond, please be patient (ready=0)
[ 10.587043] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl F300)
[ 10.617301] ata2.00: ATA-8: SAMSUNG HD501LJ, CR100-13, max UDMA7
[ 10.623307] ata2.00: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32)
[ 10.632631] ata2.00: configured for UDMA/133
[ 10.637547] scsi 1:0:0:0: Direct-Access ATA SAMSUNG HD501LJ 0-13 PQ: 0 ANSI: 5
[ 10.647710] sd 1:0:0:0: [sdb] 976773168 512-byte logical blocks: (500 GB/466 GiB)
[ 10.655239] sd 1:0:0:0: [sdb] Write Protect is off
[ 10.660072] sd 1:0:0:0: [sdb] Mode Sense: 00 3a 00 00
[ 10.660178] sd 1:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 10.669369] sd 1:0:0:0: [sdb] Preferred minimum I/O size 512 bytes
[ 10.687483] sdb: sdb1
[ 10.690267] sd 1:0:0:0: [sdb] Attached SCSI disk
[ 10.700140] usbcore: registered new interface driver usb-storage
[ 10.707608] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 10.717900] init: - preinit -
[ 13.797063] random: crng init done
[ 17.778961] mv643xx_eth_port mv643xx_eth_port.0 eth0: link up, 1000 Mb/s, full duplex, flow control disabled
[ 19.844771] UBIFS (ubi0:2): Mounting in unauthenticated mode
[ 19.881587] UBIFS (ubi0:2): background thread "ubifs_bgt0_2" started, PID 560
[ 20.011777] UBIFS (ubi0:2): UBIFS: mounted UBI device 0, volume 2, name "rootfs_data"
[ 20.019656] UBIFS (ubi0:2): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[ 20.029573] UBIFS (ubi0:2): FS size: 119218176 bytes (113 MiB, 924 LEBs), max 935 LEBs, journal size 5935104 bytes (5 MiB, 46 LEBs)
[ 20.041382] UBIFS (ubi0:2): reserved for root: 4952683 bytes (4836 KiB)
[ 20.048001] UBIFS (ubi0:2): media format: w5/r0 (latest is w5/r0), UUID D25C5BE5-40FB-4018-96FE-6627E1CBA82C, small LPT model
[ 20.060749] mount_root: overlay filesystem has not been fully initialized yet
[ 20.069111] mount_root: switching to ubifs overlay
[ 20.473273] urandom-seed: Seed file not found (/etc/urandom.seed)
[ 20.581736] procd: - early -
[ 20.586017] procd: - watchdog -
[ 21.248621] procd: - watchdog -
[ 21.252205] procd: - ubus -
[ 21.347485] procd: - init -
[ 22.762638] kmodloader: loading kernel modules from /etc/modules.d/*
[ 22.880797] tun: Universal TUN/TAP device driver, 1.6
[ 22.901022] NET: Registered PF_APPLETALK protocol family
[ 22.939103] hwmon hwmon0: temp1_input not attached to any thermal zone
[ 22.959957] hwmon hwmon1: temp1_input not attached to any thermal zone
[ 22.979893] gpio-fan gpio_fan: GPIO fan initialized
[ 23.220580] PPP generic driver version 2.4.2
[ 23.240028] NET: Registered PF_PPPOX protocol family
[ 23.278072] kmodloader: done loading kernel modules from /etc/modules.d/*
[ 24.092345] urngd: v1.0.2 started.
[ 34.856645] br-lan: port 1(eth0) entered blocking state
[ 34.861965] br-lan: port 1(eth0) entered disabled state
[ 34.867263] mv643xx_eth_port mv643xx_eth_port.0 eth0: entered allmulticast mode
[ 34.874875] mv643xx_eth_port mv643xx_eth_port.0 eth0: entered promiscuous mode
[ 37.158150] mv643xx_eth_port mv643xx_eth_port.0 eth0: link up, 1000 Mb/s, full duplex, flow control enabled
[ 37.168070] br-lan: port 1(eth0) entered blocking state
[ 37.173301] br-lan: port 1(eth0) entered forwarding state
Adventures in flashing
OpenWrt can be installed without disassembly by using a patched version of Alt-F. Details on a post later on this thread or on GitHub repo. Install v25.10.5-r1 and then sysupgrade to any other (newer or older).
The safest approach to install is to disassemble the unit. 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.
As scary as flashing the bootloader sounds, these kirkwood devices are unbrickable. Full disassembly, a CP210x USB to UART Bridge (or similar), and a ext4 -formatted USB 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 (a truly unbrickable device). 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. If someone figures that out please share.
Installation
UPDATE: Installation without disassembly (carries a risk of bricking the device if anything goes wrong, requiring disassembly to unbrick) here: Post Below . This is the preferred installation method if running Alt-F or stock.
UPDATE: u-boot has now an option to flash environment or OpenWrt image from USB. Details here: Post below . This is the preferred recovery mechanism if u-boot was successfully flashed but env/ubi flash failed, before going for the screwdriver.
Safest approach is to disassemble. These are very succinct instructions with dissassembly, more details were shared on a later post.
- Copy
u-boot.kwbandopenwrt-25.12.0-kirkwood-generic-dlink_dns320-squashfs-factory.binto a ext4 USB drive (rename the latter tofactory.binto make life easier. - Connect USB drive and TTL to the board. Run a terminal on the computer (
minicomworked great for me) - Power up or reboot the board and interrupt the boot by hitting [space] and '1'. Should give a u-boot prompt.
- Load
u-boot.kwbto memory and erase/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 aresetto restart the board with the new u-boot.
Important: After everyext4loadcommand validate the load was successful before proceeding. A message like590156 bytes read in 45 ms (12.5 MiB/s)must be returned. If not, unplug/replug the USB and try again, and if not successful try with a different USB drive. The chipset is picky when it comes to USB drives, and some USB drives out there are very low quality.
Something like:
usb reset ; ext4load usb 0:1 0x1000000 /u-boot.kwb
NOTE: device must respond with "590156 bytes read in 45 ms (12.5 MiB/s)" - where bytes read matches u-boot.kwb file size. Follow wih:
nand erase 0x0 0x0e0000
nand write 0x1000000 0x0 0x0e0000
reset
- Again, interrupt the boot. Load
factory.binto RAM (again... command must respond with bytes read in nnn ms (xx.y MiB/s)). Thenerase.part ubi(goodbye stock firmware, including mini-firmware, whatever you were) and write to address 0x100000. As per @Holig further down on this thread:
usb reset ; ext4load usb 0:1 0x1000000 /factory.bin
nand erase.part ubi
nand write 0x1000000 ubi 0xa80000
(no reset yet - set MAC address as per next point before)
- 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. 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.
Recovery in case of issues or u-boot bricking
Refer to:
Thanks @Freeflod
Acknowledgements & reference:













