====== Hacking the LaCie d2 Network 2 ======
{{.:lacie:lacie_d2_network.jpg?160 |LaCie d2 Network}}
The **LaCie d2 Network 2** is very similar to the **[[lacie_d2_network|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 [[#the_auto-update_function|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
* Interoperate with [[wp>Universal_Plug_and_Play|UPnP A/V]] and [[wp>Dlna|DLNA]]
* **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 [[lacie_d2_network#jtag_serial_connector_pin-out|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 {{:doc:appunti:hardware:lacie:clunc-head-e199d11.tar.gz|Clunc snapshot}}, downloaded from the [[http://git.lacie-nas.org/|Git repository]]. See the notes about the [[lacie_d2_network#u-boot_netconsole|NetConsole on the old LaCie model]].
This is {{.:lacie:d2net2_u-boot_help_printenv.txt|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/sd//N//8''** 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 **{{.:lacie:dmesg_d2net_v2.txt|dmesg}}** text after the boot.
* The **{{.:lacie:lacie_d2n2_boot_log.txt|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 **{{.:lacie:diagnostics.zip|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|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 **[[http://www.rigacci.net/listing/lacie_d2net2/debian_squeeze/lacie_d2net2_sda7_squeeze.tgz|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 **{{.:lacie:d2net2_initramfs.cpio.gz|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 ===
* [[http://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt|ramfs, rootfs and initramfs]]
* [[http://www.gossamer-threads.com/lists/linux/kernel/1015140|Initramfs from existing vmlinuz]]
* [[http://en.gentoo-wiki.com/wiki/Initramfs|Dismantling the Kernel]]
* [[http://blog.harrylau.com/2009/08/generate-uboot-uimage.html|Generate uboot image]]
* [[http://wiki.dns323.info/howto:uboot|Cross-compile an u-Boot image]]
==== 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 [[lacie_d2_network#testing_a_kernel_image|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 [[lacie_d2_network#cross_compile|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 **[[http://www.emdebian.org/|Emdebian]]** repository which provieds a cross-compile **[[http://wiki.debian.org/EmdebianToolchain|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 **[[http://packages.debian.org/experimental/linux-source-2.6.37|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 **{{.:lacie:config-2.6.37-rc5_lacie2dn2.0.15.txt|config}}** file and **[[http://www.rigacci.org/pub/Linux/kernel-lacie/linux-image-2.6.37-rc5_lacie2dn2.0.15_armel.deb|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: **{{.:lacie:fake-on-lan-20110324.tar.gz|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. |