====== 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 ===== - You press the power button - The device powers on - The bootloader image is loaded from the flash chip: 0x7D0000 - 0x800000 - The bootloader loads the kernel image: 0x20000 - 0x1A0000 - The kernel copies the environment to the RAM: 0x1A0000 - 0x7D0000 to /dev/ram0 - The kernel runs /etc/inittab, gathering that /dev/ram0 is the rootfs from /etc/fstab - inittab runs /etc/rc.sh - rc.sh mounts all the filesystems - mtd_check - It copies and links a lot of files from the squashfs image and mtdblock0 - mtdblock0 is unmounted - Load /lib/modules/sd_mod.ko and usblp.ko to the kernel - adjtimex -t 9960 - Writes time to system - /sbin/fan.script - Stop fan for 1 second - Set fan to low speed - Write status to /tmp/fan_status - Setup loopback network interface - Read MAC address from firmware files - Sleep 2 seconds - Set /proc/sys/net/ipv4/ip_forward to 0 - If /tmp/wrongdate exists, reboot now - chg_hostname - Run rc.init.sh from mtdblock0 - Start DHCP: - /sbin/udhcpc -i egiga0 -H NAS -p /var/run/udhcpc.pid -s /usr/share/udhcpc/default.script -x 192.168.0.32 -q -b - route add default gw 192.168.0.1 - route add -net 224.0.0.0 netmask 255.0.0.0 dev egiga0 - /bin/hostname DNS-323 (change hostname to DNS-323) - Set full permissions for /dev/null and change it's owner to 501 (nobody) - judge_swap 2 - write_raidtab - chkraidversion - hd_verify - write_raidtab - check_mtdaapd_path - scsi_mapping - Start SMB: - smbcom - smbd -D - nmbd -D - ex_goweb & (background) - SetTimeZone - stime - crond - xmldb -n config & (background) - Display version information (/sys/crfs/default/version.txt) - route add -net 224.0.0.0 netmask 255.0.0.0 dev egiga0 - /usr/sbin/mfg_search - Run /bin/upnpscript from mtdblock0 - Kill processes called 'upnp' - Start UPNP with D-Link information, sharing /mnt - Record current LAN MAC to /etc/macaddr - Start bittorrent support - Softlink BT config files - chk_openssl & (background) - sharedname_sort & (background) - Kill processes called 'webs' - Start web interface server in background - Backup SCSI file from /proc/scsi/scsi - Run /usr/sbin/chk_fun_plug & (background) - Sleep 30 seconds (annoying!) - In a very convoluted way, run /mnt/HD_a2/fun_plug if it exists - Run fanscript - This determines how the fan reacts to temperature - Read the value for CF-FAN-CONTROL from /web/sib.conf - If 0, the fan will automatically change speed or switch off - If 1, the fan will automatically change speed, but never swtich off - If 2, the fan remains at high speed - Default to 0 - Start USB support - daylight (DST) - ex_opserver - Touch /tmp/boot_finished - Record /proc/uptime to /tmp/uptimes - /usr/sbin/upscan - If /tmp/upsin exists, remove it and run "/sbin/hotplug usb add" in background - See [[http://linux-hotplug.sourceforge.net]] for more info - 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 (0x00) * /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