Terastation TS3210DN

Stock Firmware Installation

 * Install blank drives into the device and then power it on.
 * The device will bring up a web interface which can be used to format the drives and install the firmware.

Root Access
This device can be sent commands via ACP_Commander.

a basic root shell can be accessed by sending the following
 * Start telnet daemon: "/bin/busybox telnetd &"
 * Switch admin user to bash shell: "sed -i 's/rbash/bash/g' /etc/passwd"
 * Add normal directories to PATH: "echo PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin >> /home/.bash_profile"
 * Add sudo access to admin user: "echo admin ALL=(ALL:ALL) ALL >> /etc/sudoers"

You should now be able to login as the admin user via telnet and use sudo for root access as needed. The telnet daemon will need to be restarted every time the system is rebooted (or added to an init script to make persistent).

Eventually I'll add a procedure for persistent ssh access rather than telnet... someday.

Custom Firmware/Operating System installation
These devices run a modified version of Ubuntu LTS 14.04, it is relatively easy to customize once you gain root access.

These devices are based on a Annapurna Alpine SoC which appears to have some amount of mainline linux support though it's unclear (to me) whether that support is sufficient to boot from a mainline kernel. Although the device stores its operating system on the hard disks it boots from a kernel/initrd stored in the on-board flash. It should be possible to make it boot from the drives instead by adjusting the boot order in uboot but I have not yet attempted this.

U-boot env
arch=arm autoload=n baudrate=115200 board=alpine_db board_name=alpine_db boot_instance_active=0 boot_instance_non_active=1 bootargsbnas=setenv buffaloargs BOOTVER=0.26 ubootenv=0x$env_offset,0x4000,0x05,0x00@mtd6 ubootenv_redund=0x$env_offset_redund,0x4000,0x05,0x00@mtd6 boot=buffalofirm bootargshd=run rootargshd; setenv bootargs $rootargs pci=pcie_bus_perf console=ttyS0,115200 $bootargsextra $buffaloargs; printenv bootargs bootargshd_buffalo=run rootargshd; setenv bootargs $rootargs pci=pcie_bus_perf console=ttyS0,115200 $bootargsextra $buffaloargs tftpbootcmd=yes noperftest; printenv bootargs bootargsnand=run rootargsnand; setenv bootargs $rootargs pci=pcie_bus_perf console=ttyS0,115200 $bootargsextra $buffaloargs; printenv bootargs bootargsnfs=run rootargsnfs; setenv bootargs $rootargs pci=pcie_bus_perf console=ttyS0,115200 $bootargsextra $buffaloargs; printenv bootargs bootargssfs=run rootargssfs;setenv bootargs $rootargs pci=pcie_bus_perf console=ttyS0,115200 $bootargsextra;printenv bootargs bootcmd=for i in $bootorder; do run $i; done; run netboot_buffalo bootdelay=5 bootext4=lcd_print "Loading OS...";ext4load scsi ${ext4dev}:${ext4part} $loadaddr ${ext4dir}${dt_filename};if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then ;else flash_contents_obj_read_mem $loadaddr_dt $loadaddr;if test $? -ne 0; then run fail; exit; fi;fi;ext4load scsi ${ext4dev}:${ext4part} $loadaddr ${ext4dir}${kernel_filename};if test $? -ne 0; then run fail; exit; fi;fdt addr $loadaddr_dt;bootm $loadaddr $initrdaddr $fdtaddr;run fail;exit bootnand=lcd_print "Loading OS...";nand set_partition_offset $nand_pt_addr_kernel;nand read $loadaddr $nand_pt_addr_kernel 4;setenvmem filesize $loadaddr;incenv filesize 4;nand read $loadaddr $nand_pt_addr_kernel $filesize;nand set_partition_offset $nand_pt_addr_al_boot;fdt addr $loadaddr_dt;bootm $loadaddr_payload $initrdaddr $fdtaddr;run fail;exit bootnandmulti=run kernel_select;if test $kernel_selected -ne 0; then run bootnand; fi bootorder=fastboot hddboot boottftp=lcd_print "Loading OS...";tftpboot $loadaddr ${tftpdir}${dt_filename};if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then cp ${loadaddr} ${loadaddr_dt} ${filesize};else flash_contents_obj_read_mem $loadaddr_dt $loadaddr;if test $? -ne 0; then run fail; exit; fi;fi;tftpboot $loadaddr ${tftpdir}${kernel_filename};if test $? -ne 0; then run fail; exit; fi;fdt addr $loadaddr_dt;bootm $loadaddr $initrdaddr $fdtaddr;run fail;exit bootupd=is_nand_boot; if test $? -eq 0; then run bootupdspi; else; run bootupdnand; fi bootupdnand=lcd_print "Updating al-boot" "to NAND"; tftpboot $loadaddr ${tftpdir}boot.img; if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_al_boot;nand erase.spread $nand_pt_addr_al_boot $filesize; nand write $loadaddr $nand_pt_addr_al_boot $filesize; lcd_print "Done" bootupdnandy=lcd_print "Updating al-boot" "to NAND"; echo >> Use YModem to upload the boot image binary...;loady $loadaddr;if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_al_boot;nand erase.spread $nand_pt_addr_al_boot $filesize; nand write $loadaddr $nand_pt_addr_al_boot $filesize; lcd_print "Done" bootupdspi=lcd_print "Updating al-boot" "to SPI"; tftpboot ${loadaddr} ${tftpdir}boot.img; if test $? -ne 0; then run fail; exit; fi;sf probe; sf erase 0 +${filesize}; sf write ${loadaddr} 0 ${filesize}; echo bootupd done;echo Notice: Changes in default environment variables will only take effect once the;echo environment variables are deleted from flash using the 'delenv' script;lcd_print "Done" bootupdspiy=lcd_print "Updating al-boot" "to SPI"; echo >> Use YModem to upload the boot image binary...;loady ${loadaddr};if test $? -ne 0; then run fail; exit; fi;sf probe; sf erase 0 +${filesize}; sf write ${loadaddr} 0 ${filesize}; echo bootupd done;echo Notice: Changes in default environment variables will only take effect once the;echo environment variables are deleted from flash using the 'delenv' script;lcd_print "Done" bootupdy=is_nand_boot; if test $? -eq 0; then run bootupdspiy;else; run bootupdnandy; fi buffalo_version=0.26 cpu=armv7 cvos_tags=0x01000000 cvos_tags_seed_a=0x01000004 cvos_tags_seed_b=0x01000008 cvos_tags_validate=mw.l ${cvos_tags} 0xcf05cf05 delay_time_ms=5500 delenv=is_nand_boot; if test $? -eq 0; then run delenvspi; else; run delenvnand; fi delenvnand=lcd_print "Deleting env..."; nand erase ${env_offset} 2000; if test -n ${env_offset_redund}; then nand erase ${env_offset_redund} 2000; fi;lcd_print "Done" delenvspi=lcd_print "Deleting env..."; sf probe; sf erase ${env_offset} +2000;if test -n ${env_offset_redund}; then sf erase ${env_offset_redund} +2000;fi;lcd_print "Done" dt_filename=alpine-ts5010.dtb dt_is_from_toc=0 dt_location=80000 dt_nand_location=0x00200000 dt_nand_size=0x00010000 dtupd=is_nand_boot; if test $? -eq 0; then run dtupdspi; else; run dtupdnand; fi dtupdatenand=lcd_print "Updating DT" "to NAND";tftpboot $loadaddr_dt ${tftpdir}dt.img;if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_al_boot;nand erase.spread ${dt_nand_location} ${dt_nand_size};nand write ${loadaddr_dt} ${dt_nand_location} ${dt_nand_size};lcd_print "Done" dtupdnand=lcd_print "Updating DT" "to NAND"; tftpboot $loadaddr_dt ${tftpdir}dt.img;if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then; else flash_contents_obj_read_mem $loadaddr $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;fi;nand set_partition_offset $nand_pt_addr_al_boot;nand erase.spread ${dt_location} 10000; nand write ${loadaddr_dt} ${dt_location} 10000; lcd_print "Done" dtupdnandy=lcd_print "Updating DT" "to NAND"; echo >> Use YModem to upload the device tree binary...;loady $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then; else flash_contents_obj_read_mem $loadaddr $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;fi;nand set_partition_offset $nand_pt_addr_al_boot;nand erase.spread ${dt_location} 10000; nand write ${loadaddr_dt} ${dt_location} 10000; lcd_print "Done" dtupdspi=lcd_print "Updating DT" "to SPI"; tftpboot $loadaddr_dt ${tftpdir}dt.img;if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then; else flash_contents_obj_read_mem $loadaddr $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;fi;sf probe; sf erase ${dt_location} +${filesize}; sf write ${loadaddr_dt} ${dt_location} ${filesize};echo dtupd done;lcd_print "Done" dtupdspiy=lcd_print "Updating DT" "to SPI"; echo >> Use YModem to upload the device tree binary...;loady $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;if test ${dt_is_from_toc} != 1; then; else flash_contents_obj_read_mem $loadaddr $loadaddr_dt;if test $? -ne 0; then run fail; exit; fi;fi;sf probe; sf erase ${dt_location} +${filesize}; sf write ${loadaddr_dt} ${dt_location} ${filesize}; echo dtupd done;lcd_print "Done" dtupdy=is_nand_boot; if test $? -eq 0; then run dtupdspiy; else; run dtupdnandy; fi eepromupd=confirm_msg "Perform EEPROM update? [y/n] ";if test $? -ne 0; then exit; fi;tftpboot ${tftpdir}eeprom.bin;if test $? -ne 0; then exit; fi;i2c probe ${pld_i2c_addr};if test $? -ne 0; then exit; fi;i2c write $fileaddr ${pld_i2c_addr} 0.2 $filesize;if test $? -ne 0; then exit;fi;echo eepromupd done eepromupdy=confirm_msg "Perform EEPROM update? [y/n] ";if test $? -ne 0; then exit; fi;echo >> Use YModem to upload the EEPROM binary...;loady $loadaddr;if test $? -ne 0; then exit; fi;i2c probe ${pld_i2c_addr};if test $? -ne 0; then exit; fi;i2c write $loadaddr ${pld_i2c_addr} 0.2 $filesize;if test $? -ne 0; then exit;fi;echo eepromupdy done env_offset=1e0000 env_offset_redund=1f0000 eth1addr=88:57:ee:b8:f7:15 eth3addr=88:57:ee:b8:f7:14 ethact=al_eth3 ethprime=al_eth3 ext4dev=0 ext4part=1 fail=echo Failed!; lcd_print "Failed!" fastboot=run initrdnand;run bootargsbnas;run bootargshd;run bootnand fdtaddr=3b76008 fwupd=tftpboot ${tftpdir}uboot_script_fw_update.bin;source ${loadaddr} hddboot=run initrdext4;run bootargsbnas;run bootargshd;run bootext4 hdroot=/dev/sda1 initrdaddr=- initrdext4=lcd_print "Loading initrd" "from HDD";scsi init;for i in 0 1 2 3; do ext4load scsi $i:${ext4part} $loadaddr_rd ${ext4dir}${rd_filename};if test $? -eq 0; then setenv ext4dev $i;setenv rd_filesize $filesize;setenv initrdaddr $loadaddr_rd;exit;fi;done initrdnand=lcd_print "Loading initrd" "from NAND";nand set_partition_offset $nand_pt_addr_al_boot;nand read $loadaddr $rd_location 4;setenvmem filesize $loadaddr;incenv filesize 4;nand read $loadaddr_rd $rd_location $filesize;setenv initrdaddr $loadaddr_rd;incenv initrdaddr 4;nand set_partition_offset $nand_pt_addr_al_boot;lcd_print "Done" initrdtftp=lcd_print "Loading initrd" "from TFTP";while true; do tftpboot $loadaddr_rd ${tftpdir}${rd_filename};if test $? -ne 0; then run fail;if test ${ethact} != "al_eth1"; then setenv ethact al_eth1;echo ethact:al_eth1;else setenv ethact al_eth3;echo ethact:al_eth3;fi;else setenv rd_filesize $filesize;setenv initrdaddr $loadaddr_rd;lcd_print "Done";exit;fi;done initrdupd=lcd_print "Updating initrd" "to NAND";tftpboot $loadaddr_payload ${tftpdir}${rd_filename};if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_kernel;mw.l $loadaddr $filesize;incenv filesize 4;nand erase.spread $rd_location $filesize;nand write $loadaddr $rd_location $filesize;nand set_partition_offset $nand_pt_addr_al_boot;echo initrdupdnand done;lcd_print "Done" iocc_force=1 iocc_force_val=1 ipaddr=192.168.11.150 kernel_filename=uImage-generic.buffalo kernel_rename_1=editenv nand_pt_desc_kernel_1;saveenv kernel_rename_2=editenv nand_pt_desc_kernel_2;saveenv kernel_select=setenv kernel_selected 0;setenv bootmenu_0 ${nand_pt_desc_kernel_1}=run kernel_select_1;setenv bootmenu_1 ${nand_pt_desc_kernel_2}=run kernel_select_2;bootmenu kernel_select_1=setenv nand_pt_addr_kernel ${nand_pt_addr_kernel_1};setenv kernel_selected 1 kernel_select_2=setenv nand_pt_desc_kernel ${nand_pt_desc_kernel_2};setenv nand_pt_addr_kernel ${nand_pt_addr_kernel_2};setenv nand_pt_desc_kernel_2 ${nand_pt_desc_kernel_1};setenv nand_pt_addr_kernel_2 ${nand_pt_addr_kernel_1};setenv nand_pt_desc_kernel_1 ${nand_pt_desc_kernel};setenv nand_pt_addr_kernel_1 ${nand_pt_addr_kernel};saveenv;setenv kernel_selected 2 kernelupd=lcd_print "Updating kernel...";tftpboot $loadaddr_payload ${tftpdir}${kernel_filename};if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_kernel;mw.l $loadaddr $filesize;incenv filesize 4;nand erase.spread $nand_pt_addr_kernel $filesize;nand write $loadaddr $nand_pt_addr_kernel $filesize;nand set_partition_offset $nand_pt_addr_al_boot;echo kernelupd done;lcd_print "Done" loadaddr=0x08000000 loadaddr_dt=0x07000000 loadaddr_payload=0x08000004 loadaddr_rd=0x04000000 loadaddr_rootfs_chk=0x07000000 nand_pt_addr_al_boot=0x0 nand_pt_addr_fs=0x02a00000 nand_pt_addr_kernel=0x00400000 nand_pt_addr_kernel_1=0x00400000 nand_pt_addr_kernel_2=0x00a00000 nand_pt_addr_sfs=0x0c400000 nand_pt_desc_kernel_1=Test kernel A nand_pt_desc_kernel_2=Test kernel B nand_pt_size_al_boot=0x00400000 nand_pt_size_fs=0x09a00000 nand_pt_size_kernel=0x00c00000 nand_pt_size_sfs=0x33c00000 nandboot=run initrdnand;run bootargsbnas;run bootargssfs;run bootnand netboot=run initrdtftp;run bootargsbnas;run bootargsnfs;run boottftp netboot_buffalo=run initrdtftp;run bootargsbnas;run bootargshd_buffalo;run boottftp nfsrootdir=/srv/root/ pld_i2c_addr=50 rd_filename=uInitrd-generic.buffalo rd_location=0x00c00000 rootargshd=setenv rootargs root=${hdroot} rw rootargshd_buffalo=setenv rootargs root=${hdroot} rw tftpbootcmd=yes rootargsnand=setenv rootargs root=ubi0:root rootfstype=ubifs ubi.mtd=3 rootargsnfs=setenv rootargs root=/dev/nfs rw nfsroot=${serverip}:${nfsrootdir},tcp,nolock rw ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${board_name}:eth1:none rootargssfs=setenv rootargs root=${squashrootdev} ro rootfstype=squashfs rootdelay=1 ${unionrootdev} rootfs_filename=hddrootfs.buffalo.updated rootfsupd=lcd_print "Updating rootfs...";tftpboot $loadaddr_rootfs_chk ${tftpdir}rootfs.ubi.md5;if test $? -ne 0; then run fail; exit; fi;tftpboot $loadaddr ${tftpdir}rootfs.ubi;if test $? -ne 0; then run fail; exit; fi;md5sum -v $loadaddr $filesize *$loadaddr_rootfs_chk;if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_fs;nand erase.spread $nand_pt_addr_fs $nand_pt_size_fs;nand write $loadaddr $nand_pt_addr_fs $filesize;nand set_partition_offset $nand_pt_addr_al_boot;echo rootfsupd done;lcd_print "Done" series=ts3x10 serverip=192.168.11.1 skip_eth_halt=0 soc=alpine squashrootdev=/dev/mtdblock5 squashupd=lcd_print "Updating rootfs...";tftpboot $loadaddr_rootfs_chk ${tftpdir}${rootfs_filename}.md5;if test $? -ne 0; then run fail; exit; fi;tftpboot $loadaddr ${tftpdir}${rootfs_filename};if test $? -ne 0; then run fail; exit; fi;md5sum -v $loadaddr $filesize *$loadaddr_rootfs_chk;if test $? -ne 0; then run fail; exit; fi;nand set_partition_offset $nand_pt_addr_fs;nand erase.spread $nand_pt_addr_sfs $nand_pt_size_sfs;nand write $loadaddr $nand_pt_addr_sfs $filesize;nand set_partition_offset $nand_pt_addr_al_boot;echo squashsupd done;lcd_print "Done" test=echo this is a test! unionrootdev=unionfs=ubi0:ubifs ubi.mtd=4 vendor=annapurna-labs DEVICEID=SYrR8G8uSM9Y7t1_h0xZEU9BSC3HIj89