Table of Contents

Hacking the LaCie d2 Network 2

LaCie d2 Network

The LaCie d2 Network 2 is very similar to the LaCie d2 Network, luckily enough the hardware is better and gives better performances. Just one thing is worst than before: the Wake-On-LAN is not longer handled by the U-Boot code, it is handled by the init scripts. This means that if you install a plain GNU/Linux system, you must install special software to get the Wake-On-LAN function.

The LaCie software is changed a lot. May be it is possible get root access without disassembling it, have a look at the Auto-Update function.

Main features of this device are:

Serial connection

The JTAG connector is the same as the LaCie d2 Network model, see JTAG Serial Connector Pin-out. On the serial line there is a login prompt, but unfortunately we don't know the root password. This is the hash (if someone wants to break it):

root:$1$$1RDUuTsVHjre9juUvuICX.:12542:0:99999:7:::

U-Boot NetConsole

It is possible to have a boot prompt without using the serial port. 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.

I used this Clunc snapshot, downloaded from the Git repository. See the notes about the NetConsole on the old LaCie model.

This is the output of help and printenv commands. I was able to boot the device from the U-Boot NetConsole:

Marvell>> ide reset
Marvell>> ide info
Marvell>> boot

Theoretically the NetConsole is exploitable on the local network: just run Clunc and wait for a LaCie to be powered on, you will get a NetConsole prompt. Then feed an hacked boot image using tftpboot.

Here it is an example of net boot, feeding the original uImage to the device (you must configure the tftp daemon on the host running clunc and provide the uImage file renamed as searched by the U-Boot client):

Marvell>> tftpboot
tftpboot
*** Warning: no boot file name; using 'C0A80325.img'
Using egiga0 device
TFTP from server 192.168.3.2; our IP address is 192.168.3.37
Filename 'C0A80325.img'.
Load address: 0x2000000
Loading: #################################################################
         #####################################################
done
Bytes transferred = 1931568 (1d7930 hex)
Marvell>> bootm
bootm
## Booting image at 02000000 ...
   Image Name:   Linux-2.6.22.18
   Created:      2010-01-14  20:27:21 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1931504 Bytes =  1.8 MB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
OK

Starting kernel ...

Starting the SSH daemon (disassembling required)

A computer running GNU/Linux is required to perform these steps.

First of all, set the password for the admin account.

Disassemble the LaCie removing the 4 screws from the back cover and the 3 screws from the bottom side. Then take the hard disk apart, removing the 4 screws holding the disk on the bottom side.

Attach the disk to the GNU/Linux machine and mount the /dev/sdN8 partition, where N is the letter assigned to the drive. Search the last snapshot available into the /snaps/ directory; onto a new system it should be /snaps/00/.

Edit /snaps/00/etc/shadow and set the encrypted root password, see man 5 shadow if you need help. You can copy the hash from the admin account, or you can copy the following, which is the hash for d2network2 password:

root:$1$ZgjvVEBo$xxB4Bk7ppNTERbbSHIaNm/:12542:0:99999:7:::

Edit the /snaps/00/etc/initng/runlevel/default.runlevel file. If it does not exists, create it with all the subdirectories path, the file must be executable (chmod 755). Add a line at the end, telling to start sshd:

sshd

Optional: edit /snaps/00/etc/passwd and set a valid shell for the admin account:

admin:x:500:100:None:/home:/bin/sh

Umount the partition from the GNU/Linux computer and reassemble the LaCie. At next boot you will have an ssh daemon and you can logis as root.

The filesystems

At boot time the rootfs is /dev/sda7, during bootstrap the command pivot_root(8) is used to switch to a different rootfs, so at runtime the rootfs is an unionfs of /dev/sda8 + /dev/sda9 (see the table below).

Device Start End Blocks Id System Note
/dev/sda1 1 250 2008093 5 Extended Contains sda5 … sda10.
/dev/sda2 251 121601 974751907 83 Linux This is the user's data partition, formatted as xfs, it is mounted under /media/internal_6. Several subdirectories (e.g. one for each share) are mounted with the -o bind option under other mounting points.
/dev/sda5 1 32 256977 82 Linux swap Used as swap partition.
/dev/sda6 33 33 8001 83 Linux Not a filesystem, contains an u-boot uImage with the kernel and the initramfs.
/dev/sda7 34 34 8001 83 Linux Initial root filesystem used by the kernel (ext3). Contains the scripts to assemble a running root filesystem via unionfs. Available at runtime under /oldroot.
/dev/sda8 35 140 851413 83 Linux Runtime root filesystem (ext3), read-only part in unionfs. Also available at runtime under /oldroot/var/original.
/dev/sda9 141 249 875511 83 Linux Runtime root filesystem (ext3), 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.
This partition contains also the directories EDMINI/tmp/ and EDMINI/var/, which are mounted at runtime with the -o bind option, under /tmp and /var.
/dev/sda10 250 250 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.

Looking around at the shell prompt

[root@LaCie-d2 ~]# free
              total         used         free       shared      buffers
  Mem:       256848       123736       133112            0         7216
 Swap:       256968            0       256968
Total:       513816       123736       390080
[root@LaCie-d2 ~]# fdisk -l /dev/sda       

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         250     2008093+  5 Extended
/dev/sda2             251      121601   974751907+ 83 Linux
/dev/sda5               1          32      256977  82 Linux swap
/dev/sda6              33          33        8001  83 Linux
/dev/sda7              34          34        8001  83 Linux
/dev/sda8              35         140      851413+ 83 Linux
/dev/sda9             141         249      875511  83 Linux
/dev/sda10            250         250        8001  83 Linux
[root@LaCie-d2 ~]# mount
rootfs on / type rootfs (rw)
/dev/sda7 on /oldroot type ext3 (ro,data=ordered)
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)
udev on /dev type tmpfs (rw)
/dev/sda9 on /tmp type ext3 (rw,data=ordered)
usbfs on /proc/bus/usb type usbfs (rw)
/dev/sda2 on /media/internal_6 type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /lacie/tmp type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /lacie/var type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /lacie/torrent_dir type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /lacie/autoupdate type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /lacie/afp_db type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /shares/Share type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /shares/Public type xfs (rw,nosuid,nodev,usrquota,prjquota)
/dev/sda2 on /shares/prova type xfs (rw,nosuid,nodev,usrquota,prjquota)

The Auto-Update function

The AUTO-Update function will connect to an FTP site and search for a new archive to install. This is the FTP account used:

host update.lacie.com
login d2network2
password d2network2

The LaCie will serach for an update with a version number greater than the version installed on the device. With a version 1.0.8 the LaCie downloaded the following two files:

After the version 1.0.90 was installed, the LaCie will search for /1.1/prod/1.1.x/d2network2_1.1.x.{xml|capsule} files.

The capsule file is just a tar archive, with an XML header. The .xml file contains the release notes (details) for the update.

Every capsule file available on the LaCie site contains a new kernel image and a new rootfs image, it seems that no signature is verified so it should be possible to upload an hacked image just using a fake DNS server and a local FTP server.

Wake-On-LAN

The Wake-On-LAN works when the device is put into Deep Sleep Mode, send a Wake-On-LAN Magic Packet e.g. with the etherwake(8) tool:

etherwake -i eth0 00:D0:4B:8B:4F:C2

The Wake-On-LAN is not handled by the U-Boot code (like in the LaCie d2 Network). When the power switch is onto the ON position, the U-Boot always begins the boot process spinning-on the disk, during the boot process a script checks if the Deep Sleep Mode is active, in that case it halts the disk and wait for the Magic Packet.

If you install a plain Debian operating system, you can use the Fake Wake-On-LAN software to simulate a Wake-On-LAN.

Installing Debian

Device Mounting point Type Note
/dev/sda1 Extended Contains sda5, sda6 and sda7.
/dev/sda2 /home ext3
/dev/sda5 swap swap
/dev/sda6 None U-Boot image with kernel, etc.
/dev/sda7 / ext3

Creating the root filesystem

Fortunately I have an already debianized LaCie, so I used that box to make a minimal Debian installation using debootstrap.

It is mandatory to use an armel box to run debootstrap (at least the second stage of the installation, see --foreign and --second-stage switches of debootstrap), so it is not possible to use a standard Intel PC.

This is the recipe for the installation:

mkdir /home/squeeze
debootstrap squeeze /home/squeeze
cd /home/squeeze/
mount -o bind /dev /home/squeeze/dev
mount -o bind /proc /home/squeeze/proc
chroot /home/squeeze
aptitude install locales
aptitude install less
dpkg-reconfigure locales
dpkg-reconfigure tzdata

Several files must be configured in the chroot environment:

Because the original LaCie kernel does not support udev, some devices must be created statically in /dev/, using mknod:

crw------- 1 root root 5,  1 2010-12-09 22:02 /dev/console
brw-rw---- 1 root disk 8,  0 2010-12-09 22:01 /dev/sda
brw-rw---- 1 root disk 8,  1 2010-12-09 22:01 /dev/sda1
brw-rw---- 1 root disk 8,  2 2010-12-09 22:01 /dev/sda2
brw-rw---- 1 root disk 8,  5 2010-12-09 22:01 /dev/sda5
brw-rw---- 1 root disk 8,  6 2010-12-09 22:01 /dev/sda6
brw-rw---- 1 root disk 8,  7 2010-12-09 22:01 /dev/sda7
crw------- 1 root root 4, 64 2010-12-09 22:01 /dev/ttyS0

Finally exit the chroot environment and create an archive of the installation:

exit
umount /home/squeeze/dev/
umount /home/squeeze/proc/
tar zcvf /home/lacie_d2net2_sda7_squeeze.tgz --numeric-owner /home/squeeze/

The root filesystem is contained into the lacie_d2net2_sda7_squeeze.tgz archive.

Dissecting the original kernel

The contents of the original /dev/sda6 is an u-boot legacy uImage. The image was probably created with mkimage (provided by the uboot-mkimage package), it contains a kernel image and an initramfs archive.

Probably the initramfs is embedded into the kernel using the CONFIG_INITRAMFS_SOURCE kernel option.

First of all, attach the disk to a GNU/Linux box and extract the image (suppose that the box assigned /dev/sdb to the disk):

dd if=/dev/sdb6 of=sda6.bin

The file sda6.bin is an exact copy of the whole disk partition, we can get some details of the image using the file command:

file sda6.bin 
sda6.bin: u-boot legacy uImage, Linux-2.6.22.18, Linux/ARM,
  OS Kernel Image (Not compressed), 1931504 bytes, Thu Jan 14 20:27:21 2010,
  Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x231CA472,
  Data CRC: 0xF95DD173

If the header added by mkimage is 64 bytes long, we can restore the original vmlinux image:

dd if=sda6.bin of=vmlinux bs=1 skip=64 count=1931504

To restore the original uImage we use instead:

dd if=sda6.bin of=uImage bs=1 count=1931568

The command line to create the uImage was probably something like:

mkimage -A arm -O linux -T kernel -C none -a 0 -e 0x8000 -n "Linux-2.6.22.18" -d vmlinux uImage

How to extract the initramfs from the vmlinux image.

First of all search for a gzip signature (1F 8B 08) into the vmlinux file:



Say the gzip signature offset is 12504, extract the gzip data and expand it:

dd if=vmlinux of=vmlinux_data1.gz bs=1 skip=12504
gunzip vmlinux_data1.gz

Search again for a gzip signature, extract the gzip data and expand it. The resulting file is the initramfs cpio archive:

dd if=vmlinux_data1 of=vmlinux_data2.gz bs=1 skip=88928
gunzip vmlinux_data2.gz
mv vmlinux_data2 initramfs.cpio
mkdir initramfs
cd initramfs
cat ../initramfs.cpio | cpio --extract --make-directories  --no-absolute-filenames

Making a new kernel

Before preparing a new kernel image remember that the boot loader (U-boot) passes a machine ID to the kernel via the r1 register (see Testing a kernel image, tip #1), the kernel checks that number against a list of known IDs; if no match is found, the boot will halt with the following message on the serial console:

Uncompressing Linux... done, booting the kernel.
Error: unrecognized/unsupported machine ID (r1 = 0x0000089b).

Available machine support:

ID (hex)        NAME
000008ea        LaCie d2 Network

Please check your kernel config and/or bootloader.

With the old LaCie model it was possible to change the machine ID passed to the kernel using the setenv arcNumber command at the boot prompt. This seems no longer possible with the new model.

Cross compile a Debian kernel

We choose to cross-compile a kernel on a Debian i386 Squeeze box. The procedure is very similar to the cross-compile for the old LaCie d2 Network.

On the Squeeze box install the following packages:

Add to /etc/apt/sources.list the Emdebian repository which provieds a cross-compile toolchain for the arm architecture

deb http://www.emdebian.org/debian/ squeeze main

Get and install the repository key:

wget http://www.emdebian.org/0x97BB3B58.txt
apt-key add 0x97BB3B58.txt

Then install the following packages:

Install the linux-source-2.6.37 package from Debian experimental. We need 2.6.37 because previous versions does not have support for LaCie d2 Network 2 hardware.

Using the kernel config file provied by Debian for the kirkwood architecture as a starting point, we made some changes to add support for our LaCie machine (MACH_D2NET_V2), the RTC clock (RTC_DRV_MV), etc. This is the final config file and linux-image package.

Prepare the source tree:

cd /usr/src
tar jxf linux-source-2.6.37-rc5.tar.bz2
ln -s linux-source-2.6.37-rc5 linux
cd linux
cp /root/config-2.6.37-rc5_lacie2dn2.0.14 .config

These are the commands create the linux-image .deb package and the uImage:

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=lacie2dn2.0.14 --initrd --arch=armel --cross_compile=arm-linux-gnueabi- kernel_image
make uImage

The U-Boot image is saved in arch/arm/boot/uImage.

Copy both the linux-image .deb and the uImage into the LaCie and execute:

dpkg -i linux-image-2.6.37-rc5_lacie2dn2.0.14_armel.deb
dd if=uImage of=/dev/sda6

Fake Wake-on-LAN

The Ethernet chip does not have WoL capabilities (whereas the old d2 Network does), so we can only simulate it. This is my first attempt to make a software Wake-on-LAN.

At an early stage of the boot process the fake-on-lan program suspends the USB power, turn off the blue LED and suspend the disk. Then the program waits for a Wake-on-LAN Magic Packet or for a Power Button press/release before to proceed. The device is effectively powered-on and running the Linux kernel, just the USB, the LED and the disk are turned off. I'm running the program with a Debian Squeeze installation.

You can download the program here: fake-on-lan-20110324.tar.gz.

The EEPROM

The content of the EEPROM is exposed for read and write via the pseudo file /sys/bus/i2c/devices/0-0050/eeprom, like with the previous d2 Network model, but the meaning is changed. This is what I know:

Offset Length Content
0 2 0x00 0x02
2 6 Ethernet MAC address.