md
Créer une image personnalisée de Raspbian
Dernière mise à jour : 2019-06-20, Première version : 2019-01-24
<-Updating Raspbian to Stretch Creating a Custom Armbian Image->

Dernièrement, j'expérimente beaucoup avec la nouvelle version de Raspbian Stretch Lite, essayant différentes configurations et logiciels. Pour vérifier que tout fonctionne, je préfère revenir au système d'exploitation tel qu'obtenu de la Fondation Raspberry. Chaque fois que l'image est copiée sur la carte SD, il faut modifier la partition /boot pour pouvoir démarrer le Raspberry Pi sans clavier ni moniteur. Puis il faut mettre à jour le système d'exploitation. Tout ceci prend du temps. Alors j'ai décidé de créer une image binaire qui permet d'éviter ces étapes.

Dans ce qui suit il est question d'un ordinateur de bureau sont le système d'exploitation est Linux. Évidemment, ce pourrait être un second Raspberry Pi sur lequel Raspbian complet est installé. On peut peut-être réaliser ce qui suit avec un seul Raspberry Pi si l'on a un lecteur de carte (micro) SD connecté par USB et deux cartes SD, l'une pour Raspbian complet et l'une qui doit contenir l'image personnalisée de Raspbian Stretch Lite.

Table des matières

  1. Copier Stretch sur une carte SD
  2. Configuration étêtée
  3. Empêcher l'expansion automatique du système de fichiers
  4. Mise à jour de Stretch
  5. Sauvegarder l'image modifiée
  6. Accroître la taille de la partition root
  7. Utilisation

Copier Stretch sur une carte SD toc

Comme auparavant, j'ai téléchargé la plus récente version Lite de Raspbian :

  Raspbian Stretch Lite
  Minimal image based on Debian Stretch
  Version: April 2019
  Release date: 2019-04-08
  Kernel version: 4.14

On la trouve à l'URL suivante : https://www.raspberrypi.org/downloads/raspbian/. J'ai suivi les instructions Installing operating system images pour copier l'image vers une carte micro-SD en utilisant le logiciel Balena Etcher.

Configuration étêtée toc

Pour pouvoir démarrer le Raspberry Pi sans y brancher un moniteur et un clavier il faut autoriser les sessions ssh. De plus, s'il faut passer par une connexion sans fil, alors les coordonnées du réseau Wi-Fi doivent être consignées dans l'image. Cela implique des modifications à des fichiers de la partition boot ce que l'on peut faire avec tout ordinateur de bureau car la partition utilise le format FAT32 reconnu par Linux, Windows et probablement Mac OS X.

  1. Activer ssh. On active les sessions ssh en créant un fichier nommé ssh dans la partition boot qu'importe sa taille et son contenu. Il peut donc être vide.
    michel@hp:~$ cd /media/michel/boot michel@hp:/media/michel/boot$ touch ssh michel@hp:/media/michel/boot$ ls -l ssh just checking -rw-r--r-- 1 michel michel 0 jan 3 11:04 ssh
  2. Créez le fichier de configuration wpa_supplicant avec les informations d'identification Wi-Fi. J'ai utilisé nano à partir de la ligne de commande, mais tout éditeur de texte tel comme Geany pourrait sans doute être utilisé. Le fichier, wpa_supplicant.conf, va dans la partition boot à côté du fichier ssh créé à l’étape précédente. Il faut bien sûr ajuster les informations d'identification du réseau.
    michel@hp:/media/michel/boot$ nano wpa_supplicant.conf
    country=ca <<-- 2 code de lettres identifiant le pays update_config=1 ctrl_interface=/var/run/wpa_supplicant network={ scan_ssid=1 ssid="wifi_network_name" psk="wifi_password" }

    Le nom du réseau et le mot de passe doivent être entre guillemets ("). Il donc recommandé de ne pas utiliser ce caractère dans ces termes.

Empêcher l'expansion automatique du système de fichiers toc

L'image de Raspbian occupe environ 1,7Gio quand elle est copiée sur la carte SD qu'importe la taille de cette dernière. Au premier démarrage, la taille du système de fichier sera modifiée automatiquement pour qu'il occupe tout l'espace libre sur la carte SD. Normalement, cela est désirable, mais ce n'est pas le cas ici. En effet, on ne veut pas copier 8, 16 ou Gio avec Etcher alors que moins de 2 Gio suffit. Si l'on possède un ordinateur pouvant lire les partitions de type ext4 utilisées par Linux alors on peut bloquer cette expansion automatique.

  1. Modifier le fichier cmdline.txt. Avec nano ou un éditeur de texte il faut enlever init=/usr/lib/raspi-config/init_resize.sh qui est à la fin de la seule très longue ligne du fichier. Ainsi le script qui redimensionne la partition root ne sera pas exécuté.
  2. Éliminer le script resizefs_once. Ce script se trouve dans le répertoire /etc/init.d de la partition root qui est nommée rootfs. Il déclenche l'expansion du système de fichier. J'ai préféré renommer le script.
    michel@hp:/media/michel/boot$ cd ../rootfs/etc/init.d michel@hp:/media/michel/rootfs/etc/init.d$ sudo mv resize2fs_once resize2fs_bak michel@hp:/media/michel/rootfs/etc/init.d$ ls -l resize* vérification -rwxr-xr-x 1 root root 560 nov 13 09:21 resize2fs_once_bak
  3. Éliminer le lien symbolique vers resizefs_once. Le lien se nomme S01resizefs_once et se trouve dans le répertoire /etc/rc3.d/. Encore une fois, j'ai préféré renommer plutôt qu'effacer le fichier.
    michel@hp:/media/michel/rootfs/etc/init.d$ cd ../rc3.d michel@hp:/media/michel/rootfs/etc/rc3.d$ sudo mv S01resize2fs_once S01resize2fs_once_bak michel@hp:/media/michel/rootfs/etc/rc3.d$ ls -l S01resiz* vérification lrwxrwxrwx 1 root root 24 avr 8 06:58 S01resize2fs_once_bak -> ../init.d/resize2fs_once

La référence pour tout ceci est la réponse de goldilocks à la la question Temporarily disable expand filesystem during first boot dans le forum consacré au Raspberry Pi sur StackExchange.

Mise à jour de Stretch toc

Après avoir éjecté correctement la carte SD de l'ordinateur de bureau, de l'avoir inséré dans le lecteur du Raspberry Pi, d'avoir allumé son alimentation et avoir attendu un certain temps jusqu'à l'arrêt de l'activité de la DEL verte, il était possible d'ouvrir une session ssh. Il faut s'attendre aux plaintes habituelles du client ssh parce que la clé de sécurité du serveur ssh du Raspberry Pi sera différente à chaque installation du système d'exploitation. Il se peut qu'il y ait un second avertissement, car le router affecte la même adresse IP au Raspberry Pi basée sur son adresse MAC à chaque démarrage du système mono-carte. Donc, ssh note le changement de clé pour l'adresse IP et pour le nom d'hôte.

michel@hp:~$ ssh pi@raspberrypi.local @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! ... michel@hp:~$ ssh-keygen -f "/home/michel/.ssh/known_hosts" -R "raspberrypi.local" ... michel@hp:~$ ssh pi@raspberrypi.local The authenticity of host 'raspberrypi.local (192.168.1.18)' can't be established. ... Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'raspberrypi.local' (ECDSA) to the list of known hosts. Warning: the ECDSA host key for 'raspberrypi.local' differs from the key for the IP address '192.168.1.18' Offending key for IP in /home/michel/.ssh/known_hosts:12 Are you sure you want to continue connecting (yes/no)? yes pi@raspberrypi.local's password: raspberry not echoed Linux raspberrypi 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l ... The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. SSH is enabled and the default password for the 'pi' user has not been changed. This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

Comme suggéré, j'ai modifié le mot de passe. Il me faut admettre que j'utilise le même mot de passe pour toutes ces installations temporaires du système d'exploitation, quitte à le remplacer plus tard avec quelque chose d'unique advenant que le système d'exploitation n'aura plus à être modifiée. On peut négliger cette étape, mais il me semble plus sur de ne pas conserver raspberry comme mot de passe puisqu'il est connu de tous. Cela est fait avec l'utilitaire raspi-config, option Change User Password.

pi@raspberrypi:~ $ sudo raspi-config

J'ai aussi utilisé l'utilitaire pour

  1. modifier la zone horaire (Localisation Options/Change Timezone),
  2. pour réduire la mémoire affectée au processeur graphique au minimum: 16 Mio (Advanced Options/Memory Split).

Fort probablement que le Raspberry Pi sera redémarré. Après avoir créé une nouvelle session ssh, il est recommandé de faire la mise à jour de Raspbian.

pi@raspberrypi:~ $ sudo apt-get update && sudo apt-get -y upgrade

La dernière opération peut prendre un certain temps, car le 20 juin il y avait déjà 27 paquets à mettre mis à jour qui demandaient le téléchargements de 78,2 Mio d'archives.

On peut calculer exactement la taille de l'image qu'il faut sauvegarder à l'étape suivante.

pi@raspberrypi:~ $ lsblk -b NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk0 179:0 0 15931539456 0 disk ├─mmcblk0p1 179:1 0 44979712 0 part /boot └─mmcblk0p2 179:2 0 1753219072 0 part / pi@raspberrypi:~ $ sudo fdisk /dev/mmcblk0 -l Disk /dev/mmcblk0: 14.9 GiB, 15931539456 bytes, 31116288 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 Disklabel type: dos Disk identifier: 0xc1dc39e5 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 8192 96042 87851 42.9M c W95 FAT32 (LBA) /dev/mmcblk0p2 98304 3522559 3424256 1.6G 83 Linux

Le secteur numéro 3 522 559 est le dernier utilisé, ce qui implique que les partitions boot et / sont contenus dans les premiers 3 522 560*512 = 1 803 550 720 octets de la carte SD (je suppose que le premier secteur est numéroté 0). Les deux partitions occupent un peu moins d'espace (44979712+1753219072 = 1 798 198 784). Il faut ajouter 8192 secteurs au début du disque qui contiennent la table de partitionnement et un programme d'amorçage. Il y a aussi 98304-96042-1 = 2261 secteurs, probablement vides, entre les deux partitions, probablement pour un alignement optimale de la partition.

C'est toujours préférable d'arrêter le système d'exploitation correctement avant de couper le courant.

pi@raspberrypi:~ $ sudo shutdown now Connection to raspberrypi.local closed by remote host. Connection to raspberrypi.local closed.

Quand la DEL verte ne clignote plus, il est maintenant possible de retirer la carte SD sans danger de corrompre le système de fichier

Sauvegarder l'image modifiée toc

La préparation de l'image personnalisée peut être considérée comme complète à cette étape. Tout dépendra de l'utilisation que voudra faire de l'image plus tard. Alors il faut placer carte SD du Raspberry Pi dans lecteur de l'ordinateur de bureau pour en faire une image avec l'utilitaire dd. Avant il faut trouver le nom du dispositif et l'éliminer de la hiérarchie du système de fichiers, car typiquement Linux aura monté la carte automatiquement après son insertion dans le lecteur.

michel@hp:~/Téléchargements/OS/Raspbian$ df -h Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur udev 5,9G 0 5,9G 0% /dev ... /dev/sde1 44M 23M 22M 51% /media/michel/boot /dev/sde2 1,7G 1,1G 449M 72% /media/michel/rootfs michel@hp:~/Téléchargements/OS/Raspbian$ sudo umount /dev/sde2 michel@hp:~/Téléchargements/OS/Raspbian$ sudo umount /dev/sde1 michel@hp:~/Téléchargements/OS/Raspbian$ sudo dd bs=2M count=1116 if=/dev/sde of=stretch_lite_2019-01-22_base.img

L'image ainsi sauvegardée fait 1 870 659 584 octets, ce qui est un peu plus que celle provenant de la Fondation qui occupait 1 803 550 720 octets (l'image de la version précédente (nov. 2018) faisait 1 866 465 280 octets). En principe les deux images devraient être de taille égale, mais j'ai été prudent en définissant la taille à sauvegarder. De toute façon je n'ai pas de carte microSD d'une capacité inférieure à 8 Gio alors cette petite différence est peu significative.

L'étape suivante est facultative, j'expliquerai pourquoi je veux accroître la taille de la partition root à la dernière section.

Accroître la taille de la partition root toc

Il a été possible de vérifier avec GParted que la partition root de type ext4 dont l'étiquette est rootfs occupe 1,69 Gio. Alors que 722 Mio était initialement libre, cet espace a été réduit à 555,4 Mio après la mise à jour de Raspbian. J'ai décidé d'accroître la taille de la partition de 512 Mio pour avoir un peu plus d'espace pour expérimenter. Ainsi j'ai augmenté la taille de /dev/sde2 (la partition rootfs qui pourrait être montée sur un autre lecteur dans un autre système) de 1732 à 2240 Mio soit à 2,2 Gio. Cela donne un peu plus de 1 Gio pour installer programmes sous tests.

Je n'ai pas réussi à utiliser GParted pour réaliser cette opération. Alors en examinant comment raspi-config s'y prenait, voici comment le faire avec l'utilitaire fdisk. Ceci est fait avec le Raspberry Pi avec la carte SD qu'on a copier à l'étape précédente.

pi@raspberrypi:~ $ sudo fdisk /dev/mmcblk0 Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): p Disk /dev/mmcblk0: 7.5 GiB, 8053063680 bytes, 15728640 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 Disklabel type: dos Disk identifier: 0x7ee80803 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 8192 98045 89854 43.9M c W95 FAT32 (LBA) /dev/mmcblk0p2 98304 3645439 3547136 1.7G 83 Linux Command (m for help): d Partition number (1,2, default 2): 2 Partition 2 has been deleted. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): 2 First sector (2048-15728639, default 2048): 98304 Last sector, +sectors or +size{K,M,G,T,P} (98304-15728639, default 15728639): +4590412 Created a new partition 2 of type 'Linux' and of size 2.2 GiB. Partition #2 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o: n Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Re-reading the partition table failed.: Device or resource busy The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8). pi@raspberrypi:~ $ sudo reboot Connection to raspberrypi.local closed by remote host. Connection to raspberrypi.local closed.

Comme l'explique fdisk, il faut redémarrer le Raspberry Pi pour que le changement de taille soit fait lors du redémarrage. Lorsqu'une nouvelle session est ouverte pour vérifier que tout fonctionne, ssh se plaint encore que la clé de sécurité est différente pour raspberrypi.local et 192.168.1.18. On peut éliminer ce message en ouvrant une session avec l'adresse IP pour ainsi mettre à jour la clé stockée par le client ssh.

michel@hp:~ $ ssh pi@raspberrypi.local Warning: the ECDSA host key for 'raspberrypi.local' differs from the key for the IP address '192.168.1.18' Offending key for IP in /home/michel/.ssh/known_hosts:12 Matching host key in /home/michel/.ssh/known_hosts:15 Are you sure you want to continue connecting (yes/no)? yes pi@raspberrypi.local's password: xxxxxxx pas montré à l'écran Linux raspberrypi 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l ...

On peut vérifier la nouvelle taille des partitions sur la carte SD avec fdisk.

pi@raspberrypi:~ $ sudo fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 7.5 GiB, 8053063680 bytes, 15728640 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 Disklabel type: dos Disk identifier: 0x7ee80803 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 8192 98045 89854 43.9M c W95 FAT32 (LBA) /dev/mmcblk0p2 98304 4688716 4590413 2.2G 83 Linux

Maintenant il reste à éteindre le Raspberry Pi et à créer l'image comme auparavant, sauf que sa taille est différente et le nom du fichier est différent.

pi@raspberrypi:~ $ sudo shutdown now Connection to raspberrypi.local closed by remote host. Connection to raspberrypi.local closed. michel@hp:~/Téléchargements/OS/Raspbian$ df -h Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur udev 5,9G 0 5,9G 0% /dev ... /dev/sde1 44M 23M 22M 51% /media/michel/boot /dev/sde2 1,7G 1,1G 497M 69% /media/michel/rootfs michel@hp:~/Téléchargements/OS$ sudo umount /dev/sde2 michel@hp:~/Téléchargements/OS$ sudo umount /dev/sde1 michel@hp:~/Téléchargements/OS$ sudo dd bs=2M count=1150 if=/dev/sde of=stretch_lite_2019-01-22_2.2GiB.img michel@hp:~/Téléchargements/OS$ sudo chown michel: stretch_lite_2019-01-22_2.2GiB.img

Le calcul de la taille est assez facile. Selon fdisk, le dernier secteur occupé par les deux partitions est le 4688716e et chaque secteur fait 512 octets soit 0.5 Kio. Donc elles occupent les premiers 2 344 358 Ki octets de la carte ou 2289,4 Mio (on divise par 1024 car tout ceci est en multiples de 2). L'utilitaire dd copie 1150 blocs de 2 Mio soit 2300 Mio. Je préfère copier un peu plus que pas assez, les plus téméraires pourraient ne copier que 1145 blocs.

Utilisation toc

Maintenant quand je veux faire l'installation d'un programme dans une version fraiche de Raspbian Stretch, j'utilise Etcher pour copier l'une ou l'autre des versions personnalisées créées ci-dessus. La plus petite image est plus rapidement copiée alors je choisis stretch_lite_2019-01-22.img si possible. Si j'ai l'intention d'agrandir le système de fichier à la taille maximale, alors aussi bien choisir cette image. Si je veux installer des bibliothèques et programmes qui ne sont pas trop lourd, alors c'est cette image que je copie sur la carte SD. Je choisis stretch_lite_2019-01-22_2.2GiB.img si je pense qu'un espace de travail de 1 Gio est suffisant et si j'anticipe faire une sauvegarde du système modifié vers un fichier sur l'ordinateur de bureau pour pouvoir la copier sur une carte SD plus tard.

Qu'importe la source choisie, dès le premier démarrage du Raspberry Pi avec le nouveau système d'exploitation, je fais deux choses. Premièrement, je mets à jour le système (sudo apt update && sudo apt upgrade -y). Deuxièmement, je change le nom d'hôte. Il est trop facile de ne pas trouver le nouveau Raspberry Pi avec le nom d'hôte par défaut raspberrypi s'il y a déjà un serveur avec ce nom sur le réseau. Le plus simple est d'utiliser sudo raspi-config. Enfin, s'il faut accroître la taille du système de fichier j'utilise sudo raspi-config pour le faire; c'est bien plus simple qu'utiliser fdisk.

<-Updating Raspbian to Stretch Creating a Custom Armbian Image->