Disclaimer: the information provided on this page is given as is, i.e. without warranty that you will not break your system following it. Additionally, do not expect to get support and warranty from NETGEAR if this happens.

Debian and upstream kernel on NETGEAR ReadyNAS Duo v2

This page documents some efforts to get a recent kernel and latest Debian system running on NETGEAR ReadyNAS Duo v2, instead of the original (Marvell/NETGEAR-patched 2.6.31.8) kernel and custom system. The efforts was started at the beginning of 2013 on 3.7 kernel, and completed on September 2013 with the release of 3.11 kernel. The major changes pushed in mainline kernel (via commits 4a9f4c7f, 594fbe71, 6bd98481, f236f5aa) are

Note that if you are looking for a server similar to the ReadyNAS Duo v2 but with an ARMv7 processor (i.e. with NX bit support), I recently bought a NETGEAR ReadyNAS 102 (update of Duo v2) and did the same work to get a recent kernel and Debian running on it. I started a page dedicated to that work.

If you have comments, corrections, additional information I missed or problems w/ this page, do not hesitate to drop me a mail. Note that everything (from hardware specs to debian and kernel install) has been kept on a single page to have all the information available in a single location and be able to make a PDF out of it.

Here is the main table of contents for the page, with links to the various sections of the page.


Changelog i.e. work done

Todo list i.e. work in progress

Hardware specs

This section is dedicated to the hardware specs of the NETGEAR ReadyNAS Duo v2. It is based on visual inspection of Duo v2 main board and two daughter boards, completed with reading of NETGEAR 2.6.31.8 kernel sources and publicly available (read Google-gathered) information .

When available, additional information and software handling details are given for each hardware part. For instance, if you are looking for informations related to the fan controller, simply click the link above to get the details of what is used and how support is provided.

Each picture available on this page is a thumbnail of a larger picture. The larger one can be accessed by clicking the thumbnail.

If you are in a hurry looking for a specific info, you can use this table of contents to directly access information on a specific hardware part of the system or get an overview of what a NETGEAR ReadyNAS Duo v2 is made of.

The picture below provides an overview of NETGEAR ReadyNAS Duo v2 main board. At the rear of the board, from left to right on the picture are connectors for two daughter boards, respectively supporting the SATA connectors for the first (DUO V3 BP BOARD V3.0), and the two USB 3.0 ports, the RJ45 connector, the reset button, the serial pins, and the power connector for the main fan for the second (DUO V3 IO BOARD V3.2).

If you wonder why the NAS is called Duo v2 (v1 was its SPARC-based ancestor) but the board are marked DUO V3 (sources also have that mention), ... I do not have an answer.

On the main board, the various buttons and LEDs are located near the front USB 2.0 port. The Marvell SoC is located at the center of the board, mask by its heat sink.

NETGEAR ReadyNAS Duo v2 main board

The two pictures below respectively present the front and back of the first daughter board (DUO V3 BP BOARD V3.0), for connection of SATA disks.

Front of first daughter board, with SATA plugs for disksBack of first daughter board

The two pictures below respectively present the front and back of the second daughter board (DUO V3 IO BOARD V3.2), for connection of SATA disks.

Front of second daughter board

The following picture provides a view of the two daughter boards at their original location at the rear of the device (main board has been removed).

SoC

The ReadyNAS Duo v2 runs a Marvell 82F6282 SoC (aka ARMADA 300) from Kirkwood family. This SoC integrates a single core ARMv5TE-compatible CPU running at 1.6GHz (Marvell also has 1.8 and 2GHz versions). If you want to read on the subject, here are some locally cached documents:

root@hal:~# cat /proc/cpuinfo 
Processor       : Feroceon 88FR131 rev 1 (v5l)
BogoMIPS        : 1599.07
Features        : swp half thumb fastmult edsp 
CPU implementer : 0x56
CPU architecture: 5TE
CPU variant     : 0x2
CPU part        : 0x131
CPU revision    : 1

Hardware        : Feroceon-KW
Revision        : 0000
Serial          : 0000000000000000

Hynix H5TQ1G83DFR-H9C

Two 128MB DDR3 1333 Hynix H5TQ1G83DFR-H9C chips are connected to the SoC. As you may have noticed, those chips are soldered on the board, i.e. not upgradable. Local copies of Hynix H5TQ1G83DFR specs are available.

Hynix H27U1G8F2BTR

The ReadyNAS Duo comes with 128MB of NAND flash. The chip is a Hynix H27U1G8F2BTR. If you want to get more details, the Hynix NAND flash part number decoding document is woth reading.

Protechnic Electric Co MG9212YB-25 Fan

The ReadyNAS cooling is performed by a 92mmx92mmx25mm Protechnic Electric CO MG9212YB-25 Fan. This fan is connected to the second daughter board.

GMT G762 Fan controller

Previous FAN is controlled by a G762 Fan controller from Global Mixed-mode Technology Inc. The G762 has many similarities with the G760a, for which support is available in upstream kernel. For those interested by the details of the device, I keep a local copy of a more detailed datasheet for the G762/G763 fan controller than the one available on GMT site.

A driver for G762 has been developed by LaCie for some of its NASes based on existing G760a driver code. Even though the driver is published under a GPLv2 license, it is currently not available in upstream kernel. Nonetheless, with minor adaptations, it integrates perfectly in current 3.8 kernel tree and allowed me to control the rotation of the fan. After quite some work with this driver as a basis, I managed to get it merged upstream in 3.11. Here is what you get on a 3.11 kernel:

root@hal:~# uname -a
Linux hal 3.11.0.duov2 #1 Sun Sep 8 00:01:11 CEST 2013 armv5tel GNU/Linux

After having installed lm-sensors package, we get:

root@hal:~# sensors
g762-i2c-0-3e
Adapter: mv64xxx_i2c adapter
fan1:        2082 RPM  (div = 1)

kirkwood_thermal-virtual-0
Adapter: Virtual device
temp1:        +36.7°C

root@hal:~# sensors -u
g762-i2c-0-3e
Adapter: mv64xxx_i2c adapter
fan1:
  fan1_input: 2275.000
  fan1_alarm: 0.000
  fan1_fault: 0.000
  fan1_div: 1.000
  fan1_pulses: 2.000

kirkwood_thermal-virtual-0
Adapter: Virtual device
temp1:
  temp1_input: 36.697

root@hal:/sys/bus/i2c# ls drivers
dummy  g762  rtc-rs5c372

root@hal:/sys/bus/i2c/devices/0-003e# ls
driver      fan1_div    fan1_target  modalias  pwm1         pwm1_mode  uevent
fan1_alarm  fan1_input  hwmon        name      pwm1_enable  subsystem

By playing with fan1_input et fan1_target, we can indeed modify the speed of the fan and collect its value:

root@hal:/sys/bus/i2c/devices/0-003e# echo 2700 > fan1_target 
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
2700
root@hal:/sys/bus/i2c/devices/0-003e# echo 1500 > fan1_target 
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
2433
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
2048
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
2048
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1780
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1780
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1606
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1606
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1480
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1480
root@hal:/sys/bus/i2c/devices/0-003e# cat fan1_input 
1507

As can be seen above, the speed progressively stabilizes to the expected value. If you are interested by a more useful setup, you can take a look at the section dedicated to automatic fan control based on NAS temperature using fancontrol package.

RICOH RS5C372A

The RTC of the system is provided by an I2C-connected Ricoh RS5C372A. Support for that chip is avilable in upstream kernel and is working fine.

Ricoh RS5C372A I2C bus RTC

NEC µPD720200 (D720200AF1)

The two USB3.0 ports on the rear of the NAS are provided by a NEC/RENESAS (Renesas bought NEC in 2010) µPD720200 USB 3.0 Host Controller, connected on PCIe bus. The configuration of the controller is provided by the Macronix 512 Kilobit SPI flash.

Support for the chip is available in upstream kernel. Here is what lspci -v reports on a 3.8 kernel with the driver enabled:

00:01.0 USB controller: NEC Corp. uPD720200 USB 3.0 Host Controller (rev 04) (prog-if 30 [XHCI])
        Flags: bus master, fast devsel, latency 0, IRQ 9
        Memory at e0000000 (64-bit, non-prefetchable) [size=8K]
        Capabilities: [50] Power Management version 3
        Capabilities: [70] MSI: Enable- Count=1/8 Maskable- 64bit+
        Capabilities: [90] MSI-X: Enable- Count=8 Masked-
        Capabilities: [a0] Express Endpoint, MSI 00
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [140] Device Serial Number ff-ff-ff-ff-ff-ff-ff-ff
        Capabilities: [150] Latency Tolerance Reporting
        Kernel driver in use: xhci_hcd

Nonetheless, just enabling the config knob in the kernel is not sufficient: in that case plugging a simple USB key on one of the two rear ports of the device gives no result (nothing shows up in kernel logs), even though the controller is recognized (lspci presents the controller). Some initialization code is needed in board setup fiel for the port to work. As of today (March 2, 2013), USB 3.0 ports now work as expected.

Temperature sensor

Marvell 88F6282 SoC includes a temperature sensor. In Marvell 5.1.3 LSP (patches against linux 2.6.31.8 kernel on which NETGEAR kernel is based), a sensor driver is present to support the feature (/arch/arm/mach-feroceon-kw/hwmon.c, 189 lines). It provides a sysfs access to the temperature of the SoC.

It is nonetheless disabled in Netgear kernel (i.e. CONFIG_SENSORS_FEROCEON_KW is not set) and the userland on Duo v2 relies only on two other sensors to access the temperature on the enclosure: the ones included in the disks and available via smartctl.

I was about to port the drivers to 3.8 kernel when I noticed the submission of thermal sensor support for Kirkwood SoCs for upstream kernel by Nobuhiro Iwamatsu. Its set of patches has recently (2013-02-08) been applied to thermal -next tree. In the end, the patch should be availble in 3.9 kernel.

Once enabled (CONFIG_KIRKWOOD_THERMAL), the inclusion of kirkwood-6282.dtsi in NETGEAR readynas dts file, automatically provides the following information to describe how the SoC temperature sensor is supported (register, driver, status):

    thermal@10078 {
            compatible = "marvell,kirkwood-thermal";
            reg = <0x10078 0x4>;
            status = "okay";
    };

After a reboot on the new kernel, here is what is now available on the system:

root@hal:~# cd /sys/class/thermal/
root@hal:/sys/class/thermal# ls 
thermal_zone0
root@hal:/sys/class/thermal# cd thermal_zone0
root@hal:/sys/class/thermal/thermal_zone0# ls
passive  policy  subsystem  temp  type  uevent
root@hal:/sys/class/thermal/thermal_zone0# ls -l 
total 0
-rw-r--r-- 1 root root 4096 Feb 26 23:21 passive
-rw-r--r-- 1 root root 4096 Feb 26 23:21 policy
lrwxrwxrwx 1 root root    0 Feb 26 23:21 subsystem -> ../../../../class/thermal
-r--r--r-- 1 root root 4096 Feb 26 23:21 temp
-r--r--r-- 1 root root 4096 Feb 26 23:21 type
-rw-r--r-- 1 root root 4096 Feb 26 23:21 uevent

root@hal:/sys/class/thermal/thermal_zone0# cat type 
kirkwood_thermal

root@hal:/sys/class/thermal/thermal_zone0# cat temp 
28928

The final value provided by temp key is the SoC temperature in milli degrees Celsius (i.e. 28.928 °C). sensors command from lm-sensors package provides simple access to the value:

root@hal:~# sensors
g762-i2c-0-3e
Adapter: mv64xxx_i2c adapter
fan1:        2730 RPM  (div = 1)

kirkwood_thermal-virtual-0
Adapter: Virtual device
temp1:        +29.7°C

Marvell 88E1318

The SoC includes two Gigabit Ethernet MAC but no PHY. The gigabit PHY of the system is provided by a Marvell Alaska 88E1318.

Nuvoton 3012S

Local copy of Nuvoton NCT3012S datasheet .

ATMEL AT25F512B-SSH

ATMEL AT25F512B chip is a 512 Kilobit SPI flash. The chip is used to store the configuration of the XHCI controller. It is not connected to the SoC, i.e. cannot be read or modified by the system.

CR2032 Battery

The system includes a 3V CR2032 battery to maintain the system clock when the NAS is not connected on AC power.

Serial interface / Console

Marvell SoC directly embbeds two UARTs. In the NAS, one is rooted up to the second daughter board and associated pins are directly available under a simple sticker at the rear of the device. Note that the serial port is a 3.3V one.

Front of second daughter board

With a multimeter, it's easy to detect which pin on the board is TX, RX, GND and 3.3V VCC:

3.3V-capable USB-serial dongle

Once you have a proper access to the console (i.e. TX and RX working), you can see U-boot loading and interrupt it (3 second timeslot) to get access to U-boot console:

         __  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: DB-88F6282A-BP LE 

U-Boot 1.1.4 (Feb  6 2012 - 14:40:46) Marvell version: 3.4.27
Netgear version: Uboot-1_1_4-NetgearDUOV3-V1008

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006D0120

Soc: MV88F1155 Rev 1 (DDR3)
CPU running @ 1600Mhz L2 running @ 533Mhz
SysClock = 533Mhz , TClock = 200Mhz 

DRAM unknown CAL  tRP = 8 tRAS = 20 tRCD=8
DRAM CS[0] base 0x00000000   size 256MB 
DRAM Total size 256MB  16bit width
Addresses 8M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M - 7M): Done
NAND:128 MB
Flash:  0 kB

CPU : Marvell Feroceon (Rev 1)

Streaming disabled 
Write allocate disabled


USB 0: host mode
PEX 0: PCI Express Root Complex Interface
PEX interface detected Link X1
Switch On !

Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  0 
Marvell>> 

Some additional random notes on serial/console:

Fairchild FDS 4435BZ

Local copy of Fairchild FDS 4435BZ datasheet. Local copy of Fairchild FDS 4435BZ datasheet.

Fairchild FDS 8984

Local copy of Fairchild FDS 8984 datasheet.

JTAG access ???

Marvell G47B

Richtek RT8105

Local copy of Richtek RT8105 datasheet.

Texas Instruments - TPS65251

Local copy of TPS 65251 datasheet.

LEDs and Buttons

Marvell Cryptograpic Engine and Security Accelerator (CESA)

Linux Kernel supports Marvell Cryptographic Engine and Security Accelerator (drivers/crypto/mv_cesa.{c,h}, commit 85a7f0ac). DT support has been recently added (see kirkwood.dtsi).

The hardware engine supports:

Nonetheless, at time of writing, current kernel code does not support DMA, and even thoug some initial discussions have taken place.

DMA/XOR engine

Marvell SoC such as Orion and Kirkwood support DMA XOR (and memcpy(), memset()) operations. Those can be useful to decrease CPU utilization in RAID setup. Here is the commit message associated with the introduction of the feature in Linux Kernel.

commit ff7b04796d9866327ea76e1393f1e902ef032f84
Author: Saeed Bishara <saeed@marvell.com>
Date:   Tue Jul 8 11:58:36 2008 -0700

    dmaengine: DMA engine driver for Marvell XOR engine
    
    The XOR engine found in Marvell's SoCs and system controllers
    provides XOR and DMA operation, iSCSI CRC32C calculation, memory
    initialization, and memory ECC error cleanup operation support.
    
    This driver implements the DMA engine API and supports the following
    capabilities:
    - memcpy
    - xor
    - memset
    
    The XOR engine can be used by DMA engine clients implemented in the
    kernel, one of those clients is the RAID module.  In that case, I
    observed 20% improvement in the raid5 write throughput, and 40%
    decrease in the CPU utilization when doing array construction, those
    results obtained on an 5182 running at 500Mhz.
    
    When enabling the NET DMA client, the performance decreased, so
    meanwhile it is recommended to keep this client off.
    
    Signed-off-by: Saeed Bishara <saeed@marvell.com>
    Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
    Signed-off-by: Nicolas Pitre <nico@marvell.com>
    Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
    Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Note that the feature is also available for DT-converted SoC, as kikwood.dtsi file now has the required definition (since commit c896ed0f)

Step by step kernel build

This section documents in details a step by step build and install of a 3.11 kernel on the ReadyNAS Duo v2. The steps should be similar for a more recent kernel version.

Cross-compilation toolchain

The first thing needed to compile the kernel is a cross-compilation toolchain. Assuming you are on Debian, you can just emdebian.org repositories to get the required packages:

root@small# cat > /etc/apt/sources.list.d/emdebian.sources.list
deb http://www.emdebian.org/debian unstable main
^D
root@small# apt-get update
root@small# apt-get install binutils-arm-linux-gnueabi \
                            gcc-4.7-arm-linux-gnueabi \
                            libgcc1-armel-cross \
                            linux-libc-dev-armel-cross

Kernel Build

Now that we have a compiler to create arm binaries, let's first grab our kernel.

arno@small$ wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.11.tar.gz 
arno@small$ wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.11.tar.sign 
arno@small$ gunzip linux-3.11.tar.gz 
arno@small$ gpg --verify linux-3.11.tar.sign 
gpg: Signature made Mon 02 Sep 2013 10:50:04 PM CEST using RSA key ID 00411886
gpg: Good signature from "Linus Torvalds <torvalds@linux-foundation.org>"
arno@small$ tar xf linux-3.11.tar 

Let's now configure it

arno@small$ cd linux-3.11 
arno@small$ wget http://natisbad.org/NAS/config-duov2-3.11 
arno@small$ mv config-duov2-3.11 .config 
arno@small$ export ARCH=arm
arno@small$ export CROSS_COMPILE=arm-linux-gnueabi-
arno@small$ make oldconfig
scripts/kconfig/conf --oldconfig Kconfig
#
# configuration written to .config
#
arno@small$ make menuconfig

Let's now build the kernel zImage, append it to our Netgear ReadyNAS Duo v2 .dtb (Device Tree Blob) generated from .dts (Device Tree Source) file and then make a uImage out of it. The resulting uImage is then copied to our tftp folder to be served to the NAS.

arno@small$ make -j 16
arno@small$ cat arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dtb >> arch/arm/boot/zImage 
arno@small$ make uImage 
arno@small$ sudo cp arch/arm/boot/uImage /srv/tftp/

Serial access to u-boot and system console

Details of serial console access is described in hardware section.

tftp setup to serve kernel image (and later Debian installer).

The best way to push required binaries (kernel images, debian installer) to the NAS is probably via tftp. This is done quite simply from your Debian host by installing openbsd-inetd and atftpd packages (I got issues with tftpd packages so I would suggest not to use it). If you have a firewall running on your host, you need to temporarily allow incoming connection on 69/udp.

arno@small$ sudo apt-get install openbsd-inetd atftpd
arno@small$ sudo /etc/init.d/openbsd-inetd restart
arno@small$ sudo iptables -A INPUT -i eth0 -p udp --dport 69 -j ACCEPT

Then, we get access to the console and then plug the power cord without powering the device. The following appears:

arno@small$ screen /dev/ttyUSB0 115200

         __  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: DB-88F6282A-BP LE 

U-Boot 1.1.4 (Feb  6 2012 - 14:40:46) Marvell version: 3.4.27
Netgear version: Uboot-1_1_4-NetgearDUOV3-V1008

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006D0120

Soc: MV88F1155 Rev 1 (DDR3)
CPU running @ 1600Mhz L2 running @ 533Mhz
SysClock = 533Mhz , TClock = 200Mhz 

DRAM unknown CAL  tRP = 8 tRAS = 20 tRCD=8
DRAM CS[0] base 0x00000000   size 256MB 
DRAM Total size 256MB  16bit width
Addresses 8M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M - 7M): Done
NAND:128 MB
Flash:  0 kB

CPU : Marvell Feroceon (Rev 1)

Streaming disabled 
Write allocate disabled


USB 0: host mode
PEX 0: PCI Express Root Complex Interface
PEX interface detected Link X1
Plug On and Power down, Please Switch On !

We can then power on the device. This will present a 3 seconds countdown which allow us to interrupt the boot process and access u-boot, simply by hitting a key. Let's do just that.

Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  0

Marvell>>

For the record, let's just print current u-boot environment

Marvell>> printenv
baudrate=115200
loads_echo=0
ipaddr=192.168.58.21
serverip=192.168.58.135
rootpath=/mnt/ARM_FS/
netmask=255.255.255.0
run_diag=no
console=console=ttyS0,115200
CASset=min
ethprime=egiga0
bootargs_root=root=/dev/nfs rw
bootargs_end=:::DB88FXX81:eth0:none
image_name=uImage
standalone=fsload 0x2000000 $(image_name);setenv bootargs $(console) root=/dev/mtdblock0 rw \
           ip=$(ipaddr):$(serverip)$(bootargs_end) $(mvPhoneConfig); bootm 0x2000000;
ethmtu=1500
mvPhoneConfig=mv_phone_config=dev0:fxs,dev1:fxs
mvNetConfig=mv_net_config=(00:11:88:0f:62:81,0:1:2:3),mtu=1500
usb0Mode=host
yuk_ethaddr=00:00:00:EE:51:81
nandEcc=1bit
netretry=no
rcvrip=169.254.100.100
loadaddr=0x02000000
autoload=no
ethaddr=2c:b0:5d:be:c8:d6
bootcmd=nand read.e 0x1200000 0x200000 0x600000;nand read.e 0x2000000 0x800000 0x1000000; \ 
        bootm 0x1200000 0x2000000
ethact=egiga0
arcNumber=4919
stdin=serial
stdout=serial
stderr=serial
mainlineLinux=yes
enaMonExt=no
enaCpuStream=no
enaWrAllo=no
pexMode=RC
disL2Cache=no
setL2CacheWT=yes
disL2Prefetch=yes
enaICPref=yes
enaDCPref=yes
sata_dma_mode=yes
netbsd_en=no
vxworks_en=no
bootdelay=3
disaMvPnp=no
enaAutoRecovery=yes
pcieTune=no
bootargs=console=ttyS0,115200 reason=normal mtdparts= <SNIP>... 
Environment size: 1794/131068 bytes

As you can see, the environment contains the expected address of the tftp server (serverip parameter) and the NAS IP address (ipaddr):

...

Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  0 
Marvell>> printenv
...
ipaddr=192.168.58.21
serverip=192.168.58.135
...

As you can see above, u-boot environment expects the tftp server to be available at IP address 192.168.58.135. Let's just configure that adress on our host:

arno@small# sudo ip addr add 192.168.58.135/24 dev eth0

Booting your first kernel

Let's now load kernel image we built (uImage) in memory at address 0x1200000

Marvell>> tftpboot 1200000 uImage
Using egiga0 device
TFTP from server 192.168.58.135; our IP address is 192.168.58.21
Filename 'uImage'.
Load address: 0x1200000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #
done
Bytes transferred = 3662635 (37e32b hex)

Now that we have our kernel uImage loaded in RAM at address 0x1200000, we can try and check if the kernel boots by issuing the following command:

Marvell>> set bootargs console=ttyS0,115200 earlyprintk
Marvell>> bootm 0x1200000

This should fail at some point (e.g. no root device) but this is a good test before proceding to the next section.

Step by step Debian install

Now that we have a kernel to boot on, this section documents in details a step by step install of a complete Debian. To start the install, you simply need to have a console access to the device and a way to pass the kernel and the Debian installer. As we previously did, we will use tftp. This could also be done via USB.

Booting kernel and Debian installer

Let's first grab a Debian armel installer image and put it atftpd folder, just as we previously did for our kernel image:

$ cd /tmp
$ BASE=http://ftp.fr.debian.org/debian/dists/squeeze
$ wget ${BASE}/main/installer-armel/current/images/kirkwood/netboot/marvell/guruplug/uInitrd
$ sudo cp uInitrd /srv/tftp/

Now (as we already did previously only for the kernel), let's load the kernel into memory ...

Marvell>> tftpboot 1200000 uImage
Using egiga0 device
TFTP from server 192.168.58.135; our IP address is 192.168.58.21
Filename 'uImage'.
Load address: 0x1200000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #
done
Bytes transferred = 3662635 (37e32b hex)

and the Debian installer a bit further at address 2000000:

Marvell>> tftpboot 2000000 uInitrd
Using egiga0 device
TFTP from server 192.168.58.135; our IP address is 192.168.58.21
Filename 'uInitrd'.
Load address: 0x2000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #####################################
done
Bytes transferred = 3181036 (3089ec hex)

Let's modify the bootargs variable to get some console feedback.

Marvell>> set bootargs console=ttyS0,115200 earlyprintk

Note that we do not save the environment before booting the kernel and Debian installer

Marvell>> bootm 0x1200000 0x2000000

You should now see the kernel boot information and then the debian installer. At that point, you should be at home at home and continue the system installation process as if you were on a common system.

Building an uInitramfs (required for large disk w/ GPT partitions)

Once Debian install is over, you can reboot the NAS and use the process above to boot again the kernel and the Debian installer. This time, the idea is to get up to the partition manager so that all your partitions (raid, lvm, ext4) are set up and mounted. By executing a shell, we will create an initramfs and then install the kernel and this initramfs (as a replacement of NETGEAR ones on the NAND flash). So, from the Debian installer shell you can remount your disk. Below the root system is on a lvm volume - /dev/mapper/vgr-lvr - but yours could be on something like /dev/sda1 if you did something simple:

root@hal# cd /
root@hal# mkdir tgt
root@hal# mount /dev/mapper/vgr-lvr /tgt
root@hal# cd tgt
root@hal# mount -o bind /proc proc/
root@hal# mount -o bind /dev proc/dev
root@hal# mount -o bind /dev/pts proc/dev/pts
root@hal# mount -o bind /sys proc/sys 
root@hal# chroot tgt /bin/bash

Let's install initramfs tools, build one ...

root@hal# apt-get install initramfs-tools
root@hal# mkinitramfs -o /tmp/initramfs-3.11 -r /dev/mapper/vgr-lvr -v 

... , and make it understandable by u-boot:

root@hal# sudo apt-get install uboot-mkimage
root@hal# mkimage -A arm -O linux -T ramdisk -C none -a 0x00000000 -e 0x00000000 \
                  -n initramfs -d /tmp/initramfs-3.11  /tmp/uInitramfs

Commiting changes (uImage and uInitramfs) to NAND

At that point, we can either copy our uImage and uInitramfs to the NAND flash of the device or copy them to a USB key or even install those on the disk. Note that this last option is only available if your disks are small enough to not require a GUID Partition Table (GPT) partition (i.e. less that 2TB). Otherwise, u-boot will not be able to access the content of an ext2 or fat partition on the disk. Regarding the uInitramfs, it is needed in our case because the kernel is unable to directly autodetect recent RAID partition (if metadata is not v0.90).

Let's document the NAND flash way (another way would be to do it from u-boot via nand write command). Flash layout is the following:

root@hal:~# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00180000 00020000 "u-boot"
mtd1: 001a0000 00020000 "u-boot-env"
mtd2: 00800000 00020000 "uImage"
mtd3: 01800000 00020000 "minirootfs"
mtd4: 06800000 00020000 "jffs2"

So, we have 8MB available for kernel (ours is less than 4MB) and 24MB for our initramfs, respectively in /dev/mtd2 and /dev/mtd3. Let's install the tools ...

root@hal# apt-get install mtd-utils

... and install uImage (the dd and sha256sum stuff is to verify that our nandwrite command worked as expected) ...

root@hal# flash_erase /dev/mtd2 0 0
root@hal# nandwrite -p /dev/mtd2 /boot/uImage
root@hal# dd if=/dev/mtd2 of=/tmp/o bs=`wc -c /boot/uImage | cut -d' ' -f1` count=1
1+0 records in
1+0 records out
3664035 bytes (3.7 MB) copied, 0.736338 s, 5.0 MB/s
root@hal# sha256sum /tmp/o /boot/uImage
2ac3393ded6de2d37e6441260e1498ccdb1836a71552481e87d4a90eb9f84a37  /tmp/o
2ac3393ded6de2d37e6441260e1498ccdb1836a71552481e87d4a90eb9f84a37  /boot/uImage

... and then install uInitramfs ...

root@hal# flash_erase /dev/mtd3 0 0
root@hal# nandwrite -p /dev/mtd3 /boot/uInitramfs
root@hal# dd if=/dev/mtd3 of=/tmp/o bs=`wc -c /boot/uInitramfs | cut -d' ' -f1` count=1
1+0 records in
1+0 records out
2768752 bytes (2.8 MB) copied, 0.596774 s, 4.6 MB/s
root@hal# sha256sum /tmp/o /boot/uInitramfs
cdeb51f851b3967868fd52f2642283756ee42757690ba9596fc7a9f35ea9ea37  /tmp/o
cdeb51f851b3967868fd52f2642283756ee42757690ba9596fc7a9f35ea9ea37  /boot/uInitramfs

Commiting changes to u-boot environment

We can now reboot and once again interrupt the boot process to access u-boot in order to setup a final environment. In our case, as we installed the uImage and uInitramfs, we only need to modify the bootargs variable and use savenev to write u-boot configuration to nand:

Marvell>> setenv bootargs root=/dev/mapper/vgr-lvr console=ttyS0,115200 earlyprintk rootdelay=10
Marvell>> saveenv
Marvell>> boot

If you decide to go the USB way or install the uImage and uInitrd, you will have to modify root parameter and potentially other elements.

Notes on PaX/grsec support

If you intend to use the NAS as a server, you will probably configure and run a grsec kernel on it and may be interested by additional details on the topic. Bottom line: the processor being an ARMv5, it does not provide NX support (available from ARMv6): this means that some useful protection mechanisms provided by grsec patch will not be available (e.g. MPROTECT).

I spent some time configuring and testing a PaX/grsec-enabled 3.7.6 kernel for the NAS and diffing what is lost compared the same kind of setup on x86_64 platform. Pipacs was kind enough to provide some answers on how ARM support may evolve i.e. explain which x86_64-available feature which are currently missing on ARM may be supported at some point. Bottom line: pax/grsec support on ARM is expected to progressively match the level of "features" available on x86/x86_64 but on an ARMv5TE-based device, NX-dependent protection mechanisms will never be available.

In more details:

Additionally, if you are interested by the topic, you should read Recent ARM security improvements article on Spender's blog.

Automatic fan control based on NAS temperature

After having installed fancontrol package ...

root@hal:/sys/bus/i2c# apt-get install fancontrol

... , you first need to run pwmconfig to create an initial configuration referencing the temperature sensor and the fan controller, and the various temperature and fan rotation limits. You will end up with a configuration file (/etc/fancontrol)like the following (stock 3.11 kernel):

root@hal:/sys/bus/i2c# cat /etc/fancontrol 
# Configuration file generated by pwmconfig, changes will be lost
INTERVAL=10
DEVPATH=hwmon0=devices/ocp.2/f1011000.i2c/i2c-0/0-003e hwmon1=
DEVNAME=hwmon0=g762 hwmon1=kirkwood_thermal
FCTEMPS= hwmon0/device/pwm1=hwmon1/temp1_input
FCFANS= hwmon0/device/pwm1=hwmon0/device/fan1_input
MINTEMP= hwmon0/device/pwm1=25
MAXTEMP= hwmon0/device/pwm1=45
MINSTART= hwmon0/device/pwm1=50
MINSTOP= hwmon0/device/pwm1=45
MAXPWM= hwmon0/device/pwm1=200

Obviously, you may change the configuration (e.g. modify MAXTEMP and/or MAXPWM values) based on your needs (noise vs SoC temperature).

As a side note, I do not go here into the details of the fan driving mode (PWM vs DC) and the fan speed control modes (manual i.e. open-loop and automatic i.e. closed-loop) the g762 fan controller supports. By default, Netgear's u-boot puts g762 driver in manual fan speed control (/sys/bus/i2c/drivers/g762/0-003e/pwm1_enable is set to 1) and DC mode (/sys/bus/i2c/drivers/g762/0-003e/pwm1_mode set to 0). Addditional information is available in kernel g762 documentation (Documentation/hwmon/g762).

Configuring custom actions for buttons

If you want to trigger custom actions using the power, backup and reset buttons, you can probably use this script as a basis.