Table of Contents
Hacking the LaCie d2 Network 2
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:
- CPU ARM926EJ-S rev 1 (v5l) at 1200 MHz
- Clocks: L2 400 MHz, SysClock 400 MHz, TClock = 166 MHz
- 256 Mb RAM
- 512 kb of Flash Memory
- Aluminium case works as heatsink, no cooling fan
- Gigabit Ethernet
- Wake-On-LAN (handled by system software, not by firmware)
- Linux kernel version 2.6.22.18
- 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
- USB port B for printer
- Hard disk Samsung 1.00 Tb, SAMSUNG HD103SI (929.5 Gb available)
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
- The dmesg text after the boot.
- The boot log captured on the serial line. The boot process is interrupted by the device entering the Deep Sleep Mode, see the Wake up the board message when the Wake-On-LAN packet is received.
- The diagnostics.zip file saved when you click on the configuration download. It is an archive containing most of the
/etc/
directory.
[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:
/1.0/prod/1.0.90/d2network2_1.0.90.capsule
/1.0/prod/1.0.90/d2network2_1.0.90.xml
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:
/etc/fstab
/etc/hosts
/etc/inittab
/etc/network/interfaces
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
Useful links
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:
- build-essential
- kernel-package
- libncurses5-dev
- lzma
- uboot-mkimage
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:
- linux-libc-dev-armel-cross
- libc6-armel-cross
- libc6-dev-armel-cross
- binutils-arm-linux-gnueabi
- gcc-4.3-arm-linux-gnueabi
- g++-4.3-arm-linux-gnueabi
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. |