This translation is older than the original page and might be outdated. See what has changed.

Agencement de la mémoire flash

Il y a les disques durs qui sont considérés comme des périphériques blocs, et il y a la mémoire flash. Il y a différents types de mémoire flash comme: NOR, SLC NAND et MLC NAND.
Si le circuit intégré (peu importe le type) est directement connecté au SoC et doit être adressé directement par Linux, on l'appelle “raw flash” (mémoire flash brute). Si le circuit intégré ne peut pas être adressé directement par le système d'exploitation (parce qu'il y a un composant contrôleur additionnel entre lui et le SoC), on l'appelle “FTL (Flash Translation Layer) flash”. Les logiciels embarqués utilisent presqu'exclusivement de la “raw flash”, tandis que les clés USB utilisent presqu'exclusivement de la “FTL flash”!

Le composant flash, sur les systèmes embarqués, n'est pas accompagné par un composant contrôleur, et par conséquent, n'est pas un composant “FTL” mais un composant “raw flash”. L'espace de stockage est traité et adressé comme un MTD (Memory Technology Device) et des système de fichiers spéciaux sont utilisés. L'espace de stockage n'est pas partitionné de manière traditionnelle, dans laquelle vous stockez les informations relatives aux partitions dans le MBR et les PBRs, mais c'est fait dans le Noyau Linux (et parfois indépendamment dans le chargeur d'amorçage !). Vous définissez simplement, que la “partition noyau commence à l'offset x et se termine à l'offset y”. L'avantage de cette méthode, c'est que, plus tard, vous pouvez adresser ces partitions par nom, plutôt qu'en précisant le point de départ précis des données.

:!: Le document suivant, présentant l'arrangement mémoire du TL-WR1043ND en est un pur exemple! Un autre exemple, légèrement différent, est disponible à la page du wiki DIR-300. Ainsi donc, les arrangements de la mémoire diffèrent d'un routeur à l'autre ! Reportez-vous à la page de wiki de votre routeur, pour connaître son arrangement particulier et vérifiez le vous même sur votre routeur.

TP-Link WR1043ND Arrangement de la mémoire Flash
Couche0 m25p80 spi0.0: m25p64 8192KiB
Couche1 mtd0 u-boot 128KiB mtd5 firmware 8000KiB mtd4 art 64KiB
Couche2 mtd1 kernel 1280KiB mtd2 rootfs 6720KiB
Point de montage /
Système de fichiers mini_fo/overlayfs
Couche3 mtd3 rootfs_data 5184KiB
Taille en KO 128KiB 1280KiB 1536KiB 5184KiB 64KiB
Nom u-boot kernel rootfs_data art
Point de montage aucun aucun /rom /overlay aucun
Système de fichiers aucun aucun SquashFS JFFS2 aucun

Comme les partitions sont imbriquées, cet ensemble peut être vu en couches :

  1. Couche0: nous avons le composant flash, d'une taille de 8MiB , qui est soudé au circuit imprimé et connecté au soc via le SPI (Serial Peripheral Interface Bus)(Bus d'Interface Série).
  2. Couche1: nous “partitionnons” l'espace en mtd0 pour le chargeur d'amorçage, mtd5 pour le firmware et, dans ce cas, mtd4 pour l'ART (Atheros Radio Test) - il contient les adresses MAC et les données de calibration pour le sans fil (EEPROM). S'il est manquant ou corrompu, ath9k (pilote du sans fil) ne démarrera pas.
  3. Couche2: nous subdivisons mtd5 (firmware) en mtd1 (noyau) et mtd2 (rootfs); Dans le processus de génération du firware, (voir imagebuilder) le fichier binaire du noyau est le premier empaqueté avec le LZMA, puis, le fichier résultant est empaqueté avec gzip et finalement, ce fichier est écrit dans la mémoire raw flash (mtd1) sans faire partie d'aucun système de fichiers !
  4. Couche3: nous subdivisons rootfs encore plus en mtd3 pour les données rootfs_data et le reste pour une partition sans nom qui recevra la partition SquashFS.
  • / c'est votre système de fichiers racine dans son intégralité ; il comprend /rom et /overlay. Ignorez /rom et /overlay et utilisez exclusivement / pour vos routines courantes!
  • /rom contient tous les fichiers de base, comme busybox, dropbear ou iptables y compris les fichiers de configuration par défaut. Elle ne contient pas le noyau. Les fichiers de ce dossier sont sur la partition SqashFS , et par conséquent ne peuvent être effacés. Mais, comme nous utilisons le système de fichiers mini_fo, aussi appelé overlay-whiteout-des liens symboliques peuvent être créés sur la partition JFFS2.
  • /overlay est la partie inscriptible de système de fichiers qui est fusionné /rom pour créer un -arbre-/ uniforme. Elle contient tout ce qui a été écrit dans le routeur après l'installation, comme les fichiers de configuration modifiés, les paquets additionnels installés avec opkg, etc. Elle est formaté en JFFS2.

Plutôt que d'effacer les fichiers, insérez un whiteout, une entrée spéciale haute priorité qui marque le fichier comme effacé. Le système de fichiers, quand il voit une entrée whiteout pour le fichier F, se comporte comme si le fichier F n'existait pas.

#!/bin/bash
# shows all overlay-whiteout symlinks
 
find /overlay -type l | while read FILE
  do
    [ -z "$FILE" ] && break
    if ls -la "$FILE" 2>&- | grep -q '(overlay-whiteout)'; then
    echo "$FILE"
    fi
  done

NOTE1: si le noyau faisait partie de la partition SquashFS, nous ne pourrions contrôler à quel emplacement exact dans la mémoire flash il serait écrit (dans quels blocs se trouveraient ses données). Par conséquent, nous ne pourrions nous contenter de dire au chargeur d'amorçage de charger et exécuter certains blocs sur la mémoire flash, mais nous devrions l'adresser avec un chemin et un nom de fichier. Ce ne serait pas mauvais en soi, mais pour le faire, le chargeur d'amorçage aurait à connaître et comprendre le système de fichier SquashFS, ce qui n'est pas le cas. Les chargeurs d'amorçage embarqués que nous utilisons avec OpenWrt ne comprennent pas le concept de système de fichiers et, par conséquent, sont incapables d'adresser un fichier par chemin/nom.Le mieux qu'il fassent, c'est de supposer que le début de la section trx data est du code exécutable.

NOTE2: la dénomination “firmware” est généralement employée pour l'intégralité des données de la mémoire flash, y compris le chargeur d'amorçage et les autres données nécessaires au fonctionnement du routeur, comme ART, NVRAM, FIS, etc, mais nous l'employons aussi pour désigner la partie ré-inscriptible. Ne vous laissez pas embrouiller par cela. ;-)

TODO

cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00010000 "u-boot"
mtd1: 00140000 00010000 "kernel"
mtd2: 00690000 00010000 "rootfs"
mtd3: 00530000 00010000 "rootfs_data"
mtd4: 00010000 00010000 "art"
mtd5: 007d0000 00010000 "firmware"

Le champ erasesize est la taille de bloc de la mémoire flash, en l'occurrence 64KiB. Cette taille est écrite en valeur hexadécimales little ou big endian en Octets. Dans le cas de little endian, vous commutez en mole hexa et entrez 02 0000 dans l'ordinateur par exemple et convertissez en décimal (en re-commutant en mode décimal). Puis estimez estimez commant elles sont imbriquées l'une dans l'autre. Ou bien, exécutez dmesg juste après un boot et voyez quelque chose comme :

Creating 5 MTD partitions on "spi0.0":
0x000000000000-0x000000020000 : "u-boot"
0x000000020000-0x000000160000 : "kernel"
0x000000160000-0x0000007f0000 : "rootfs"
mtd: partition "rootfs" set to be root filesystem
mtd: partition "rootfs_data" created automatically, ofs=2C0000, len=530000
0x0000002c0000-0x0000007f0000 : "rootfs_data"
0x0000007f0000-0x000000800000 : "art"
0x000000020000-0x0000007f0000 : "firmware"

Ce sont les offsets de début et de fin des partitions en valeur hexa-décimales représentant des Octets.Maintenant, vous n'avez plus besoin de supposer qui est inclus dans qui.Ex : 02 0000 = 131.072 Bytes = 128KiB

La mémoire flash peut être vue comme un grand bloc d'espace continu:

début de la mémoire flash ................. fin de la mémoire flash

Il n'y a pas de ROM à partir de laquelle booter; à la mise sous tension, le CPU commence à exécuter le code au tout début de la mémoire flash. Fort heureusement, il ne s'agit pas du firmware, sinon nous serions en réel danger à chaque ré-écriture du firmware. Le démarrage est en fait pris en charge par une section de code que nous avons tendance à appeler chargeur d'amorçage (le BIOS de votre PC est un chargeur d'amorçage).

Partition du chargeur d'amorçage Partition du firmware Données spéciale de configuration
Atheros U-Boot firmware ART
Broadcom CFE firmware NVRAM
Atheros RedBoot firmware FIS recovery RedBoot config boardconfig

La (ou les) partition(s) contenant les données spéciales de configuration diffèrent beaucoup entre elles.Exemple: la partitionART ' que l'on rencontre concomitamment avec Atheros-Wireless et U-Boot, ne contient que les données relatives au pilote sans fil, tandis que la partition NVRAM des routeurs Broadcom est utilisée pour bien d'autres choses en plus.

Si vous plongez dans la section “firmware”, vous trouverez un trx. Un trx n'est qu'une encapsulation qui ressemble à ceci :

trx-header (entête trx)
HDR0 length crc32 flags pointers data

“HDR0” est un nombre magique pour indiquer une entête trx, le reste est une valeur non signée de 4 octets suivie par le contenu réel. En bref, c'est un bloc de données avec une longueur et une somme de contrôle. Ainsi, l'utilisation de notre mémoire flash ressemble à ceci :

CFE trx contenant le firmware NVRAM

Sauf que le firmware est en général très petit et n'occupe pas l'espace entier en CFE et NVRAM :

CFE trx firmware unused NVRAM

(NOTE: The <model>.bin files are nothing more than the generic *.trx file with an additional header appended to the start to identify the model. The model information gets verified by the vendor's upgrade utilities and only the remaining data -- the trx -- gets written to the flash. When upgrading from within OpenWrt remember to use the *.trx file.)

So what exactly is the firmware?

The boot loader really has no concept of filesystems, it pretty much assumes that the start of the trx data section is executable code. So, at the very start of our firmware is the kernel. But just putting a kernel directly onto flash is quite boring and consumes a lot of space, so we compress the kernel with a heavy compression known as LZMA. Now the start of firmware is code for an LZMA decompress:

lzma decompress lzma compreszsed kernel

Now, the boot loader boots into an LZMA program which decompresses the kernel into memory and executes it. It adds one second to the bootup time, but it saves a large chunk of flash space. (And if that wasn't amusing enough, it turns out the boot loader does know gzip compression, so we gzip compressed the LZMA decompression program)

Immediately following the kernel is the filesystem. We use SquashFS for this because it's a highly compressed readonly filesystem -- remember that altering the contents of the trx in any way would invalidate the crc, so we put our writable data in a JFFS2 partition, which is outside the trx. This means that our firmware looks like this:

trx gzip'd lzma decompress lzma'd kernel (SquashFS filesystem)

And the entire flash usage looks like this -

CFE trx gz'd lzma lzma'd kernel SquashFS JFFS2 filesystem NVRAM

That's about as tight as we can possibly pack things into flash.


This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2018/06/11 17:33
  • by tmomas