Firmware information

Testing on v1.08 on a C1 DNS-323

Note: I haven't tested writing to most of these devices, for fear of bricking my unit. Testers wanted!

Boot process

  1. You press the power button
  2. The device powers on
  3. The bootloader image is loaded from the flash chip: 0x7D0000 - 0×800000
  4. The bootloader loads the kernel image: 0×20000 - 0x1A0000
  5. The kernel copies the environment to the RAM: 0x1A0000 - 0x7D0000 to /dev/ram0
  6. The kernel runs /etc/inittab, gathering that /dev/ram0 is the rootfs from /etc/fstab
    1. inittab runs /etc/rc.sh
      1. rc.sh mounts all the filesystems
      2. mtd_check
      3. It copies and links a lot of files from the squashfs image and mtdblock0
      4. mtdblock0 is unmounted
      5. Load /lib/modules/sd_mod.ko and usblp.ko to the kernel
      6. adjtimex -t 9960
      7. Writes time to system
      8. /sbin/fan.script
        1. Stop fan for 1 second
        2. Set fan to low speed
        3. Write status to /tmp/fan_status
      9. Setup loopback network interface
      10. Read MAC address from firmware files
      11. Sleep 2 seconds
      12. Set /proc/sys/net/ipv4/ip_forward to 0
      13. If /tmp/wrongdate exists, reboot now
      14. chg_hostname
      15. Run rc.init.sh from mtdblock0
        1. Start DHCP:
        2. /sbin/udhcpc -i egiga0 -H NAS -p /var/run/udhcpc.pid -s /usr/share/udhcpc/default.script -x 192.168.0.32 -q -b
        3. route add default gw 192.168.0.1
        4. route add -net 224.0.0.0 netmask 255.0.0.0 dev egiga0
        5. /bin/hostname DNS-323 (change hostname to DNS-323)
      16. Set full permissions for /dev/null and change it's owner to 501 (nobody)
      17. judge_swap 2
      18. write_raidtab
      19. chkraidversion
      20. hd_verify
      21. write_raidtab
      22. check_mtdaapd_path
      23. scsi_mapping
      24. Start SMB:
      25. smbcom
      26. smbd -D
      27. nmbd -D
      28. ex_goweb & (background)
      29. SetTimeZone
      30. stime
      31. crond
      32. xmldb -n config & (background)
      33. Display version information (/sys/crfs/default/version.txt)
      34. route add -net 224.0.0.0 netmask 255.0.0.0 dev egiga0
      35. /usr/sbin/mfg_search
      36. Run /bin/upnpscript from mtdblock0
        1. Kill processes called 'upnp'
        2. Start UPNP with D-Link information, sharing /mnt
      37. Record current LAN MAC to /etc/macaddr
      38. Start bittorrent support
      39. Softlink BT config files
      40. chk_openssl & (background)
      41. sharedname_sort & (background)
      42. Kill processes called 'webs'
      43. Start web interface server in background
      44. Backup SCSI file from /proc/scsi/scsi
      45. Run /usr/sbin/chk_fun_plug & (background)
        1. Sleep 30 seconds (annoying!)
        2. In a very convoluted way, run /mnt/HD_a2/fun_plug if it exists
      46. Run fanscript
        1. This determines how the fan reacts to temperature
        2. Read the value for CF-FAN-CONTROL from /web/sib.conf
        3. If 0, the fan will automatically change speed or switch off
        4. If 1, the fan will automatically change speed, but never swtich off
        5. If 2, the fan remains at high speed
        6. Default to 0
      47. Start USB support
      48. daylight (DST)
      49. ex_opserver
      50. Touch /tmp/boot_finished
      51. Record /proc/uptime to /tmp/uptimes
      52. /usr/sbin/upscan
      53. If /tmp/upsin exists, remove it and run ”/sbin/hotplug usb add” in background
    2. inittab starts a shell, /bin/sh, on the system console

Flash memory access

The 8MB flash chip is split into 8192 1K blocks, split into 5 sections and assigned to 21 devices.

There are 4 types of firmware devices:

  • /dev/mtdX: Raw access
  • /dev/mtdblockX: Block device, can be mounted (theoretically) and has random access
  • /dev/mtdcharX: Character device, serial access only, read/write from beginning to end
  • /dev/mtdrX: Presumed to be raw, read only access

The sections are as follows:

  • 0 - 64K - Configuration
  • 1 - 64K - Configuration
  • 2 - 1,536K - Kernel image
  • 3 - 6,336K - Compressed ramdisk image
  • 4 - 192K - uboot bootloader image

Every block is represented as one of each of the above device types, EXCEPT /dev/mtdcharX. Details below.

Configuration block

These contain the more volatile configuration files of the firmware. 0 is represented in mtdchar0 and mtdchar1, while 1 is represented in mtdchar1 and mtdchar2.

The behaviour of the block devices is rather odd. One can read and write to them with no problems initially, however, on reboot, problems start to occur. If both blocks are mounted and a file is written to both, the data is not saved. If only one block is mounted, and a file written to it, the data is saved to both blocks. You also sometimes need to manually unmount to save the data. I haven't tested for deleting data, or in the case of power loss.

The easiest thing to do is to only deal with 0 as the de-facto configuration block. Never mount or modify 1, and always ensure to unmount after your modifications.

If you want to flash this block with a default.tar.gz file, you could do something like this:

mkdir /sys/default
mount /dev/mtdblock0 /sys/default
cd /sys
tar xzf /mnt/HD_a2/default.tar.gz
umount /dev/mtdblock0
reboot

BRICK WARNING: Using a bad rc.init.sh can brick the device, as this is non-volatile memory you are writing to.

Kernel image

This contains the kernel image that is loaded by the bootloader. It is a standard Linux kernel binary, compiled for ARM. The easiest way to flash the kernel is to do a direct copy from a file:

dd if=/mnt/HD_a2/kernel.bin of=/dev/mtdblock2
reboot

This shouldn't affect running processes, as the kernel is copied into memory on boot. Oh, and BRICK WARNING. You probably won't ever need to do this unless you want to update the core kernel. Drivers etc. can be loaded through .ko files and insmod. The kernel image is also represented in mtdchar4 and mtdchar5.

Ramdisk image

This is essentially a compressed gzip file called ramdisk_el with a 64-byte header at the beginning. On boot, it is copied to a ramdisk, /dev/ram0, and mounted to the root. It contains all the necessary binaries and libraries to run the system. To work in the device, ramdisk images need to be 6MB or less when compressed, and 10MB exactly when expanded. Note that the compression is not limited to gzip, that is simply the default option specified for D-Link's mkimage program, found in the GPL files. Also specified in mkimage are the processor architecture and OS type, hinting at the possibility for further modification.

To flash the ramdisk, we first need to get our ramdisk image on a computer:

gunzip ramdisk_el.gz
mount ramdisk_el /mnt/ramdisk -o loop
#do modifications now
read x
umount /mnt/ramdisk
gzip ramdisk_el
mkimage -A arm -O linux -T ramdisk -C gzip -a 0x00800000 -n Ramdisk -d ramdisk_el.gz uRamdisk

Then we copy the image to the NAS, and:

dd if=/mnt/HD_a2/uRamdisk of=/dev/mtdblock3
reboot

This will permanently modify the firmware image, so BRICK WARNING. For a softer modification, you could try this for the second step:

dd if=/mnt/HD_a2/uRamdisk of=/mnt/HD_a2/ramdisk_el.gz skip=64 #This assumes gzip compression etc.
gunzip /mnt/HD_a2/ramdisk_el.gz
killall5
dd if=/mnt/HD_a2/ramdisk_el of=/dev/ram0
/bin/sh /etc/rc.sh

This will affect (i.e. kill) all running processes and effectively reset the system, and isn't a perfect solution, as the program memory is not reset, so environment variables will not be reset. However, if incorporated into a fun_plug, you can effectively run non-standard firmware while entirely removing the risk of bricking the device, as you can restore it by simply removing the drive.

Bootloader image

This is usually a binary of u-Boot 1.1.1 compiled for ARM. BRICK WARNING! This is the absolute first thing to be run on pressing the power button, and is completely out of the picture as soon as the kernel is loaded, so don't even think about flashing it unless you have a serial cable handy and are ready to use it.

The main purpose of flashing this section is to modify the kernel options passed. You would do the flashing, quite simply, like this:

dd if=/mnt/HD_a2/u-boot.bin of=/dev/mtdblock4
reboot

Other Devices

Storage

The kernel can cope with the standard 16 SCSI (read: high speed) devices, with 16 partitions each, named /dev/sd[a-p][0-15]. These will be used for USB storage devices and the two SATA drives. It can also theoretically handle one old IDE drive, /dev/hda[0-9].

RAID storage

When a RAID arrangement is set up between the SATA drives, they are mounted to /dev/md0 or both md0 and md1, depending on the RAID setting.

USB printer

USB printers are automatically found and loaded to /dev/usblp0 with the usblp.ko kernel module.

Loopback devices

There are a maximum of 5 loopback devices available, for mounting filsystem images: /dev/loop[0-5] They would be used like this:

mount /mnt/HD_a2/filesystem.img /mnt/img -o loop

Behind the scenes, a loop device would be used to interface between applications and the filesystem image.

Ramdisks

The kernel supports up to 3 ramdisks, each allocated 10MB exactly. Normally, only /dev/ram0 is in use, but after formatting, /dev/ram and /dev/ram1 can be used as well:

mke2fs -m 0 /dev/ram1
mount /dev/ram1 /mnt/ram1

Remember that, as with all ramdisks, the memory used is not recoverable until a reboot is performed, as the kernel flags it once it is touched. Also remember that the DNS-323 only has 64MB of ram, so use it wisely.

The size of the ramdisks is predetermined by the bootloader and kernel options.

Direct memory access

You can directly access the memory with the /dev/mem device. For some reason, copying the whole thing gives a “Bad address” error, and copying it back gives a segmentation fault, then locks up the device completely.

Kernel memory

This is located at /dev/kmem. Trying to read from this device gives a segmentation fault, as it is protected memory.

Flash devices

Presumably these are used to flash the firmware, however it can be written to directly as discussed above, and trying to read from these devices gives a “no such device” error. They are located at /dev/flasha[1-7] and /dev/flashb[1-7]. There are some symlinks that point to these blocks, namely:

  • flash_environment: flasha3
  • flash_kernel: flasha2
  • flash_monitor: flasha1
  • flash_reserved: flasha4

NAND Flash Transition Layer

Same story as the flash devices above. They are: /dev/nftla[1-7] and /dev/nftlb[1-4].

TTY

A number of TTY devices are theoretically available: /dev/tty, /dev/tty[0-3] and /dev/ttyS[0-1]. One of these should point to the serial connector on the mainboard, probably /dev/ttyS0. The virtual master/slave device, /dev/ptmx, is also supported.

Consoles

These are the IO ports for the various user sessions.

  • /dev/console: The system console
  • /dev/pts/X: Where X is the UID of the user

Pseudo-devices

These are not actual hardware ports, nor are they virtual devices or user sessions.

  • /dev/null: Accepts all input, outputs none, and destroys all
  • /dev/zero: Outputs a constant stream of nullbytes (0×00)
  • /dev/random: Generates random data. This one blocks.
  • /dev/uramdom: Generates random data. This one does not block.

Unused devices

A number of devices are present in /dev, and work on PC versions of Linux, but in this case do not:

  • /dev/mouse: Normally the mouse device, now just a symlink to /dev/null
  • /dev/fb: Framebuffer device. Symlink to /dev/fb0. As there is no graphics capability, this does not work.
  • /dev/rtc: Real time clock. Normally returns the current timestamp, but in this case is always busy, even when using hwclock. Use the rtc command to get the time.

Issues

  • Sometimes /mnt/HD_a2/fun_plug is NOT run when an unformatted hard drive is in the right bay. This is because the DNS-323 assigns /dev/sda to the right bay and /dev/sdb to the left bay, oddly. Swap the drives around.
  • The script waits 30 seconds before executing the fun_plug
  • rc.init.sh is not executed in the background
  • Hotplug does not automount USB devices

Navigation

Personal Tools