Table of Contents
Hacking the LaCie d2 Network
After power-up the LaCie will get an IP address from a DHCP server, if available.
A simple nmap run will show:
nmap 192.168.2.131 Starting Nmap 4.62 ( http://nmap.org ) at 2009-12-25 10:46 CET Interesting ports on 192.168.2.131: Not shown: 1709 closed ports PORT STATE SERVICE 21/tcp open ftp 80/tcp open http 139/tcp open netbios-ssn 443/tcp open https 445/tcp open microsoft-ds 548/tcp open afp MAC Address: 00:D0:4B:88:62:FE (LA CIE Group S.A.) Nmap done: 1 IP address (1 host up) scanned in 0.319 seconds
We can point the browser to the ip address and make a login with the default admin username/password: admin/admin. The web interface is available via https too. The web interface is available in english, français, deutsch, italiano, español, dutch, svenska, dansk and japanese.
Main features of this device are:
- CPU ARM926EJ-S at 400 MHz
- 128 Mb RAM (123.5 available)
- 512 kb of Flash Memory
- Aluminium case works as heatsink, no cooling fan
- Gigabit Ethernet with jumbo frame support
- Wake-On-Lan
- Linux kernel version 2.6.22.7
- System version 2.2.2
- DHCP client
- File server: SMB, AFP, FTP, HTTP, Apple Bonjour
- Compatible with Active Directory Windows domains
- BitTorrent client
- USB 2.0 and eSata connector for external storage
- Hard disk Hitachi Deskstar 1.00 Tb, 7200 rpm, SATA 3Gb/s, HDT721010SLA360 (930.43 Gb available)
- Power consumption: 16 W (6 W in stand-by)
With default configuration I tested the transfer rate and disk speed writing 30 mp3 songs - about 100 Mb of data - from the local hard disk to the smb share. It took about 15 seconds, this is about 6.64 Mb/s on a 100 Mbit network.
From the web interface you can control a BitTorrent client: just upload a .torrent file from the local hard disk and choose the destination folder. Several download can run simultaneously.
The LaCie supports Ethernet jumbo frame sizes of 1500, 4000 and 9000 bytes, not a very interesting feature in my opinion.
The front panel
On the front panel there is one large button with led. Pressing the button will power up the device, if it is powered down and it is in the auto mode (see below). During normal operation the button press will start the copy of USB external storage contents to the internal disk. The light is steading blue when the device is ready, blinking blue when busy booting or shutting down. It becomes red when performing USB content backup.
The back panel
On the back panel there is a three position power switch. In the on position the device is powered-up and cannot be switched off via software. In the auto position the device can be controlled by the front button and via software. In the off position the device is off, as you can guess.
LaCie software
I tried to install LaCie Network Assistant 1.1, which is distributed as a MS-Windows installer or as a GNU/Linux autopackage archive. The autopackage version requires the avahi-daemon and it will install into $HOME/.local/
and $HOME/.packages/
. I was unable to run the Windows version of the program both under Wine and under Qemu.
LaCie Network Assistant allows to wake-up a device, discover LaCie devices on the local network, configure IP address and automatically mount shares via smb protocol. It is not a very impressive software, sometimes it crashes too. You can live without it.
Hacking it
I found two recipes to break into the LaCie operating system: Jailbreaking LaCie (in English) and LaCie telnet hack (in Italian, with telnetd package to download). Both hacks do not require skrewdrivers.
This is my revised procedure:
- Create a new share called root and make it writable.
- Save the configuration: System, Maintenance, Save configuration. A file named
edconf.xml
will be saved on your hard disk. - Make a copy of the configuration file, open it with an editor, search the share section and change the
<path>root</path>
with:
<path>root/../../../</path>
i.e. the same directory followed by 3 levels up. - Load the configuration back to the device: System, Maintenance, Load configuration.
- Browse the
root
share to get access to the root filesystem.
Notice 1: when this hack is active, do not change the configuration of shares: you risk to erase their contents. Once you hacked the root filesystem as you wish (see below), reload the original configuration.
Notice 2: this hack is temporary. If you reboot, the root
share will be broken and you will find a recovered_root_YYYYMMDD_hhmmss
share. Do not change them from the web interface, just upload the original configuration file. This is due a bug in the LaCie code, which does not properly sanitize the modified configuration file and save a corrupted version of it.
The web interface runs with root privileges, so it is possible to modify system files by browsing the share contents and using the upload function.
- Unpack this archive, upload
utelnetd
andtelnet.cgi
into/www/cgi-bin/public/
directory of the LaCie. - Point the browser to
http://192.168.2.133/cgi-bin/public/telnet.cgi
: the telnet daemon will start. - Telnet into the LaCie, you will get a root shell.
- Reload the original configuration from System, Maintenance, Load configuration.
Starting the ssh service
LaCie operating system does not use the traditional sysvinit to start the services on boot, it uses the initng replacement. The main tool for initng is ngc
, used to start/stop the services, query the status of a service, etc.
Here it is the help screen of ngc:
[root@LaCie-d2 ~]# ngc -h initNGControl (0.6.10.2 ) by Jimmy Wennlund http://www.initng.org/ ngc understand this commands: short Option : description ---------------------------------------------------------- [-h] --help : Print what commands you can send to initng. [-H] --help_all : Print out verbose list of all commands. [-s] --status <opt> : Print all services. [-u] --start opt : Start service. [-d] --stop opt : Stop service. [-t] --states <opt> : Print out all possible states. [-c] --hot_reload : Fast Reload [-z] --zap <opt> : Resets a failed service, so it can be restarted. [-r] --restart opt : Restart service [-R] --reload_service <opt> : Reload service data from disk ( reparse /etc/initng ) [-6] --reboot : Reboot the computer [-0] --poweroff : Power off the computer [-1] --halt : Halt the computer [-y] --stop_unneeded : Stop all services, not in runlevel
If you have some problem running initng
commans, try to send a SIGHUP
signal to initng
:
ngc --start sshd Error connecting to initng socket kill -HUP 1
The ssh daemon is already installed in the LaCie d2 Network, but it does not start automatically. To start sshd
- the very first time be prepared to wait some minutes for host keys generation - run:
ngc --start sshd
Once started, you can add sshd
to the list of services to start automatically, and initialize the lastlog
:
echo sshd >> /etc/initng/runlevel/default.runlevel touch /var/log/lastlog
Files /etc/passwd
and /etc/shadow
will be “sanitized” on each reboot, so it is useless to change the root password or change the users login shell (default to /bin/false
). To allow ssh root access, just create a /root/.ssh/authorized_keys
file and put in it your ssh public key (see ssh-keygen(1)
man page).
Looking around at the shell prompt
root@LaCie-d2:~# uname -a Linux LaCie-d2 2.6.22.7 #1 Mon Mar 23 17:03:07 CET 2009 armv5tejl unknown
Here the kernel config, obtained with zcat /proc/config.gz
root@LaCie-d2:~# free total used free shared buffers Mem: 126928 71204 55724 0 6564 Swap: 128448 0 128448 Total: 255376 71204 184172
root@LaCie-d2:~# cat /proc/cpuinfo Processor : ARM926EJ-S rev 0 (v5l) BogoMIPS : 266.24 Features : swp half thumb fastmult edsp CPU implementer : 0x41 CPU architecture: 5TEJ CPU variant : 0x0 CPU part : 0x926 CPU revision : 0 Cache type : write-back Cache clean : cp15 c7 ops Cache lockdown : format C Cache format : Harvard I size : 32768 I assoc : 1 I line length : 32 I sets : 1024 D size : 32768 D assoc : 1 D line length : 32 D sets : 1024 Hardware : Feroceon Revision : 0000 Serial : 0000000000000000
root@LaCie-d2:~# df -h Filesystem Size Used Available Use% Mounted on rootfs 648.5M 20.0M 595.5M 3% / udev 648.5M 20.0M 595.5M 3% /dev df: /dev/pts: No such file or directory /dev/sda7 7.5M 5.9M 1.2M 83% /oldroot udev 10.0M 0 10.0M 0% /oldroot/dev udev 10.0M 0 10.0M 0% /oldroot/dev none 62.0M 0 62.0M 0% /oldroot/dev/shm /dev/sda8 167.0M 111.3M 47.1M 70% /oldroot/var/original /dev/sda9 648.5M 20.0M 595.5M 3% /oldroot/snapshots unionfs 648.5M 20.0M 595.5M 3% / /dev/sda9 648.5M 20.0M 595.5M 3% /var /dev/sda9 648.5M 20.0M 595.5M 3% /tmp /dev/sda2 930.4G 907.9M 929.5G 0% /home
root@LaCie-d2:~# fdisk -l Disk /dev/sda: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 1 125 1004031 5 Extended /dev/sda2 126 121601 975755970 83 Linux /dev/sda5 1 16 128457 82 Linux swap /dev/sda6 17 17 8001 83 Linux /dev/sda7 18 18 8001 83 Linux /dev/sda8 19 40 176683+ 83 Linux /dev/sda9 41 124 674698+ 83 Linux /dev/sda10 125 125 8001 83 Linux
[root@LaCie-d2 ~]# mount rootfs on / type rootfs (rw) none on /proc type proc (rw) none on /sys type sysfs (rw) udev on /dev type tmpfs (rw) devpts on /dev/pts type devpts (rw) /dev/sda7 on /oldroot type ext3 (ro,data=ordered) udev on /oldroot/dev type tmpfs (rw) none on /oldroot/proc type proc (rw) none on /oldroot/sys type sysfs (rw) udev on /oldroot/dev type tmpfs (rw) devpts on /oldroot/dev/pts type devpts (rw) none on /oldroot/dev/shm type tmpfs (rw) /dev/sda8 on /oldroot/var/original type ext3 (ro,data=ordered) /dev/sda9 on /oldroot/snapshots type ext3 (rw,data=ordered) unionfs on / type unionfs (rw,dirs=/oldroot/snapshots/snaps/00=rw:/oldroot/var/original=ro) proc on /proc type proc (rw) sys on /sys type sysfs (rw) /dev/sda9 on /var type ext3 (rw,data=ordered) /dev/sda9 on /tmp type ext3 (rw,data=ordered) usbfs on /proc/bus/usb type usbfs (rw) /dev/sda2 on /home type xfs (rw)
[root@LaCie-d2 ~]# cat /proc/mtd dev: size erasesize name mtd0: 00080000 00010000 "cfi_flash_0"
dmesg Linux version 2.6.22.7 (root@grp-dash) (gcc version 4.2.1) #1 Mon Mar 23 17:03:07 CET 2009 CPU: ARM926EJ-S [41069260] revision 0 (ARMv5TEJ), cr=a0053177 Machine: Feroceon Using UBoot passing parameters structure ... Kernel command line: console=ttyS0,115200 root=/dev/sda7 ro boardType=mv88F5182 productType=d2Next ... Memory: 128MB 0MB 0MB 0MB = 128MB total Memory: 126464KB available (2792K code, 185K data, 356K init) Calibrating delay loop... 266.24 BogoMIPS (lpj=1331200) ... Sys Clk = 200000000, Tclk = 166666667 ... Init Marvell USB port 0 => HOST Marvell USB EHCI Host controller #0: c0493600 Init Marvell USB port 1 => HOST Marvell USB EHCI Host controller #1: c0493400 ... Time: orion_clocksource clocksource has been installed. ... Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled serial8250.0: ttyS0 at MMIO 0xf1012000 (irq = 3) is a 16550A serial8250.0: ttyS1 at MMIO 0xf1012100 (irq = 4) is a 16550A Marvell Ethernet Driver 'mv_ethernet': ... Intergrated Sata device found scsi0 : Marvell SCSI to SATA adapter scsi1 : Marvell SCSI to SATA adapter scsi 1:0:0:0: Direct-Access Hitachi HDT721010SLA360 ST6O PQ: 0 ANSI: 5 sd 1:0:0:0: [sda] 1953525168 512-byte hardware sectors (1000205 MB) ... egiga0: link down egiga0: link up, full duplex, speed 100 Mbps
Here the full dmesg output.
The pseudo file /proc/edmini
is provided by a LaCie kernel driver (released under the GPL license). It reports some useful info and can be used to write some configuration to the device, see below.
[root@LaCie-d2 ~]# cat /proc/edmini d2Net status: ------------ Restore: NO Sw Power button: Status: Auto Count: 0/0 ACTION: name count blink callback Shutdown 0 0/0 Internal call Button action 1 0/0 /sbin/snapshot
The S.M.A.R.T. function works, just add the --device=marvell
option (otherwise you get the error Device does not support SMART):
[root@LaCie-d2 ~]# smartctl --device=marvell -a /dev/sda
The filesystems
Device | Start | End | Blocks | Id | System | Note |
---|---|---|---|---|---|---|
/dev/sda1 | 1 | 125 | 1004031 | 5 | Extended | Contains sda5 … sda10. |
/dev/sda2 | 126 | 121601 | 975755970 | 83 | Linux | Mounted as /home , formatted as xfs filesystem. |
/dev/sda5 | 1 | 16 | 128457 | 82 | Linux-swap | Used as swap partition. |
/dev/sda6 | 17 | 17 | 8001 | 83 | Linux | U-Boot image with kernel, etc. |
/dev/sda7 | 18 | 18 | 8001 | 83 | Linux | Initial root filesystem used by the kernel. Contains the scripts to assemble a running root filesystem via unionfs. Available at runtime under /oldroot . |
/dev/sda8 | 19 | 40 | 176683 | 83 | Linux | Runtime root filesystem, read-only part in unionfs. Also available at runtime under /oldroot/var/original . |
/dev/sda9 | 41 | 124 | 674698 | 83 | Linux | Runtime root filesystem, read/write part in unionfs. Also available at runtime under /oldroot/snapshots . The system can save several snapshots, unionfs uses the last one available, which is /oldroot/snapshots/snaps/00/ in a clean device. |
/dev/sda10 | 125 | 125 | 8001 | 83 | Linux | Empty partition. If it contains an U-Boot image, it will used instead of /dev/sda6 . Probably used to boot from disk2 if disk1 fails, on Lacie RAID models. |
As you can see, the root filesystem at runtime is an unionfs.
The original configuration is stored read-only in /dev/sda8
which is mounted in /oldroot/var/original
. Here you can always find the original version of each configuration and system file. Changes to the root filesystem are stored in /dev/sda9
, into a snapshot, the read/write part in unionfs. So the current version of each system file is available into /oldroot/snapshots/snaps/00/
(assuming that 00
is the latest snapshot available).
If you want to learn how the bootstrap works on the LaCie, look at the script /oldroot/sbin/init
and the functions countained into /oldroot/lib/lacie/libunionfs
. The unionfs is assembled in this way:
mount -n -t unionfs -o dirs=/var/original=rw unionfs /var/base mount -t unionfs -o remount,add=/snapshots/snaps/00 none /var/base
Some shell variables used by the script:
$root_partition | /dev/sda8 |
$root_mountpoint | /var/original |
$snap_partition | /dev/sda9 |
$snap_mountpoint | /snapshots |
$union_base | /var/base |
$oldroot | oldroot |
Wake-On-Lan
The Wake-On-Lan function works when the device is turned off but the power switch is on the auto position: sending a Magic packet will power-up the LaCie. The etherwake(8)
program does not work, while wakeonlan(1)
does. May be the difference is that etherwake
uses raw Ethernet packet, while wakeonlan
encapsulate the Magic packet into an UDP packet.
Connect the Ethernet cable before the power cable, otherwise the Wake-On-Lan will not work.
Dual boot with Debian
We can install a full-featured Debian distribution on this LaCie NAS, the processor requires a Debian armel architecture, do not use the old one arm. The armel is very much faster in floating point operations, with or without an FPU.
Our goal is to install a full Debian system and use it in dual boot with the original system.
Make a new partition
First of all we need a new partition /dev/sda3
to host Debian. Unfortunately the data partition /dev/sda2
(mounted in /home
) is XFS formatted and cannot be shrunk, so we need to backup the data, delete it and create it smaller. In my case making it 122 cylinders smaller, leaves room for a new partition of about 1 Gb.
From the ssh prompt:
# Backup user data, you can use tar over ssh: tar cf - /home | ssh user@other_host 'cat > lacie_home.tar' umount /home fdisk /dev/sda # (d)elete partition sda(2) # create a (n)ew (p)rimary partition sda(2) # create a (n)ew (p)rimary partition sda(3) # (w)rite the parition table and (q)uit fdisk # Notice the warning: # fdisk: WARNING: rereading partition table failed, kernel still uses old table reboot # Once rebooted: mkfs.xfs -f /dev/sda2 mkfs.ext3 /dev/sda3 reboot
First stage of debootstrap on a Linux box
We use debootstrap(8)
on a standard Linux box. We need to specify the target architecture armel, which is different from the hosting one (i386 or whatever). We ask to perform the unpack phase of bootstrapping only, the rest will be executed on the LaCie. debootstrap
requires root privileges:
mkdir debian-armel debootstrap --arch=armel --foreign lenny debian-armel tar debian-armel.tgz debian-armel
Second stage of debootstrap on the LaCie
Copy the tar archive to the LaCie and extract the /debian-armel
directory. We can switch to this Debian environment using chroot(8)
and execute the rest of debootstrap
:
cd / mkdir /debian-armel mount /dev/sda3 /debian-armel tar zxf /home/share/share/debian-armel.tgz mount /proc /debian-armel/proc mount /sys /debian-armel/sys mount /oldroot/dev/ /debian-armel/dev chroot /debian-armel /debootstrap/debootstrap --second-stage
Complete the Debian installation
Still in the chroot
environment, we can proceed with the rest of Debian setup.
- Set the Debian repository in
/etc/apt/sources.list
and executeapt-get update
. - Install some more packages, like
udev
,openssh-server
,locales
,resolvconf
,xfsprogs
. - Setup some configuration files as they will be required when booting Debian, mostly:
/etc/network/interfaces
,/etc/fstab
,/etc/hosts
,/etc/inittab
,/etc/default/rcS
. - Reconfigure
locales
andtzdata
packages usingdpkg-reconfigure
. - Set a password for user root and add users as required.
To exit from the chroot environment, stop all the services you have started and execute exit
. Then umount /proc
, /sys
and /dev
underneath the chroot before umounting /debian-armel
itself.
Controlling the dual boot
We will use the original kernel and the original root filesystem to bootstrap. The original bootstrap sequence is like this:
- Load the kernel from
/dev/sda6
. - Mount the root filesystem from
/dev/sda7
. - Assemble a new root filesystem from
/dev/sda8
and/dev/sda9
, using unionfs. - Switch to the new rootfs using
pivot_root(8)
. - Execute
init
from the unionfs.
We will change the init sequence in /dev/sda7
, so that if a specified file exists (used as a flag), pivot_root
will proceed with /dev/sda3
instead of unionfs. Do not forget to copy kernel modules into the new partition.
Via ssh execute the following into the LaCie environment (not into the Debian chroot):
cp -pr /lib/modules/2.6.22.7 /debian-armel/lib/modules/ mount -o remount,rw /dev/sda7 vi /oldroot/sbin/init # Add a 4.1 section, as below... mount -o remount,ro /dev/sda7 echo "/dev/sda3" > /rootfs
On /dev/sda7
partition, init
is just a shell script. This is the part that we added (put it after section 4, at line 160 in our case):
#=========================================================================== # 4.1. Boot with an alternative RootFS. #=========================================================================== if [ -f $union_base/rootfs ]; then rootfs=`cat $union_base/rootfs` rootfs_base=/var/rootfs debug_msg "Found file $union_base/rootfs, using (once) $rootfs as RootFS" rm $union_base/rootfs sync if [ -b $rootfs ]; then debug_msg "Preparing RootFS: $rootfs_base and $rootfs_base/dev" [ -d $rootfs_base ] || mkdir $rootfs_base mount -n $rootfs $rootfs_base mount -n -o size=10M,mode=0755 -t tmpfs udev $rootfs_base/dev mknod $rootfs_base/dev/console c 5 1 mknod $rootfs_base/dev/ttyS0 c 4 64 mknod $rootfs_base/dev/sda b 8 0 for n in 1 2 3 4 5 6 7 8 9 10 ; do mknod $rootfs_base/dev/sda$n b 8 $n done cd $rootfs_base mkdir -p $oldroot mount -n -o remount,ro $rootfs $rootfs_base debug_msg "Executing pivot_root and exec init from the new RootFS" pivot_root . $oldroot umount /oldroot/proc umount /oldroot/sys umount /oldroot/dev/shm umount /oldroot/dev/pts exec /sbin/init < /dev/console > /dev/console 2>&1 fi fi
At the next reboot, the system will boot into our new Debian system. For an added safety this will be done only once: the flag file is removed just before switching rootfs. If something goes wrong we can power-cycle and restart with the original LaCie system.
If Debian bootstrap nicely, we can create the flag file again adding this in /etc/rc.local
:
echo "/dev/sda3" > /oldroot/var/base/rootfs
Debian settings
You can find my Debian customization in this archive: debian_on_lacie_d2_network.tgz. Most important files contained herein:
/etc/init.d/lacie
: set automatically the reboot EEPROM flag before shutdown, set the LED status, create the flag file to reboot in Debian the next time./etc/inittab
: spawn a getty login on the serial line./etc/fstab
mounted partitions./etc/init.d/checkroot.sh
: in case of reboot needed afterfschk
, create the flag file to reboot again in Debian./etc/default/rcS
: setFSCKFIX=yes
for non-interactive filesystem check.
Bugs and TODO
Once booted in Debian, some things does not work as expected.
smartctl
need the--device=marvell
option, the problem is fixed with a 2.6.32 Debian kernel.- See below on how to build and install a Debian kernel.
- Problems with
/proc/uptime
, reporting over 16600 days of uptime. The problem is related also to error messageUnknown HZ value! (0) Assume 100.
reported byuptime
and other procps commands. The problem is fixed with a 2.6.32 Debian kernel. - When the power switch is switched to the off position, an
halt
should start automatically.
The problem is thatlacie_initiateShutdown()
function (fromlacie_button.c
kernel driver) sends aSIGUSR1
toinit
: this is used to initiate an halt by the LaCie customizedinitng
. Unfortunately this is not true forsysvinit
.
Power management
When the power switch is in the auto position, it is necessary to set in advance the required action (halt or reboot) executed by the shutdown(8)
command, traditional flags -P
and -r
are ignored. This is accomplished by writing a string to /proc/edmini
:
String | Action with power switch in the auto position |
---|---|
POWER:HALT | Do an halt after shutdown. |
POWER:REBOOT | Do a reboot after shutdown. |
Actually a flag is written into the Lacie d2 Network EEPROM. The shutdown
command always does a reboot and the U-Boot will do the proper action upon the power switch position and the EEPROM flag.
LED, button and switch
The LaCie has a big button on the front which includes a blue/red LED. On the back it has a rocker switch with three positions: on, auto and off.
With LaCie kernel
The big LED on the front panel is normally steady blue. It is possible to change its status writing some values to the /proc/edmini
pseudo file. To change the LED status run a command like this:
echo "LED:MAIN:HBT:BLUE_RED" > /proc/edmini
Here there are some values (extracted from the /sbin/event-led-manager
script):
Value | LED light |
---|---|
SYSTEM_READY | Restore default state |
LED:MAIN:CTL:OFF | Off |
LED:MAIN:CTL:ON | Steady blue |
LED:MAIN:HBT:BLUE | Blinking blue |
LED:MAIN:HBT:BLUE_RED | Blinking blue/red |
LED:MAIN:HBT:RED | Blinking red |
LED:MAIN:SWT:RED:OFF | Turn off the red light |
LED:MAIN:SWT:RED:ON | Steady red |
To associate an action to the button press (it is the snapshot function on the original system), just execute:
echo "ACTION:ADD:snapshot:/usr/bin/command:1:300/0" > /proc/edmini
The string is composed of ACTION:ADD:Name:Path:Count:Led_ON_Time/Led_OFF_time
.
To remove the association:
echo "ACTION:DEL:1" > /proc/edmini
With Linux 2.6.32 kernel
Vanilla 2.6.32 kernel supports the dual color blue/red LED, but does not activate the blue LED blinking on SATA access. It lacks also the ability to program the GPIO #24, required to ignore the power-off switch. So it is impossible to control the shutdown via software.
Default actions associated to the switches are:
Front Push Button | None |
---|---|
Power rocker switch (on|auto) | None |
Power rocker switch (auto|off) | Power-off immediately (not clean) |
The rocker switch, when switched to off, will power off the device, this is different from the behaviour with the LaCie kernel, where a soft reboot is started.
The path for controlling the LEDs are: /sys/class/leds/d2net:blue:power
and /sys/class/leds/d2net:red:fail
.
With Linux 2.6.32 patched
Thanks to Simon Guinot, there is a patch for kernel 2.6.32, which enables GPIO #24 programming and blue LED blinking on disk access. Notice that BLUE led path is canged.
# Blue led blinking. echo "timer" > "/sys/class/leds/d2net:blue:sata/trigger" echo "50" > "/sys/class/leds/d2net:blue:sata/delay_off" echo "50" > "/sys/class/leds/d2net:blue:sata/delay_on" # Blue led steady on (blinking on SATA access): echo "default-on" > "/sys/class/leds/d2net:blue:sata/trigger" # Blue led steady off: echo "none" > "/sys/class/leds/d2net:blue:sata/trigger" # Red led blinking. echo "timer" > "/sys/class/leds/d2net:red:fail/trigger" echo "50" > "/sys/class/leds/d2net:red:fail/delay_on" echo "50" > "/sys/class/leds/d2net:red:fail/delay_off"
Front push button and rear rocker switch are connected to an irq:
cat /proc/interrupts CPU0 40: 57 orion_gpio_irq Power rocker switch (on|auto) 41: 0 orion_gpio_irq Power rocker switch (auto|off) 50: 4 orion_gpio_irq Front Push Button
It is possible to control the power-off behaviour using GPIO #24, setting this pin to 1 will activate the ignore power-off status, thus enabling the software to catch the event and initiate a clean shutdown.
Here are the commands required to activate GPIO programming and setting the value to 1:
echo 24 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio24/direction echo 1 > /sys/class/gpio/gpio24/value echo 24 > /sys/class/gpio/unexport
The kernel module evdev and gpio_keys (CONFIG_INPUT_EVDEV
and CONFIG_KEYBOARD_GPIO
) provide the device /dev/input/event0
. With the input-events(8)
command (provided by the input-utils package) it is possible to monitor the button events:
lacie:~# input-events -t 120 0 /dev/input/event0 bustype : BUS_HOST vendor : 0x1 product : 0x1 version : 256 name : "gpio-keys" phys : "gpio-keys/input0" bits ev : EV_SYN EV_KEY EV_SW waiting for events # # Front button pressed: 00:11:11.723379: EV_KEY KEY_POWER pressed 00:11:11.723394: EV_SYN code=0 value=0 # # Front button released: 00:11:11.816207: EV_KEY KEY_POWER released 00:11:11.816219: EV_SYN code=0 value=0 # # Rocker switch from AUTO to ON position: 00:11:38.619606: EV_SW code=1 value=1 00:11:38.619634: EV_SYN code=0 value=0 # # Rocker switch from ON to AUTO position: 00:11:40.321607: EV_SW code=1 value=0 00:11:40.321618: EV_SYN code=0 value=0 # # Rocker switch from AUTO to OFF position: 16:08:04.410119: EV_SW code=2 value=1 16:08:04.410134: EV_SYN code=0 value=0 # # Rocker switch from OFF to AUTO position: 16:08:06.845804: EV_SW code=2 value=0 16:08:06.845816: EV_SYN code=0 value=0
How to react to input events? See Power Buttons Under HAL and this mail suggesting some code.
LaCie U-Boot looks at an EEPROM flag to decide if it will stop the bootstrap waiting for a Wake-On-Lan packet or if it will proceed. So we need to set this flag before doing an halt
or a reboot
to obtain the correct behaviour.
Furtunately the Linux kernel exposes the EEPROM content for reading and writing. To obtain an halt
, write a 0 at offset 6, to obtain a reboot write 1 at the same offset:
eeprom_write_byte /sys/bus/i2c/devices/0-0050/eeprom 6 0
Here it is the binary and the source code of eeprom_write_byte.
The EEPROM
With a proper kernel (2.6.32 with the above patch, or 2.6.37) the EEPROM content is exposed for read and write via the pseudo file /sys/bus/i2c/devices/0-0050/eeprom
. This is what I know about its content:
Offset | Length | Content |
---|---|---|
0 | 6 | Ethernet MAC address. |
6 | 1 | Power flag. If set to LACIE_POWER_OFF (0), U-Boot will stop the boot process and wait for Wake-on-LAN.If set to LACIE_POWER_ON (1), U-Boot will reboot. |
Disassembling the LaCie d2 Network
Removing the four screws from the back, you can remove the front and the back panels. Removing other two screws from the bottom, the hard disk with the attached PCB will slide out from the aluminium body.
U-Boot NetConsole
It is possible to have a boot prompt without using the serial port (see below). The boot loader U-Boot waits some time before booting, for a special Lacie UDP magic packet (see the message Waiting for LUMP on the serial console), if it receives it from an host, it will enter a special remote console, communicating on port 6666 UDP.
You need the NetConsole client called clunc. I downloaded the Clunc source code from the Git repository and compiled it just with make
. You need also the nc
command from the netcat-traditional package.
Start the clunc
program on your Linux box and power on the Lacie (WARNING: it seems that clunc
broadcasts to U-Boot only to the interface where you have the default route, beware if you have more than one Ethernet interface):
./clunc -v -i 192.168.2.35 waiting U-Boot... U-Boot NetConsole ----------------- Marvell>> help
This is also a security hole in the device: anybody with IP connectivity to the Lacie can interrupt the bootstrap process and perform low level operations on the device, taking full control of it. Actually I was not able to bootstrap the internal hard disk from the NetConsole, it seems that the SATA controller is disabled when NetConsole is activated.
Here it is the output of the help and printenv (print environment variables) command.
Experimenting on the NetConosole:
Marvell>> echo ${bootcmd} echo ${bootcmd} if lump 2; then ; else run disk_disk; fi Marvell>> echo ${disk_disk} echo ${disk_disk} ide reset; run boot_disk1; bootm ${kernel_addr}; Marvell>> echo ${boot_disk1} echo ${boot_disk1} if disk ${kernel_addr} 1:A; then; else run boot_disk2; fi Marvell>> echo ${kernel_addr} echo ${kernel_addr} 0x400000 Marvell>> echo ${boot_disk2} echo ${boot_disk2} disk ${kernel_addr} 1:6 Marvell>> echo ${bootargs} echo ${bootargs} console=ttyS0,115200 root=/dev/sda7 ro boardType=mv88F5182 productType=d2Next
As you can see the standard boot sequence is:
- Eventually wait for the LUMP packet
- If not LUMP packet, load boot image from IDE device 1:A (
/dev/sda10
) - If boot from
sda10
fails, load boot image from IDE device 1:6 (/dev/sda6
) - Run the boot image, passing
bootargs
to the kernel.
The commands diskboot
and bootm
are used to load the boot image and to run it respectively.
Strange enough: I cannot start the device with boot
, it does not find the hard disk.
Marvell>> boot boot Waiting for LUMP (2) no lump receive; continuing Reset IDE: Marvell Serial ATA Adapter Integrated Sata device found ** Device 1 not available ** Device 1 not available ## Booting image at 00400000 ... Bad Magic Number Marvell>> ide reset ide reset Reset IDE: Marvell Serial ATA Adapter Integrated Sata device found Marvell>> ide info ide info Marvell>>
JTAG Serial Connector Pin-out
Once disassembled you can see the JTAG 8 pin connector: a 8 pin header 2.0 mm pitch (you can use a female connector SQT-108-01-L-S). Pin 1 is toward the hard disk, pin 8 is toward the power switch.
Pin | Signal |
---|---|
1 | +3.3 V |
2 | GND |
3 | |
4 | |
5 | |
6 | |
7 | RX |
8 | TX |
This is a 3.3 volt serial port, to connect it to a standard one we need an adapter, like those based on the MAX232 chip.
The U-Boot boot loader will write to the serial port at 115200,8,N,1, so the kernel during bootstrap. Once started the system will spawn a getty
on the same serial port, with the same baud rate. On the original system, only root can login, but we don't know its password.
This is the start of boot messages, here you can find the full bootstrap log.
__ __ _ _ | \/ | __ _ _ ____ _____| | | | |\/| |/ _` | '__\ \ / / _ \ | | | | | | (_| | | \ V / __/ | | |_| |_|\__,_|_| \_/ \___|_|_| _ _ ____ _ | | | | | __ ) ___ ___ | |_ | | | |___| _ \ / _ \ / _ \| __| | |_| |___| |_) | (_) | (_) | |_ \___/ |____/ \___/ \___/ \__| ** LOADER ** ** MARVELL BOARD: DB-88F5182-LaCie LE U-Boot 1.1.4 (Feb 9 2009 - 13:15:53) Marvell version: 2.4.9 LaCie : 1.00.0001 U-Boot code: 00200000 -> 0026FFF0 BSS: -> 00283280 Soc: 88F5182 A2 (DDR2) CPU running @ 400Mhz SysClock = 200Mhz , TClock = 166Mhz DRAM CS[0] base 0x00000000 size 128MB DRAM Total size 128MB 32bit width [512kB@fff80000] Flash: 512 kB Addresses 4M - 0M are saved for the U-Boot usage. Mem malloc Initialization (4M - 3M): Done *** Warning - bad CRC, using default environment CPU : ARM926 (Rev 0) 88F5182 A2 streaming disabled
Compiling the Linux kernel
You can download the custom kernel I compiled (vanilla with patches for LEDs) here: http://www.rigacci.org/pub/Linux/kernel-lacie/
After several tries, I compiled a 2.6.32 kernel suitable to boot the LaCie from an ext3 Debian Lenny partition. No initrd is required to boot (this is fortunate , because I don't know how to install initrd with U-Boot). Here it is the config file.
The installation steps are:
- Provide a Debian rootfs into
/dev/sda7
(substitute the LaCie one. Partitionsda8
,sda9
andsda10
are no longer used). - Install the linux-image-2.6.32_lacie.0.10_armel.deb Debian package.
- Provide a swap partion into
/dev/sda5
(this is the LaCie default).
Native compile
We will try to compile a Debian kernel directly on the LaCie, i.e. this is a native compile, not a cross-compile. Obviously this will require a lot of time, a typical Debian kernel will require over 13.5 hours!
We start installing the Debian packages kernel-package and linux-source-2.6.32 (from Debian Squeeze) and all the dependencies.
We get a .config
file from the Debian package linux-image-2.6.32-trunk-kirkwood_2.6.32-5_armel.deb
, just to have something to start from:
/usr/src tar jxf linux-source-2.6.32.tar.bz2 ln -s linux-source-2.6.32 linux cd linux make-kpkg clean cp /root/config-2.6.32-trunk-kirkwood .config make-kpkg --revision=lacie.0.1 kernel_image --initrd --cross_compile=-
The cross_compile
option is required, otherwise the script will prepend the arm-linux-gnueabi-
prefix to all the build tool (ar
, as
, cc
, ld
, nm
, objdump
, objcopy
, strip
) and will fail, unless you make required symlinks in /usr/bin/
.
To avoid Cannot allocate memory
errors, provide plenty of swap space. The standard 128 Mb swap partition was not sufficient, an additional 1 Gb swap file did.
Cross compile
Compiling an arm kernel (for the LaCie) on a non-arm Linux box (e.g. your i386 or amd64 desktop) is called cross-compiling, this requires a specific toolchain (compiler and utilities). The Embedian project provides several prebuilt toolchains for Debian. See also How to build a new Debian/NSLU2 image. Compiling a kernel on my virtual KVM Linux box (running on an AMD Athlon 2.3 GHz) requires about 1 hour.
The Emdebian Wiki has detailed instructions, in short (we are working on Debian Lenny):
- Added Embedian repository to
/etc/apt/sources.list
:deb http://www.emdebian.org/debian/ lenny main
- Executed
apt-get update
andapt-get upgrade
. This will install automatically some packages required for cross-compiling, but others must be installed too:- gcc-4.3-arm-linux-gnu-base
- gcc-4.3-arm-linux-gnueabi-base
- g++-4.3-arm-linux-gnueabi
- libgcc1-armel-cross
- libc6-armel-cross
- libc6-dev-armel-cross
- binutils-arm-linux-gnueabi
- To compile the kernel in the Debian-way, install kernel-package and linux-source-2.6.32 (from Debian Squeeze). Package uboot-mkimage is also required to make an U-Boot image.
- I started using the kernel config from
linux-image-2.6.32-trunk-kirkwood
: it is not good to bootstrap the LaCie, but it is a starting point. You can use my working config instead. - Prepare the source tree:
cd /usr/src tar jxf linux-source-2.6.32.tar.bz2 ln -s linux-source-2.6.32 linux cd linux cp /root/config-2.6.32-trunk-kirkwood .config
- These are the commands executed to compile:
cd /usr/src/linux export CROSS_COMPILE=arm-linux-gnueabi- export ARCH=arm make menuconfig make-kpkg --arch armel --cross_compile=arm-linux-gnueabi- clean make-kpkg --revision=lacie.0.1 --initrd --arch=armel --cross_compile=arm-linux-gnueabi- kernel_image make uImage
The U-Boot image is saved in
arch/arm/boot/uImage
, thefile
command identifies it as an u-boot/PPCBoot image.
NOTE 1: make-kpkg
suggests to use the value of DEB_HOST_ARCH_CPU
reported by dpkg-architecture
as the -arch
parameter. On the LaCie it is arm, but we want KERNEL_ARCH=arm
and DPKG_ARCH=armel
so that the resulting .deb package will be installable into Debain armel. To obtain this, we need to add some line at the end of /usr/share/kernel-package/ruleset/misc/kernel_arch.mk
:
ifeq ($(strip $(architecture)),armel) KERNEL_ARCH := arm endif ifeq ($(strip $(architecture)),armeb) KERNEL_ARCH := arm endif
NOTE 2: Always remember to define the CROSS_COMPILE
and ARCH
variables before making anything in the source tree, also if you are just executing a make menuconfig
.
NOTE 3: After installing the .deb package, you must also install the uImage:
dd if=uImage of=/dev/sda6
NOTE 4: Using kernel-package 12.032 from Debian Squeeze, requires to patch debug.mk
and image.mk
files into /usr/share/kernel-package/ruleset/targets/
directory. They invoke the objcopy
command wich fails on arm files, it should be substituted by $(CROSS_COMPILE)objcopy
. Is this a bug?
Testing a kernel image
Our first try did not produce an image capable of booting the LaCie, fortunately it is possible to test a kernel image without actually installing it: just load it from a tftp server and try a boot.
On your Linux box install the tftpd package and copy the kernel uImage into /srv/tftp/C0A80224.img
(the default filename loaded by the U-Boot tftp client depends on the LaCie IP address).
Start the NetConsole using clunc
(see above), and use the tftpboot
and bootm
commands:
Marvell>> tftpboot TFTP from server 192.168.2.6; our IP address is 192.168.2.36 Filename 'C0A80224.img'. Load address: 0x400000 Loading: #####... done Bytes transferred = 1433512 (15dfa8 hex) Marvell>> bootm 0x400000 bootm 0x400000 ## Booting image at 00400000 ... Image Name: Linux-2.6.32 Created: 2010-02-01 13:29:21 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1433448 Bytes = 1.4 MB Load Address: 00008000 Entry Point: 00008000 Verifying Checksum ... OK OK Starting kernel ...
If you need to pass different boot arguments to the kernel, use setenv
before bootm
(the change is temporary, use saveenv
to make it permanent):
Marvell>> echo ${bootargs} echo ${bootargs} console=ttyS0,115200 root=/dev/sda7 ro boardType=mv88F5182 productType=d2Next Marvell>> setenv bootargs "console=ttyS0... "
If you are attached to the serial console you can see the kernel boot messages and errors:
Waiting for WOL Magic Packet Using egiga0 device Hit any key to stop autoboot: 0 Waiting for LUMP (0) Lump received switching to NetConsole on 192.168.2.6 Uncompressing Linux... done, booting the kernel. Error: unrecognized/unsupported machine ID (r1 = 0x0000020e). Available machine support: ID (hex) NAME 00000690 Marvell DB-88F6281-BP Development Board 00000691 Marvell RD-88F6192-NAS Development Board 00000692 Marvell RD-88F6281 Reference Board 00000831 Marvell SheevaPlug Reference Board 0000085b QNAP TS-119/TS-219 000009c6 QNAP TS-41x 00000915 Marvell OpenRD Base Board 00000939 Marvell OpenRD Client Board Please check your kernel config and/or bootloader.
Tip #1: Fixing the machine ID
The first problem was with the machine ID: the boot loader passes 0x20e = 526 in the r1 register, while the Linux kernel knows about different values (0x8ea = 2282 is the LaCie d2 Network). See the explanation here: Resolving Booting Problems on arm.
The fix is to change the archNumber
environment variable (saving it into the U-Boot flash is required) and reset:
Marvell>> echo ${arcNumber} echo ${arcNumber} 526 Marvell>> setenv arcNumber 2282 setenv arcNumber 2282 saveenv reset
Tip #2: Warning: unable to open an initial console
If we are trying to use a kernel without initrd, remember to populate the /dev/
directory, at least with the following devices:
crw------- 1 root root 5, 1 2010-02-03 21:28 /dev/console brw-rw---- 1 root disk 8, 0 2010-02-03 21:27 /dev/sda brw-rw---- 1 root disk 8, 1 2010-02-03 21:27 /dev/sda1 brw-rw---- 1 root disk 8, 2 2010-02-03 21:27 /dev/sda2 brw-rw---- 1 root disk 8, 5 2010-02-03 21:27 /dev/sda5 brw-rw---- 1 root disk 8, 6 2010-02-03 21:27 /dev/sda6 brw-rw---- 1 root disk 8, 7 2010-02-03 21:27 /dev/sda7 brw-rw---- 1 root disk 8, 8 2010-02-03 21:27 /dev/sda8 brw-rw---- 1 root disk 8, 9 2010-02-03 21:27 /dev/sda9 brw-rw---- 1 root disk 8, 10 2010-02-03 21:27 /dev/sda10 crw-rw---- 1 root root 4, 0 2010-02-03 21:27 /dev/tty0 crw------- 1 root root 4, 1 2010-02-03 21:28 /dev/tty1 crw------- 1 root root 4, 2 2010-02-03 21:28 /dev/tty2 crw------- 1 root root 4, 3 2010-02-03 21:28 /dev/tty3 crw------- 1 root root 4, 4 2010-02-03 21:28 /dev/tty4 crw------- 1 root root 4, 64 2010-02-03 21:28 /dev/ttyS0 crw-rw---- 1 root dialout 4, 65 2010-02-03 21:27 /dev/ttyS1
Once init(8)
will start, other devices will be created by udev(7)
.
USB Sound
When I attached an USB audio stick, this is what the lsusb
command says:
Bus 001 Device 002: ID 0c76:1607 JMTek, LLC.
Then the kernel loads the proper drivers:
usb 1-1: new full speed USB device using orion-ehci and address 2 usb 1-1: New USB device found, idVendor=0c76, idProduct=1607 usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0 usb 1-1: Product: USB Headphone Set usb 1-1: configuration #1 chosen from 1 choice usbcore: registered new interface driver hiddev input: USB Headphone Set as /devices/platform/orion-ehci.0/usb1/1-1/1-1:1.3/input/input1 generic-usb 0003:0C76:1607.0001: input,hidraw0: USB HID v1.00 Device [USB Headphone Set] on usb-orion-ehci.0-1/input3 usbcore: registered new interface driver usbhid usbhid: v2.6:USB HID core driver usbcore: registered new interface driver snd-usb-audio
Playing some mp3 tracks with mpg321
via Alsa resulted in annoying audio glitches; strange enough the glitches tend to disappear if the LaCie is under heavy load. Fortunately there is a workaround: load the Alsa OSS compatibility layer and use OSS output instead:
modprobe snd_pcm_oss mpg321 -o oss track1.mp3
Playing mp3 takes about 16% of CPU, 2% of memory and system load average remains near to zero.
USB Audio volume problem
On Linux kernel 2.6.32 (providing Alsa sound drivers 1.0.21) the following USB audio dongle works as expected, including the volume control:
Bus 001 Device 003: ID 0c76:1607 JMTek, LLC. audio controller
There is a problem with some other USB chips, where the volume control does not work. When the volume control is set to the lower position, the audio is muted, but at any other position the audio is set to its maximum value. This is a chip wich has the problem:
Bus 001 Device 002: ID 1130:f211 Tenx Technology, Inc. TP6911 Audio Headset
Here there is a bug report #559939 reported to the Ubuntu distribution.
Other NAS comparison
Model | CPU | RAM | Flash | HD | Fan | WoL |
---|---|---|---|---|---|---|
Qnap TS-110 | 800 Mhz | 256 Mb | 16 Mb | 1 | Yes | ? |
Qnap TS-119 | 1.2 Ghz | 512 Mb | 16 Mb | 1 | No | ? |
ReadyNAS Duo RND2000 | 280 Mhz Sparc 32 | (exp) 256 Mb | 64 Mb | 2 | Yes | No |
NETGEAR Stora MS2110 | 1 GHz Marvell 88F6281 Kirkwood | 128 Mb | 256 Mb | 2 | Yes | ? |
LaCie d2 Network | 400 Mhz Marvell 88F5182 Orion | 128 Mb | 4 Mb | 1 | No | Yes |
LaCie 2big Network | 400 Mhz | 64 Mb | ? | 2 | Yes | ? |
LaCie Network Space 1 TB | 400 Mhz Marvell 88F6082 Feroceon | 16/64 Mb | ? | 1 | No | ? |
Backporting minidlna
We run Debian 6 Squeeze on our LaCie d2 Network and we want it to be a DLNA server. We choosed minidlna because it is targeted to embedded systems. The package exists for Debian 7 Wheezy, so we have to backport it.
Into a Qemu armel virtual machine we installed the packages required for Debian developing and build dependencies, we need also debhelper from backports.
apt-get install build-essential dh-make debhelper dpatch apt-get install libavcodec-dev libavformat-dev libavutil-dev libexif-dev \ libflac-dev libid3tag0-dev libogg-dev libsqlite3-dev libvorbis-dev libjpeg-dev wget http://ftp.at.debian.org/debian-backports//pool/main/d/debhelper/debhelper_9.20120909~bpo60+1_all.deb dpkg -i debhelper_9.20120909~bpo60+1_all.deb
Then we downloaded the minidlna sources and compiled the sources:
mkdir /usr/local/src/minidlna cd /usr/local/src/minidlna wget http://ftp.de.debian.org/debian/pool/main/m/minidlna/minidlna_1.0.24+dfsg-1.dsc wget http://ftp.de.debian.org/debian/pool/main/m/minidlna/minidlna_1.0.24+dfsg.orig.tar.gz wget http://ftp.de.debian.org/debian/pool/main/m/minidlna/minidlna_1.0.24+dfsg-1.debian.tar.gz dpkg-source -x minidlna_1.0.24+dfsg-1.dsc cd minidlna-1.0.24+dfsg dpkg-buildpackage -rfakeroot cd ..
The resulting minidlna_1.0.24+dfsg-1_armel.deb package installed fine into the LaCie, just make a symlink /run → /var/run
.
Configuration file is /etc/minidlna.conf
, default share directory is /var/lib/minidlna
, used ports are 8200/TCP (http and media transfer), 3307/UDP and 1900/UDP.
Web Links
- LaCie NAS another Wiki, with U-Boot NetConsole
- LaCie Ethernet Disk mini. Interesting part on how to install a Debian into a chroot.
- Arm binaries for Buffalo NAS. Partially compatible with LaCie O.S.
- utelnetd, binary for arm processor.
- LaCie d2 Network, Italian product page
- LaCie d2 Network, English product page
- Hardware Upgrade - LaCie, serial console on LaCie Network Space (Italian).