Image of an arrow

Comment reprogrammer une EEPROM sous Linux (2)

Avatar

evigier

eepromDans un premier billet, nous avons vu qu’il était très simple de reprogrammer une mémoire de type EEPROM sous linux. Malheureusement, nous avions rencontré des soucis d’accès au périphérique que nous devons maintenant contourner. Dans ce second billet, je vous propose donc d’étudier les outils des débogage I2C Tools et leur utilisation sur un système embarqué.

Permission denied

« Permission denied » est probablement l’erreur la plus courante sous Linux. C’est aussi la moins déconcertante: si make me a sandwich ne fonctionne pas, sudo make me a sandwich le devrait. En embarqué, la commande sudo n’a pas de sens puisque nous sommes déjà root. Alors, si ce n’est pas un problème d’utilisateur, pourquoi le système ne nous laisse-t-il pas écrire dans l’EEPROM?

Use the source, Luke!

Allons jeter un œil au code source du pilote. Celui-ci dispose bien des routines pour lire et écrire dans l’EEPROM, mais il y a un élément plus intéressant : l’option AT24_FLAG_READONLY. Le pilote permet en effet aux développeurs de supprimer l’accès en écriture. En définissant cette option, le développeur empêche les applications d’utilisateur de modifier le contenu de la mémoire. L’option peut être déclarée dans des platform_data ou propriété « read-only » pour les systèmes supportant l’OpenFirmware (CONFIG_OF).

Pour faire court, sous Linux, nous pouvons classer les périphériques en deux types : les périphériques découvrables par le matériel (souris USB, carte PCI, …) et ceux qui doivent être « figés dans le code » au niveau du kernel (I2C, SPI, …). Notre mémoire EEPROM I2C tombe dans la deuxième catégorie.

I2C Tools

Si le pilote ne nous permet pas d’écrire, nous avons néanmoins une alternative : envoyer des commandes d’écriture directement sur le bus I2C. C’est la raison d’être de la chaîne d’outils I2C Tools, qui comprend quatre binaires:

  • i2cset envoie des commandes d’écriture à un périphérique,
  • i2cget envoie des commandes de lecture,
  • i2cprobe détecte les périphériques présents sur le bus,
  • et i2cdump lit l’intégralité des registres d’un périphérique.

Problème : je n’ai pas accès au système de compilation de ce système et l’ingénieur matériel qui m’accompagne n’en a pas connaissance non plus. Réfléchissons : sur quel système travaillons-nous?

# cat /proc/cpuinfo
Processor : ARM926EJ-S rev 5 (v5l)

Un ARM9, formidable! Je travaille présentement sur un autre projet équipé de ce CPU. Je devrais pouvoir utiliser la version d’i2c-tools compilée pour ARM de mon projet sur cet équipement. La version de Linux n’est pas la même (2.6.30 contre 3.2.27), mais l’API i2c.h n’a probablement pas bougé entre les deux. Essayons :

# i2cget -y 2 0x54
Error: Could not set address to 0x54: Device or resource busy

Le binaire fonctionne, l’API n’a pas dû bouger.

Opération à coeur ouvert

Évidemment le pilote de l’EEPROM a le contrôle sur ce périphérique et Linux ne nous permet pas de le hacker. Les outils I2C peuvent forcer la porte avec l’option -f, mais il y a un risque de contention du bus. Par exemple, si deux accès concurrents s’entrelacent, ils risquent de corrompre notre périphérique I2C. Nous allons plutôt utiliser la méthode élégante : déconnecter le lien entre le pilote et le périphérique. Cette méthode est disponible depuis linux-2.6.13 et est décrite sur LWN. L’idée est de supprimer le lien qui existe entre l’EEPROM et son pilote : at24. Même de cette façon, il y a un risque de corruption comme le décrit cet échange de la liste de discussion du kernel. Dans notre cas, au pire, une application accédant à l’EEPROM va planter. Jetons un œil à ce lien entre notre EEPROM et son pilote :

# cd /sys/devices/platform/i2c_davinci.2/i2c-2/2-0054/driver
# ls -l
lrwxrwxrwx 1 root root 0 Feb 1 03:43 0-0050 -> ../../../../devices/platform/i2c_davinci.0/i2c-0/0-0050
lrwxrwxrwx 1 root root 0 Feb 1 03:43 2-0054 -> ../../../../devices/platform/i2c_davinci.2/i2c-2/2-0054
--w------- 1 root root 4096 Feb 1 03:43 bind
--w------- 1 root root 4096 Feb 1 03:43 uevent
--w------- 1 root root 4096 Feb 1 03:43 unbind

Ici, on peut voir que le pilote est associé à deux mémoires EEPROM différentes : L’une à l’adresse 0x50 sur le bus i2c-0. L’autre à l’adresse 0x54 sur le bus i2c-2. C’est la deuxième qui nous intéresse. Essayons de retirer le pilote :

# echo 2-0054 > unbind

# i2cdump -y 2 0x54
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 4b 5a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 KZ
10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 4e 50 NP
40: 45 4e 30 31 20 20 20 20 20 20 20 20 20 20 20 20 EN01

Bingo! Essayons maintenant d’écrire un octet à l’adresse 0x44, par exemple :

# i2cset -y 2 0x54 0x44 0x5a

# i2cget -y 2 0x54 0x44
0x5a

Bingo! Quoi de plus simple? Désormais nous pouvons écrire un petit script shell ou programme C pour réécrire les octets qui nous intéressent spécifiquement et l’exécuter sur chaque équipement présentant le défaut initial. N’oublions pas de recoudre le patient, c’est à dire de reconnecter le pilote :

# echo 2-0054 > bind
[ 643.972940] at24 2-0054: 512 byte 24c04 EEPROM, writable, 1 bytes/write

Et vérifions que le patient est bien guéri en lisant l’octet modifié :

# hexdump -C 2-0054/eeprom -n 1 -s 0x44
00000044 5a |Z|

Mission réussie grâce à un petit « hack » rapide et efficace. Inutile de brancher un JTAG ou de recompiler quoi que ce soit. Reste à convaincre le chef de projet que la solution logicielle vaut le coup, ce qui risque d’être une autre histoire…


Articles similaires

Image of an arrow

Savoir-faire Linux est fière d’annoncer la sortie de la version v2.3.0 de l’extension officielle du Projet Yocto pour VS Code. Lisez l’article complet en anglais. Liens et ressources Pour en savoir plus sur cette ambitieuse extension du Projet Yocto pour VS Code : Téléchargez l’extension depuis le magasin VS Code Parcourez le code, signalez des […]

Savoir-faire Linux est fière d’annoncer la sortie de la version v2.2.0 de l’extension officielle du Projet Yocto pour VS Code. Cette version majeure offre de nouvelles fonctionnalités très demandées par la communauté ! Parmi les nouveautés, la possibilité de gérer plusieurs configurations BitBake dans le même espace de travail VS Code, ou encore l’analyse des […]

[L’introduction est en français, le reste du texte en anglais]   L’économie d’énergie a toujours été une préoccupation majeure dans les systèmes embarqués, puisque par définition, ils peuvent avoir des contraintes énergétiques. Bien sûr, aujourd’hui, l’économie d’énergie est toujours au cœur des discussions. L’économie d’énergie est toujours un ensemble de compromis. En termes de disponibilité […]

L’équipe de Savoir-faire Linux est fière d’annoncer la sortie de la version v2.1 de l’extension du Projet Yocto pour VS Code. Le projet Yocto, avec le financement du Sovereign Tech Fund, a entrepris d’étendre et de moderniser cette technologie pour les cinq années à venir. Au sein de cette initiative, Savoir-faire Linux s’est vu confier […]

Thumbnail image

[L’introduction est en français, le reste du texte en anglais] TL;DR Les systèmes audio utilisent souvent des périphériques asynchrones, qui ont besoin d’être synchronisés avec du ré-échantillonnage. Nos mesures montrent que la charge CPU du ré-échantillonnage peut atteindre presque 30% d’un cœur sur un SoC i.MX8M Nano. Utiliser l’endpoint de feedback de l’USB gadget UAC2 […]