Soho NAS Smardisk-Verbatim

De LagaSchiex.

Tentative de hack du NAS Smartdisk/Verbatim.

Il existe deux versions de ce NAS au moins. Une 250 Go et une 500 Go. C'est de la première variante (Rev. D, achetée 69€ chez LuxDisk) dont je dispose mais la seconde est vraisemblablement identique (hors du modèle de disque installé).

Ce NAS est équipé d'une CPU ARM/STORLINK FA52Xid(wb) utilisé dans de très nombreux NAS (D-LINK, NAS 2000...) pour lesquels des firmwares alternatifs existent. Qu'est il possible de faire ?

De base, le SOHONAS offre un noyau linux 2.6.10 avec 64 Mo de RAM. Il dispose de 8Mo de mémoire flash accessible via le driver mtd. D'un port USB 1.1, d'une if ethernet 100Mbps (deux en interne apparemment sont visibles) et peut aussi être directement utilisé via USB 2.0 (mais pas en même temps qu'ethernet ?).

Avec le firmware de base, le NAS permet

* un accès au disque et imprimante (USB 1.1) via SAMBA
* un accès NFS
* un accès FTP (proftpd)
* un accès telnet
* s'annonce via Bonjour (Avahi sous linux)
* peut faire serveur DHCP (pas franchement utile quand la moindre box ADSL le fait)

Mais, contrairement à ce que certaines documentations annoncent, ne fait pas fonction de serveur audio (DAAP) par exemple.

Apparemment, la mémoire flash est coupée en différentes zones:

dev:    size   erasesize  name
mtd0: 00040000 00010000 "RedBoot"
mtd1: 00180000 00010000 "Kernel"
mtd2: 00200000 00010000 "Ramdisk"
mtd3: 00400000 00010000 "Application"
mtd4: 00010000 00010000 "VCTL"
mtd5: 00020000 00010000 "CurConf"
mtd6: 00010000 00010000 "FIS directory"
* RedBoot (256 Ko = 262144o) est le Bootloader 
* Kernel (1.5 Mo = 1572864o) doit contenir le noyau linux
* Ramdisk (2 Mo = 2097152o) un initrd pour booter
* Application (4Mo = 4194304o) de quoi restaurer la partition de 100Mo du HD qui contient les applications
* VCTL: (64Ko = 65536 o) ?
* CurConf: (128Ko = 131072) la sauvegarde de la conf courante (qqs fichiers de /etc et rc.conf...)
* FIS directory: (64Ko = 65536 o) sans doute la configuration de la FLASH en zone.

Total: 8Mo.

Des sources, le firmware et des outils de développement sont disponibles chez Smartdisk [1]

Le firmware est une simple archive tar. Contenu:

-rw-r--r-- 1 tom tom 1,5K 2006-07-24 06:15 curconf.tgz
-rw-r--r-- 1 tom tom 3,8M 2006-07-24 06:15 hddapp.tgz
-rwxr--r-- 1 tom tom  343 2006-07-24 06:15 ImageInfo*
-rw-r--r-- 1 tom tom 1,8M 2006-07-24 06:15 rd.gz
-rwxr-xr-x 1 tom tom 1,5M 2006-07-24 06:15 zImage*

Il est vraisemblable que chacun des fichiers, hors ImageInfo, correspond à une des zones de la flash. Total: env 7Mo. A compléter avec RedBoot, VCTL et FIS.

Il est possible aussi de sauvegarder le firmware directement sur le NAS vis un simple "dd". Voir [2]. C'est fait !

-rw-r--r--    1 root     root       256.0k Dec 31 20:44 redboot.bin
-rw-r--r--    1 root     root        64.0k Dec 31 20:44 VCTL.bin
-rw-r--r--    1 root     root       128.0k Dec 31 20:45 curconf.tgz
-rw-r--r--    1 root     root         4.0M Dec 31 20:44 hddapp.tgz
-rw-r--r--    1 root     root        64.0k Dec 31 20:45 fid.dat
-rw-r--r--    1 root     root         1.5M Dec 31 20:44 zImage
-rw-r--r--    1 root     root         2.0M Dec 31 20:44 rd.gz

RedBoot est un bootloader assurant la possibilité de reflasher le NAS via une ligne série (interne, et en 3.3 V (CMOS)) ou, plus sympathiquement via un trivial FTP (TFTP). Tant que cette zone de la mémoire flash n'est pas touchée, le NAS est ressuscitable. Le site sur le NAS2000 est plein d'infos la dessus [3] et une documentation utilisayeur est dispo ici [4].

Par défaut, au boot du NAS, il est possible d'accéder a RedBoot pour reflasher le NAS via TFTP. L'accès se fait à une adresse IP par défaut (192.168.2.71, port 9000). Pour plus de détails, voir [5]. Allons-y !

...
Escape character is '^]'.
==> enter Ctrl+C to abort booting within 2 seconds ...... 
^C
                           Boot Menu
====================================================================
1: Start the Kernel Code
2: List Image
3: Delete Image
4: Create New Image
5: Command Line Interface
6: Set IP adderss
7: Setting MAC address

X:Upgrade Boot    Y:Upgrade Kernel    

=> Select: 

Le 1 active le boot du noyau.

Tentons un 2:

=> Select: 2

Name                   FLASH addr      Mem addr    Datalen     Entry point
RedBoot           0x70000000-7001FFFF  0x00000000  0x0001E7EC  0x00000000
FIS directory     0x707F0000-707FFFFF  0x707F0000  0x00000000  0x00000000
Kern              0x70040000-701AFFFF  0x01600000  0x001673B0  0x01600000
Ramdisk           0x701C0000-7038FFFF  0x00800000  0x001CA908  0x00800000
Application       0x703C0000-7078FFFF  0x00000000  0x003C8BE4  0x00000000
CurConf           0x707D0000-707DFFFF  0x00000000  0x000005F4  0x00000000
VCTL              0x707C0000-707CFFFF  0x00000000  0x00010000  0x00000000

On retrouve les zones de flash avec adresses, taille...

Il est possible de supprimer une zone avec 3, créer (écraser, redéfinir) une zone avec 4. Tentons un 5 (Command Line interface)

Start Redboot CLI
RedBoot> help
Display/switch console channel
   channel [-1|<channel number>]
Display (hex dump) a range of memory
   dump -b <location> [-l <length>] [-s] [-1|2|4]
Execute an image - with MMU off
   exec [-w timeout] [-b <load addr> [-l <length>]]
        [-r <ramdisk addr> [-s <ramdisk length>]]
        [-c "kernel command line"] [<entry_point>]
Manage FLASH images
   fis {cmds}
Execute code at a location
   go [-w <timeout>] [entry]
Help about help?
   help [<topic>]
Set/change IP addresses
   ip_address [-l <local_ip_address>] [-h <server_address>]
Load a file
   load [-r] [-v] [-h <host>] [-m <varies>] [-c <channel_number>] 
        [-b <base_address>] <file_name>
Network connectivity test
   ping [-v] [-n <count>] [-l <length>] [-t <timeout>] [-r <rate>]
        [-i <IP_addr>] -h <IP_addr>
Reset the system
   reset 
Display RedBoot version information
   version 
Display (hex dump) a range of memory
   x -b <location> [-l <length>] [-s] [-1|2|4]

RedBoot> version

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Storlink release, version S000.9016 - built 21:17:16, Apr  4 2006

Platform: Storlink Sword (ARM9) 
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

Use Internal PCI Clock 
Processor: SL3316a3
IDE0 Enable       
AHB Bus Clock:108MHz    Ratio:3/2
RAM: 0x00000000-0x04000000, 0x00049f80-0x03fef000 available
FLASH: 0x70000000 - 0x70800000, 135 blocks of 0x00010000 bytes each.

Il est possible de changer l'adresse IP utilisée par défaut par Redboot. J'ai mis la même adresse que le NAS une fois booté, compatible avec mon subnet pour éviter la nécessité de changer l'IP pour se connecter. Cela fonctionne.

Le but étant de remplacer telnet par SHH, d'ajouter daapd, commençons à jouer avec le firmware. Pour commencer, je récupère le firmware d'un autre NAS de la même famille: NAS 2000 de chez raidSonic. Il est disponible ici [6] (2_3_2_IB_2(20070309).tar.gz | MD5: f72d18d944d877eb1f3e91429cd9a50c).

Voyons voir le contenu:

-rwxr-xr-x 1 tom tom 1,5K 2007-03-09 12:34 curconf.tgz*
-rwxr-xr-x 1 tom tom 4,0M 2007-03-09 12:34 hddapp.tgz*
-rwxr-xr-x 1 tom tom  354 2007-03-09 12:34 ImageInfo*
-rw-r--r-- 1 tom tom 1,9M 2007-03-09 12:34 rd.gz
-rwxr-xr-x 1 tom tom 1,5M 2007-03-09 12:34 zImage*

La ressemblance avec le FW du sohonas smartdisk est frappante:

-rw-r--r-- 1 tom tom 1,5K 2006-07-24 06:15 curconf.tgz
-rw-r--r-- 1 tom tom 3,8M 2006-07-24 06:15 hddapp.tgz
-rwxr--r-- 1 tom tom  343 2006-07-24 06:15 ImageInfo*
-rw-r--r-- 1 tom tom 1,8M 2006-07-24 06:15 rd.gz
-rwxr-xr-x 1 tom tom 1,5M 2006-07-24 06:15 zImage*

Les applis et le ramdisk sont plus gros. En comparant, cela est du principalement à la présence de daapd et une version plus récente de proftpd (mais d'autres choses: raid1 possible, cela pourrait expliquer l'initrd plus gros et pas de telnet visible...).

Je décide de me lancer dasn un premier test: construction d'un firmware avec la version du serveur proftpd du NAS 2000. La différence en taille faible devrait permettre d'éviter d'avoir à redimensionner les images flash.

# je détarre les deux firmwares: 
#* tar xvfz 2_3_2_IB_220070309.tar.gz
#* tar xvfz SOHONAS_v2_3_2_03b.tar.gz
# je détarre les hdapp.tgz (attention, c'est du bz2)
#* cd 2_3_2_IB_220070309; tar xvfj  hddapp.tgz
#* cd ../SOHONAS_v2_3_2_03b; tar xvfj  hddapp.tgz

Je copie le proftpd du NAS2000 dans le directory du SOHONAS, je vire au passage les traduction non françaises et anglaises (dans webroot/locale/) et je personnalise 2 images du site web du SOHONAS dans webroot/image/.

Je refait un tar, compression bzip2:

* tar cvfj ../hddapp.tgz hddapp/ lib/ sausalito/ webroot/

Verdict: hddapp.tgz fait 4010449 octets, soit moins que 4Mo = 4194304 octets. Ca devrait passer.

Deux façons de procéder pour la suite:

# refaire le tar complet du firmware  via l'interface web. : 25 minutes d'attente
# flasher en passant par redboot.

On va tenter le seconde approche. Il faut installer un serveur TFTP. Sous mon ubuntu, j'installe tftpd-hpa. Je copie hddapp.tgz dans /var/lib/tftpboot, je relance RedBoot.

=> Select: 4

Image Name: Application
Flash Address: 0x703C0000
Memory Address: 0x00000000
Entry Point: 0x00000000
An image named 'Application' exists - continue (y/n)? y
1: Download by X-modem 
2: Download by TFTP 
2
TFTP Server IP Address: 192.168.0.1
Image Path and name(EX. /images/zImage): hddapp.tgz
Waiting to receive file  ....
|

J'ai utilisé les mêmes adresses que dans la liste des images précédentes. Le caractère | tourne doucement en / \...le temps passe. Le caractère |\/ ne tourne plus... Le temps passe... En train de flasher ? Pas causante la bête. Quelques minutes plus atrd:

Raw file loaded 0x01000000-0x013d31d0, assumed entry at 0x01000000
Erase flash ...
... Erase from 0x703c0000-0x707a0000: ..............................................................
OK!
... Program from 0x01000000-0x013d31d1 at 0x703c0000: ..............................................................
OK!
Update FIS ...
... Erase from 0x707f0000-0x70800000: .
... Program from 0x00400000-0x00410000 at 0x707f0000: .
OK!
Upload 'Application' code successfully!

Ouf ! Tentons maintenant de rebooter (item 1 du menu de RedBoot). C'est parti ! Tentons un FTP:

ftp sohonas
Connected to sohonas.
220 ProFTPD 1.3.0 Server (NAS FTPD) [192.168.0.9]

Cela fonctionne. Le serveur 1.2.10 a été remplacé par un 1.3.0.

Les travaux sur le NAS2000 sont très avancés et un firmware alternatif appelé tinky a été développé [7]. Un premier pas serait de customiser l'image flash tinky.

Je pars de tinkyy-2_3_2-mu-02.2 [8]. Après extraction de l'archive, on obtient:

-rw-r--r-- 1 tom tom 4,2M 2007-05-07 22:20 Application
-rw-r--r-- 1 tom tom   46 2007-05-07 22:21 Application.md5
-rw-r--r-- 1 tom tom 2,2K 2007-05-07 21:12 Changelog
-rw-r--r-- 1 tom tom 2,0M 2007-05-07 22:20 Ramdisk
-rw-r--r-- 1 tom tom   42 2007-05-07 22:21 Ramdisk.md5
-rw-r--r-- 1 tom tom  13K 2007-05-07 21:09 README
-rw-r--r-- 1 tom tom 8,0M 2007-05-07 22:20 tinky-2_3_2-mu-02.2
-rw-r--r-- 1 tom tom   54 2007-05-07 22:21 tinky-2_3_2-mu-02.2.md5

Il me semble hasardeux de directement flasher tinky-2_3_2-mu-02.2 qui contient visiblement une image flash complète car cela écraserait le RedBoot du SOHONAS avec celui du NAS2000, sans garantie de compatibilité (même si les probabilités sont fortes que cela fonctionne, car la plateforme matérielle sous jacente est très similaire, à base de chipset Storlink type "Centroid" [9].

Le problème de tinky est que le layout de la flash est évidemment modifié puisque la zone "Applications" fait 4.2 Mo (qui ne tiennent pas dans 4mo).

Il faudrait donc revoir le "layout" actuel pour faire un peu de place. En observant le layout courant, il y a pas mal de place perdue:

RedBoot           0x70000000-7001FFFF  0x0001E7EC	20000
           20000 octets perdus
Kern              0x70040000-701AFFFF  0x001673B0	170000
	   10000 perdus
Ramdisk           0x701C0000-7038FFFF  0x001CA908	1D0000
           30000 perdus
Application       0x703C0000-7078FFFF  0x003C8BE4	3D0000
	   30000 perdus
VCTL              0x707C0000-707CFFFF  0x00010000	10000
		  
CurConf           0x707D0000-707DFFFF  0x000005F4	10000
	    10000 perdus
FIS directory     0x707F0000-707FFFFF  0x00000000	10000

Soit un total de A0000 octest perdus (640 Ko). Les codes étant copiés en RAM avant d'être exécutés (modèle ROMRAM indiqué dans la version de RedBoot), pas de question de Position Independant Code (PIC). Esperons que le nom des images donne le point d'accès.

Je tente de déplacer le Kernel pour le coller à "RedBoot". On va le mettre entre 0x70020000-7018FFFF (au lieu de 0x70040000-701AFFFF).

On se reconnecte à RedBoot, j'efface l'image Kern, je recrée l'image en la déplaçant (et en utilisant le fichier zImage du firmware original récupérée par TFTP). Résultat du layout:

Name                   FLASH addr      Mem addr    Datalen     Entry point
RedBoot           0x70000000-7001FFFF  0x00000000  0x0001E7EC  0x00000000
FIS directory     0x707F0000-707FFFFF  0x707F0000  0x00000000  0x00000000
Kern              0x70020000-7018FFFF  0x01600000  0x001673B0  0x01600000
Ramdisk           0x701C0000-7038FFFF  0x00800000  0x001CA908  0x00800000
Application       0x703C0000-7079FFFF  0x00000000  0x003D31D1  0x00000000
CurConf           0x707D0000-707DFFFF  0x00000000  0x000005F4  0x00000000
VCTL              0x707C0000-707CFFFF  0x00000000  0x00010000  0x00000000

On reboote... Ca marche toujours. Je vais déplacer le ramdisk en 0x70190000. Panique... J'ai oublié le 0x devant l'adresse hexa.

=> Select: 4

Image Name: Ramdisk
Flash Address: 70190000
Memory Address: 0x00800000
Entry Point: 0x00800000
1: Download by X-modem 
2: Download by TFTP 
2
TFTP Server IP Address: 192.168.0.1
Image Path and name(EX. /images/zImage): rd.gz
Waiting to receive file  ....
-
Raw file loaded 0x01000000-0x011ca907, assumed entry at 0x01000000
Erase flash ...
... Erase from 0x042f0000-0x044c03b0: 
FAILED!
Can't erase region at 0x042f0000: Driver timed out waiting for device
OK!
... Program from 0x01000000-0x011ca908 at 0x042f03b0: .............................
OK!
Update FIS ...
... Erase from 0x707f0000-0x70800000: .
... Program from 0x00400000-0x00410000 at 0x707f0000: .
OK!
Upload '<Not a string: 0x400300>' code successfully!

Plus rien ne fonctionne. La liste des images est cassée. Peut-être RedBoot aussi. Je vais tenter d'éviter la brique en reflashant tout le firmware (que j'avais sauvegardé, ouf !). Ca va être long.

=> Select: X

1: Download by X-modem 
2: Download by TFTP 
2
TFTP Server IP Address: 192.168.0.1
Image Path and name(EX. /images/zImage): firmware.save
Waiting to receive file  ....
\
Raw file loaded 0x01000000-0x017fffff, assumed entry at 0x01000000
image not found !! Creating ...

Do not power-off this device while flash programming is proceeding!!
Are you sure to program Boot code (Y/N) ?

Damned. Ce message "image not found !!" n'est pas rassurant. Tant pis... let's go !

Erase flash ...
... Erase from 0x70000000-0x70800000: ................................................................................................................................
OK!
... Program from 0x01000000-0x01800000 at 0x70000000: ................................................................................................................................
OK!
Update FIS ...
Upgrade Boot Code successful!

Cela semble fonctionner ! Me revoila parti avec le layout d'origine, et le vieux ProFTPD. Je recommence... Déplacement du noyau...Fait. Déplacement du Ramdisk...(adresse en hexa 0x70190000 !). Fait. On déplace Application. Comme il faut 0x200000 pour le Ramdisk de tinky, je vais mettre Applications en 0x70190000+0x200000 = 0x70390000. C'est parti... Je déplace CurConf contre FIS directory (en 0x707E0000). Il faut enfin déplacer VCTL contre CurConf (en 0x707D0000). Layout obtenu:

Name                   FLASH addr      Mem addr    Datalen     Entry point
RedBoot           0x70000000-7001FFFF  0x00000000  0x0001E7EC  0x00000000
Kern              0x70020000-7018FFFF  0x01600000  0x001673B0  0x01600000
Ramdisk           0x70190000-7035FFFF  0x00800000  0x001CA908  0x00800000
Application       0x70390000-7076FFFF  0x00000000  0x003D31D1  0x00000000
VCTL              0x707D0000-707DFFFF  0x00000000  0x00010000  0x00000000
CurConf           0x707E0000-707EFFFF  0x00000000  0x000005F4  0x00000000
FIS directory     0x707F0000-707FFFFF  0x707F0000  0x00000000  0x00000000

Malheureusement, le Sohonas n'achève pas son démarrage. Le site web n'est pas nourri des fichiers idoines ce qui laisse penser que le déplacement de Application n'est pas "transparent". La lecture de Applications doit s'effectuer depuis un script du initrd (Ramdisk).

Pour examiner le ramdisk du firmware d'origine:

mkdir InitRd
gunzip rd.gz
sudo mount -o loop rd InitRd/   

Un examen du script de démarrage "rc.start" montre que la partition Flash est lue depuis le /dev/mtd "Applications". Malheureusement, Les adresses des mtd (cat /proc/mtd) n'ont pas changé. Elles doivent être en dur dans le noyau.

Partons donc à la chasse dans les sources du noyau, gentiment fournies par SmartDisk [10].

On trouve ces sources dans "RD669_V2_3_2/source/kernel". Le driver MTD est dans "linux/drivers/mtd". Dans le directory "maps", le fichier "sl2312_flashmap.h" contient:

// --> Vic.Tsai 24/02/06 14:48:17
// Added structure for 256k bootloader

// 256K Bootloader
static struct mtd_partition sl2312_partitions[] = {
	{ name: "RedBoot", offset: 0x00000000, size: 0x00040000, },
	{ name: "Kernel",  offset: 0x00040000,  size: 0x00180000, },
	{ name: "Ramdisk", offset: 0x001C0000, size: 0x00200000, },
	{ name: "Application", offset: 0x003C0000, size: 0x00400000, },
	{ name: "VCTL", offset: 0x007C0000, size: 0x10000, },
	{ name: "CurConf", offset: 0x007D0000, size: 0x20000, },
	{ name: "FIS directory", offset: 0x007F0000, size: 0x00010000, }
};

// <-- Vic.Tsai 24/02/06 14:48:32

Le layout vu par Linux n'est donc pas lu dans la flash, mais cablé en dur. Une zImage étant très pénible à décortiquer, le plus simple (sic !) serait de recompiler un noyau. Avant de se lancer dans cette avnture (cross-compilation...), je vais tenter une chose simple: greffer le redboot de SmartLink sur l'image Flash de NAS2000. Serait il possible que le noyau NAS2000 tourne sous le Smartlink ? La greffe se fait en ajoutant les 128 premiers Ko de la sauvegarde redboot à la flash de tinky, amputée de ses 128 premiers Ko. Après le flashage, le NAS démarre et...s'éteint aussitôt. Flippant ?

Redémarrage par RedBoot et on reflash le firmware de sauvegarde. Et ça redémarre sans problème.

Lançons nous donc dans la compilation d'un noyau-sohonas !

Outils personnels