I was working on getting the DCS-930L camera support working several years back on the old forum, but eventually gave up due to USB issues that prevented the camera to work. Having a bunch of these cameras and with D-Link not having released a firmware for the last 5 years I decided to give this another shot, and after a ton of issues finally managed to get it working without requiring soldering a serial console to it. I know this is a 4/32 device and that support for these in general is going away, but hopefully there's still an opportunity to keep these working.
The Wiki page is quite outdated (I can see if I can update it later on), but as stated in the forum thread above one of the biggest challenges with this device is the stock firmware layout. In the stock firmware there is only one partition listed as "Kernel" or "Firmware" depending on version, in addition to the bootloader, config and factory settings partitions:
Creating 4 MTD partitions on "Ralink SoC physically mapped flash": 0x00000000-0x00030000 : "Bootloader" 0x00030000-0x00040000 : "Config" 0x00040000-0x00050000 : "Factory" 0x00050000-0x00400000 : "Kernel"
Problem here though is that while not showing up in the bootlog above this partition is actually split into two, and the kernel one is only 1MB in size. So any attempt to flash this device with a kernel bigger than that will fail as long as you do it through the emergency web interface, which without soldering is the only practical way of doing it. I spent a lot of time trying to slim down the current kernel in 19.07 to get below this limit, and finally managed to build one that was just a few KB below the limit. Sadly I despite much testing could not get this one to properly read the partitions after flashing it through the emergency web interface, where I got this on the serial console:
VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6 Please append a correct "root=" boot option; here are the available partitions: 1f00 192 mtdblock0 (driver?) 1f01 64 mtdblock1 (driver?) 1f02 64 mtdblock2 (driver?) 1f03 3776 mtdblock3 (driver?) Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) Rebooting in 1 seconds..
I initially thought I had just slimmed it down too much, but oddly enough booting with the current official initramfs kernel over TFTP gives the same error. Having worked on this device years back I did have an old firmware though that I knew booted. Flashing that one through the emergency web interface worked. Turns out that ssh wasn't working in that image without a root password set, but luckily telnet did, allowing me to not have to have serial access. Through telnet I logged into the device and could then scp a more proper firmware to the device and flash it through sysupgrade. The initial 1MB kernel limitation is only an issue when using the emergency web interface, so now I could re-flash again with a more proper firmware:
killall: telnetd: no process killed Sending TERM to remaining processes ... ntpd ubusd urngd logd rpcd netifd Sending KILL to remaining processes ... Performing system upgrade... Unlocking firmware ... Writing from <stdin> to firmware ... Upgrade completed Rebooting system... umount: can't unmount /dev: Resource busy umount: can't unmount /tmp: Resource busy umount: can't unmount /: Ireboot: Restarting system þ U-Boot 1.1.3 Board: Ralink APSoC DRAM: 32 MB relocate_code Pointer at: 81fac000 config usb.. ****************************** Software System Reset Occurred ****************************** flash_protect ON: from 0xBF000000 to 0xBF021767 flash_protect ON: from 0xBF030000 to 0xBF030FFF ============================================ Ralink UBoot Version: 188.8.131.52 -------------------------------------------- ASIC 3052_MP2 (Port5<->None) DRAM component: 256 Mbits SDR DRAM bus: 16 bit Total memory: 32 MBytes Flash component: NOR Flash ============================================ icache: sets:256, ways:4, linesz:32 ,total:32768 dcache: sets:128, ways:4, linesz:32 ,total:16384 ##### The CPU freq = 320 MHZ #### estimate memory size =32 Mbytes Signature: DCS-930 Release 1.11 (2011-05-31) Please choose the operation: 1: Load system code to SDRAM via TFTP. 2: Load system code then write to Flash via TFTP. 3: Boot system code via Flash (default). 4: Entr boot command line interface. 7: Load Boot Loader code then write to Flash via Serial. 9: Load Boot Loader code then write to Flash via TFTP. 0 3: System Boot system code via Flash. ## Booting image at bf050000 ... Image Name: MIPS OpenWrt Linux-4.14.215 Created: 2021-01-19 13:10:02 UTC Image Type: MIPS Linux Kernel Image (lzma compressed) Data Size: 1256560 Bytes = 1.2 MB Load Address: 80000000 Entry Point: 80000000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK No initrd ## Transferring control to Linux (at address 80000000) ... ## Giving linux memsize in MB, 32 Starting kernel ... Linux version 4.14.215 (builder@buildhost) (gcc version 7.5.0 (OpenWrt GCC 7.5.0 r11278-8055e38794)) #0 Tue Jan 19 13:10:02 2021 SoC Type: Ralink RT3350 id:1 rev:2 bootconsole [early0] enabled CPU0 revision is: 0001964c (MIPS 24KEc) MIPS: machine is D-Link DCS-930 Determined physical RAM map: memory: 02000000 @ 00000000 (usable) Initrd not found or empty - disabling initrd Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes. Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 32 bytes Zone ranges: Normal [mem 0x0000000000000000-0x0000000001ffffff] Movable zone start for each node Early memory node ranges node 0: [mem 0x0000000000000000-0x0000000001ffffff] Initmem setup node 0 [mem 0x0000000000000000-0x0000000001ffffff] random: get_random_bytes called from 0x803926ec with crng_init=0 Built 1 zonelists, mobility grouping on. Total pages: 8128 Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2 PID hash table entries: 128 (order: -3, 512 bytes) Dentry cache hash table entries: 4096 (order: 2, 16384 bytes) Inode-cache hash table entries: 2048 (order: 1, 8192 bytes) Writing ErrCtl register=0002f9d0 Readback ErrCtl register=0002f9d0 Memory: 27348K/32768K available (3070K kernel code, 167K rwdata, 412K rodata, 1208K init, 196K bss, 5420K reserved, 0K cma-reserv) SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 NR_IRQS: 256 CPU Clock: 320MHz timer_probe: no matching timers found clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 11945377789 ns sched_clock: 32 bits at 160MHz, resolution 6ns, wraps every 13421772796ns Calibrating delay loop... 212.58 BogoMIPS (lpj=1062912) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 1024 (order: 0, 4096 bytes) Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes) clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns futex hash table entries: 256 (order: -1, 3072 bytes) pinctrl core: initialized pinctrl subsystem NET: Registered protocol family 16 rt2880_gpio 10000600.gpio: registering 24 gpios rt2880_gpio 10000600.gpio: registering 24 irq handlers clocksource: Switched to clocksource MIPS NET: Registered protocol family 2 TCP established hash table entries: 1024 (order: 0, 4096 bytes) TCP bind hash table entries: 1024 (order: 0, 4096 bytes) TCP: Hash tables configured (established 1024 bind 1024) UDP hash table entries: 256 (order: 0, 4096 bytes) UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) NET: Registered protocol family 1 rt-timer 10000100.timer: maximum frequency is 3255Hz workingset: timestamp_bits=30 max_order=13 bucket_order=0 squashfs: version 4.0 (2009/01/31) Phillip Lougher jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc. io scheduler noop registered io scheduler deadline registered (default) Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled console [ttyS0] disabled 10000c00.uartlite: ttyS0 at MMIO 0x10000c00 (irq = 20, base_baud = 6666666) is a Palmchip BK-3103 console [ttyS0] enabled console [ttyS0] enabled bootconsole [early0] disabled bootconsole [early0] disabled 1f000000.cfi: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x0000c2 Chip ID 0x0022a8 Amd/Fujitsu Extended Query Table at 0x0040 Amd/Fujitsu Extended Query version 1.1. number of CFI chips: 1 4 fixed-partitions partitions found on MTD device 1f000000.cfi Creating 4 MTD partitions on "1f000000.cfi": 0x000000000000-0x000000030000 : "u-boot" 0x000000030000-0x000000040000 : "u-boot-env" 0x000000040000-0x000000050000 : "factory" 0x000000050000-0x000000400000 : "firmware" 2 uimage-fw partitions found on MTD device firmware Creating 2 MTD partitions on "firmware": 0x000000000000-0x000000132cb0 : "kernel" 0x000000132cb0-0x0000003b0000 : "rootfs" mtd: device 5 (rootfs) set to be root filesystem 1 squashfs-split partitions found on MTD device rootfs 0x000000340000-0x0000003b0000 : "rootfs_data" libphy: Fixed MDIO Bus: probed rt3050-esw 10110000.esw: link changed 0x01 mtk_soc_eth 10100000.ethernet eth0: mediatek frame engine at 0xb0100000, irq 5 rt2880_wdt 10000120.watchdog: Initialized NET: Registered protocol family 17 bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need th. 8021q: 802.1Q VLAN Support v1.8 VFS: Mounted root (squashfs filesystem) readonly on device 31:5. Freeing unused kernel memory: 1208K This architecture does not have kernel memory protection. random: fast init done init: Console is alive init: - watchdog - kmodloader: loading kernel modules from /etc/modules-boot.d/* usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb dwc2 101c0000.otg: Configuration mismatch. dr_mode forced to host dwc2 101c0000.otg: DWC OTG Controller dwc2 101c0000.otg: new USB bus registered, assigned bus number 1 dwc2 101c0000.otg: irq 26, io mem 0x101c0000 hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected kmodloader: done loading kernel modules from /etc/modules-boot.d/* init: - preinit - usb 1-1: new full-speed USB device number 2 using dwc2 8021q: adding VLAN 0 to HW filter on device eth0 Press the [f] key and hit [enter] to enter failsafe mode Press the , ,  or  key and hit [enter] to select the debug level random: procd: uninitialized urandom read (4 bytes read) mount_root: jffs2 not ready yet, using temporary tmpfs overlay urandom-seed: Seed file not found (/etc/urandom.seed) procd: - early - procd: - watchdog - open: No such file or directory random: jshn: uninitialized urandom read (4 bytes read) random: ubusd: uninitialized urandom read (4 bytes read) random: ubus: uninitialized urandom read (4 bytes read) Command failed: Not found procd: - init - Please press Enter to activate this console. kmodloader: loading kernel modules from /etc/modules.d/* i2c /dev entries driver Linux video capture interface: v2.00 Loading modules backported from Linux version v4.19.161-0-gdaefdc9eb24b Backport generated by backports.git v4.19.161-1-0-g4bb568fe nf_conntrack version 0.5.0 (1024 buckets, 4096 max) xt_time: kernel timezone is -0000 ip_tables: (C) 2000-2006 Netfilter Core Team usbcore: registered new interface driver snd-usb-audio urngd: v1.0.2 started. uvcvideo: Found UVC 1.00 device <unnamed> (1b3b:2970) uvcvideo: UVC non compliance - GET_DEF(PROBE) not supported. Enabling workaround. input: UVC Camera (1b3b:2970) as /devices/platform/101c0000.otg/usb1/1-1/1-1:1.0/input/input0 usbcore: registered new interface driver uvcvideo USB Video Class driver (1.1.1) rt2800_wmac 10180000.wmac: loaded eeprom from mtd device "factory" ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 2872, rev 0200 detected ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 0005 detected kmodloader: done loading kernel modules from /etc/modules.d/* random: crng init done random: 6 urandom warning(s) missed due to ratelimiting jffs2_scan_eraseblock(): End of filesystem marker found at 0x0 jffs2_build_filesystem(): unlocking the mtd device... done. jffs2_build_filesystem(): erasing all blocks after the end marker... 8021q: adding VLAN 0 to HW filter on device eth0 br-lan: port 1(eth0) entered blocking state br-lan: port 1(eth0) entered disabled state device eth0 entered promiscuous mode br-lan: port 1(eth0) entered blocking state br-lan: port 1(eth0) entered forwarding state done. jffs2: notice: (986) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of. overlayfs: upper fs does not support tmpfile.
To fit the new firmware onto the small flash I had to slim it down considerably, but not having the 1MB kernel limit anymore it was not any issues building a firmware that is fully functional for it's intended use case. With networking + wireless, ssh and mjpg-streamer built in I still have about 500KB left for the JFFS2 partition. I have removed anything not strictly needed to run the camera part, like LUCI and also took out IPv6 support. I did the steps above on a second DCS-930 A1 device lacking serial console, and it worked fine there too.
mjpg-streamer requires a bit of configuration changes to work, I will try to work that into the firmware itself to not waste JFFS2 space changing it. Here's the config I have for it now:
root@OpenWrt:~# cat /etc/config/mjpg-streamer config mjpg-streamer 'core' option enabled '1' option input 'uvc' option output 'http' option device '/dev/video0' option resolution '640x480' option fps '5' option led 'auto' option www '/www/webcam' option port '8080'
Streaming works really well, it consumes 10-20% CPU only, doing a continuous stream over HTTP. I will stream to Zoneminder so I can do the motion detection there, but in the past I know people have successfully run motion on the camera as well. Oddly enough mjpg_streamer seems to do some sort of motion detection on it's own too:
user.notice root: webcam motion event
For anyone interested I'll make my old firmware available for initial flashing, and the config for the new one too. I will give it another shot getting a version based on 19.07 compiled as well, but it will be so slimmed down that it will probably still be hard to provide it as an official factory image. Since it is only needed once maybe that isn't a big issue though. Creating a working official sysupgrade image should be doable though I think.