Le RaspberryPi nécessite 2 partitions et les OS sont généralement founis en .img

J’avais besoin de comparer certains fichiers entre mon installation Rasbian et la distribution Raspbmc.

Je télécharge donc raspbmc-final.img sur mon laptop puis:

$ mkdir mount  
$ sudo fdisk -l raspbmc-final.img   

Disk raspbmc-final.img: 1363 MB, 1363148800 bytes  
4 heads, 32 sectors/track, 20800 cylinders, total 2662400 sectors  
Units = sectors of 1 * 512 = 512 bytes  
Sector size (logical/physical): 512 bytes / 512 bytes  
I/O size (minimum/optimal): 512 bytes / 512 bytes  
Disk identifier: 0x000d692e  

Device Boot Start End Blocks Id System  
raspbmc-final.img1 4096 147455 71680 c W95 FAT32 (LBA)  
raspbmc-final.img2 151552 2662399 1255424 83 Linux  

Si on veut monter la 1ère partition qui démarre au sector 4096, l'offset à utiliser est donc 512x4096=2097152

$ sudo mount -o loop,offset=2097152 raspbmc-final.img mount/  
$ cat mount/cmdline.txt   
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 noatime quiet rootwait loglevel=1 zram.num_devices=2  
$ sudo umount mount/

Si on veut monter la 2ème partition qui démarre au sector 151552, l’offset à utiliser est donc 512x151552=77594624

$ sudo mount -o loop,offset=77594624 raspbmc-final.img mount/  
$ cat mount/etc/hostname   
raspbmc  
$ sudo umount mount/  

man fdisk  
 [...] starting offset and the size of each partition is stored in two ways: as an absolute number of sectors [...]
 
man mount  
 [...] mount knows about four options, namely loop, *offset*, sizelimit and encryption  [...]

[Edit:] Tassatux m’indique dans le commentaires que kpartx est créé à cet effet:

This tool, derived from util-linux' partx, reads partition tables on specified device and create device maps over partitions segments detected. It is called from hotplug upon device maps creation and deletion.

Voir les commentaires pour les informations supplémentaires.

Comme indiqué dans le très bon article de Framboise314, il est interressant, compte tenu de la fiabilité limité des carte SD en écriture, et compte tenu des vitesses d’accès, de placer le système de fichier sur une clé ou disque dur USB.

Les opérations décrites ci-dessous sont différentes de celles de l’article de Framboise314 (mais le but reste le même).

Les principales différences (qui justifient donc un peu ce post) sont:

  • Opérations effectuées à partir d’un autre poste GnuLinux (et non depuis le Rasp)
  • Opérations comprenant l’installation depuis le fichier .img
  • Opérations effectuées en terminal (pas besoin de X, pourrait être scripté, etc.. )
  • Pas de copie carte SD -> clé USB (mais .img -> clé USB et .img -> carte SD donc probablement plus rapide ?)
  • Utilisation de UUID pour le fstab afin de pouvoir utiliser d’autres disques USB.
  • Utilisation d’une clé USB qui n’est pas encore ni partitionée ni formatée.
  • L’opération sur la clé USB intervient dans la foulée de l’installation sur la carte SD (pas de déplacement de données perso)

On part du principe que la clé USB est vue sur le PC qui prépare, en /dev/sdb. (/dev/sda étant généralement le disque dur du PC).

Les commandes suivante ne sont PAS a effectuer sur le Rasp (car il n’est pas encore installé ..vous me suivez ? ).

/!\ On joue avec dd, avec la table des partitions etc.. Donc n’utilisez les commandes suivantes que si vous les comprenez…

  • Lister les partitions
sudo fdisk -l
  • Démonter les éventuelles partitions existantes qui se seraient montées automatiquement en insérant la carte SD et la clé USB.
umount /dev/mmcblk0p1 && umount /dev/mmcblk0p2  
umount /dev/sdb1 && umount /dev/sdb2
  • On claque les 100 premiers Mio du .img sur la carte SD (à priori seuls les 57 premiers Mio devraient suffir)
sudo dd if=/data/RaspberryPi/2013-02-09-wheezy-raspbian.img of=/dev/mmcblk0 bs=1M count=100 && sudo sync
  • On claque le .img sur la clé USB. On utilise pv pour visualiser l’avancement.
sudo dd if=/data/RaspberryPi/2013-02-09-wheezy-raspbian.img | pv -tpreb | sudo dd of=/dev/sdb bs=4M && sudo sync
  • On modifie le fichier cmdline.txt
mkdir /tmp/toto
sudo mount /dev/mmcblk0p1 /tmp/toto
sudo vi /tmp/toto/cmdline.txt
    root=/dev/sda2  
sudo umount /dev/mmcblk0p1

C’est bien sda2 qui est utilisé car 2ème partition du premier “disque” du Rasp… et je n’ai pas trouvé à la date de rédaction de ce post de moyen de forcer ce paramètre en utilisant UUID (mais si quelqu’un à trouvé un moyen qui fonctionne, qu’il laisse un commentaire et sinon j’imagine que ceci pourra changer par un upgrade d’un futur firmware )

  • On détermine le UUID de sdb2 (pour le fstab)
sudo partprobe /dev/sdb 
sudo blkid | grep sdb2
  • On modifie le fichier fstab
sudo mount /dev/sdb2 /tmp/toto 
sudo vi /tmp/toto/etc/fstab
  /dev/mmcblk0p1 /boot vfat defaults,ro 0 0  
 UUID=XXXXXXXX-AAAA-BBBB-CCCC-YYYYYYYYYYYY / ext4 defaults,noatime 0 0
sudo umount /dev/sdb2

/dev/mmcblk0p1 est donc en ReadOnly (ro) et /dev/sda2 est remplacé par l’UUID correspondant.

Ceci permet d’identifier avec certitude le bon disque USB dans le cas où plusieurs sont branchés.

Attention a renlever le ReadOnly dans certains cas (Upgrade du firmware - rpi-update / Modif memory_split et donc globalement tout ce qui fait des modifs dans /boot… )

La parition sdb2 ne fait qu’une partie de la taille totale de la clé USB car crée par dd et le .img Il faut donc l’agrandir.

  • Lister les partitions et afficher leur taille de manière lisible
sudo parted -l
  • Augmentation de la taille de la partition sdb2

    On va supprimer la référence dans la table des partitions puis la recréer avec la taille totale.

sudo fdisk /dev/sdb

Puis utiliser “p” pour noter le point de départ de la seconde partition (Avec la version actuelle de Raspbian et d’Occidentalis c’est 122880)

Command (m for help): d  
Partition number (1-4): 2  
Command (m for help): n  
Select (default p): p  
Partition number (1-4, default 2):   
First sector (2048-15663103, default 2048): 122880  
Last sector, +sectors or +size{K,M,G} (122880-15663103, default 15663103):   
Using default value 15663103  
Command (m for help): p  
Command (m for help): w  

sudo parted -l doit maintenant lister une taille de partition sdb2 prenant la taille quasi totale de la clé USB.

  • Augmentation de la taille du système de fichier EXT4
sudo e2fsck -f /dev/sdb2
sudo resize2fs /dev/sdb2

A noter qu’on peut également ensuite avec parted supprimer les 2 partitions inutiles:

/dev/mmcblk0p2 (de toute façon on n’utilise pas l’espace additionnel de la SD)
/dev/sdb1 (on pert 57 Mio)

Procédure testée plusieurs fois sur des clés USB différentes, des cartes SD différentes, avec des images différentes (Rasbian/Occidentalis).

Pour prendre la main sur le Rasp sans clavier/souris/écran/réseau, il est possible d’utiliser le port série disponible sur les GPIO.

Un tutorial en anglais est disponible sur l’excellent Adrafruit

Si le prix du cable/convertisseur Adafruit vous semble réberbatif ($10 ou 12€ chez les revendeurs français et sans les frais de ports ), sachez que j’ai pu tester avec succès les 2 “cables/convertisseurs” suivants.

1,37 EUR (Port inclu!)

3,81 EUR les 2 (Port inclu!)

L’un des mots clé semble donc bien être “PL2303” pour chercher d’autres vendeurs.

Sous Gnu/Linux, rien de spécial à installer comme soft/driver (contrairement aux OS privateurs à priori)…

La console du Rasp est ensuite accessible par la commande:

sudo screen /dev/ttyUSB0 115200

Les tests ont étés réalisés avec dd sur RaspberryPi.

Pour l’écriture, on “lit” depuis /dev/zero ce qui fait que la vitesse de lecture n’est pas un frein.

dd if=/dev/zero bs=xxxx count=yyyy of=file_1GB

Pour la lecture, on “écrit"vers /dev/null ce qui fait que la vitesse d’écriture n’est pas un frein.

dd if=file_1GB of=/dev/null bs=xxxx

Les tests ont été réalisés en jouant avec un fichier d’une taille de 1 Gio mais avec différentes valeurs de bs.

La taille à priori optimale de bs est déterminée en utilisant la commande:

stat -c "%o" file_1GB

D’autres commandes peuvent être utile pour déterminer bs

fdisk -l /dev/sda1 | grep "I/O size"
dumpe2fs /dev/sda1 | grep -i "Block size"

A titre d’information, il semblerait que la commande cp utiliserait un bs de 4096 octets.

Les tests ont étés réalisés sans une utilisation parallèle du bus USB (pas d’autre périphérique sur les ports USB, utilisation ethernet limitée aux commandes passées en SSH )

  • Clé USB Corsair EXT4

    • bs=4096
      Écriture: 29.2 MB/s
      Lecture: 27.1 MB/s

    • bs=1024 Écriture: 15.5 MB/s
      Lecture: 21.7 MB/s

  • Clé USB Corsair FAT32

    • bs=16384
      Écriture: 20.7 MB/s
      Lecture: 26.0 MB/s
    • bs=4096
      Écriture: 20.1 MB/s
      Lecture: 26.9 MB/s
  • Disque Dur USB FAT32

    • bs=4096
      Écriture: 21.3 MB/s
      Lecture: 25.1 MB/s
    • bs=32768
      Écriture: 21.6 MB/s
      Lecture: 24.7 MB/s
  • Disque Dur USB EXT4

    • bs=4096
      Écriture: 31.1 MB/s
      Lecture: 24.0 MB/s

Ne me demandez pas pourquoi la vitesse d’écriture est parfois supérieure à la vitesse de lecture.

Ayant fait l’acquisition d’un compteur d’énergie, je me suis livré à quelques mesures avec le Rasp (modèle B) ( 800 Mhz - cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq ) et quelques accessoires.

  • Rasp - Raspbmc écran d’acceuil XBMC: ~ 3.1 W

  • Rasp - Rascpbmc lecture vidéo Youtube: ~ 3.3 W

  • Rasp - Raspbian sans rien faire: ~3.0W

  • Rasp - Raspbian pendant apt-get upgrade: ~3.6W

  • Hub USB alimenté +Rasp (alimenté par le hub) + ports USB reliés entre eux (ce qui change la conso): ~ 4.0W

  • Hub USB alimenté: ~0.9W

  • Hub USB alimenté +Rasp (alimenté par le hub) + clé USB: ~ 4.2W

  • Clé USB: ~ 0.2W

  • Hub alimenté +Rasp (alimenté par le hub)+ clé USB + disque dur USB 2.5" (pas SSD): ~6.1W

  • Disque dur USB 2.5" (pas SSD): ~ 1.9W

D’après la page des tarifs EDF, un Rasp (4W) allumé 24/24 (en abonnement heures pleines/creuses) coûte donc 4,36€ d’électricité par an.