ACPI: ajout de périphériques sans recompilation du noyau

Il s'avère que peu de gens sont conscients de l'existence d'un mode de superposition dans ACPICA et de leur support sous Linux. Je veux combler cette lacune avec l'exemple de l'ajout d'esclaves I2C au système sans recompilation.

Conditions initiales


Disons au démarrage

i2cdetect -y -r 0 

nous avons l'image suivante:

Sortie I2cdetect
      0 1 2 3 4 5 6 7 8 9 abcdef
 00: - - - - - - - - - - - - - 
 10: - - - - - - - - - - - - - - - - - 
 20: - - - - - - - - - - - - - - - - - 
 30: - - - - - - - - - - - - - - - - - 
 40: - - - - - - - - - - - - - - - - - - 
 50: - - - 53 - - - 57 - - - - - - - - 
 60: - - - - - - - - - - - - - - - - - 
 70: - - - - - - - - -                         


où l'accéléromètre ADXL345 est détecté à l'adresse 0x53 et la puce EEPROM de la mémoire 24c128 se trouve à l'adresse 0x57. Les descriptions de ces périphériques ne sont pas disponibles dans ACPI, notamment dans le tableau DSDT .

Ajouter un accéléromètre ADXL345


Tout ce que nous devons savoir ici est l'adresse à laquelle l'appareil répond, ses identifiants pris en charge par le pilote, la fréquence du bus sur lequel il doit fonctionner. Veuillez noter que la fréquence du bus I2C côté conducteur est souvent réglée au minimum pris en charge par tous les périphériques esclaves sur ce bus!

Oh oui, il fut un temps où le sous - système IIO n'existait pas, et le pilote ADXL345 existait déjà. Nous en utilisons donc un nouveau disponible via le sous-système IIO.

Total

  • Adresse: 0x53
  • Fréquence du bus: 400 kHz
  • Lien vers le périphérique maître (contrôleur): \ _SB.PCI0.I2C1
  • ID: adi, adxl345

Il convient de noter que nous utilisons ici un identifiant spécial, qui est destiné aux systèmes avec OF . En tant que couche dans ACPI, un identifiant spécial PRP0001 a été ajouté, ce qui garantit la compatibilité avec les pilotes écrits précédemment pour OF.

Nous traduisons les informations reçues en ASL :

Code ASL pour l'accéléromètre ADXL345
 DefinitionBlock ("adxl345.aml", "SSDT", 5, "", "ADXL345", 1) { External (_SB_.PCI0.I2C1, DeviceObj) Scope (\_SB.PCI0.I2C1) { Device (ACL0) { Name (_HID, "PRP0001") Name (_DDN, "Analog Devices ADXL345 3-axis accelerometer") Name (_CRS, ResourceTemplate () { I2cSerialBusV2 ( 0x0053, // I2C Slave Address ControllerInitiated, 400000, // Bus speed AddressingMode7Bit, "\\_SB.PCI0.I2C1", // Link to ACPI I2C host controller 0 ) }) Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "compatible", "adi,adxl345" }, } }) } } } 


Ajouter EEPROM 24c128


Comme dans le cas précédent, nous obtenons les informations nécessaires sur le périphérique et son pilote:

  • Adresse: 0x57
  • Fréquence du bus: 400 kHz
  • Lien vers le périphérique maître (contrôleur): \ _SB.PCI0.I2C1
  • Numéro d'identification: INT3499
  • Volume: 1024
  • Taille de la page: 32

Code ASL pour EEPROM 24c128
 DefinitionBlock ("at24.aml", "SSDT", 5, "", "AT24", 1) { External (_SB_.PCI0.I2C1, DeviceObj) Scope (\_SB.PCI0.I2C1) { Device (EEP0) { Name (_HID, "INT3499") Name (_DDN, "Atmel AT24 compatible EEPROM") Name (_CRS, ResourceTemplate () { I2cSerialBusV2 ( 0x0057, // I2C Slave Address ControllerInitiated, 400000, // Bus speed AddressingMode7Bit, "\\_SB.PCI0.I2C1", // Link to ACPI I2C host controller 0 ) }) Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "size", 1024 }, Package () { "pagesize", 32 }, } }) } } } 


Notez la différence avec l'option précédente. Il utilise directement l'ID ACPI, qui est alloué dans l'espace contrôlé par Intel, grâce à la plateforme Intel Galileo. La deuxième différence, nous passons des paramètres de périphérique supplémentaires sous la forme de chaînes de valeurs-clés.

Options d'initialisation possibles


Que faire maintenant avec tout ça? L'algorithme est simple. Tout d'abord, vous devez compiler les fichiers résultants en bytecode ASL. Atteint en appelant une commande

 iasl adxl345.asl 

et par analogie pour l'EEPROM. Deuxièmement, choisissez un moyen d'initialiser la table nouvellement créée. Il y en a en fait trois: 1) rejoindre initramfs, 2) charger sur le système de travail via ConfigFS, 3) charger la table à partir de la variable EFI. Considérez les deux premiers ci-dessous.

Rejoindre initramfs

Nous ne ferons rien avec l'archive initramfs elle - même , cependant, il est recommandé de sauvegarder l'original quelque part.

 #  ACPI    cpio . #      /kernel/firmware/acpi  . #       . mkdir -p kernel/firmware/acpi cp adxl345.aml kernel/firmware/acpi cp at24.aml kernel/firmware/acpi #         initramfs: find kernel | cpio -H newc --create > /boot/instrumented_initramfs-vX.Y cat /boot/initramfs-vX.Y >> /boot/instrumented_initramfs-vX.Y 

Après cette procédure, vous pouvez remplacer l'ancienne archive par une nouvelle et redémarrer l'ordinateur.
Quelque chose comme ça devrait apparaître dans la sortie dmesg:

 [ 0.000000] ACPI: Table Upgrade: install [SSDT- - ADXL345] [ 0.000000] ACPI: SSDT 0x000000003F4FF5C4 0000A6 (v05 ADXL345 00000001 INTL 20170303) 

Notez que le noyau ne prend en charge qu'une chaîne de 64 archives de ce type.

Télécharger via ConfigFS

Cette fonctionnalité est disponible lorsque le noyau est compilé avec l'option CONFIG_ACPI_CONFIGFS et ConfigFS est monté. En supposant qu'il est monté dans le sous-répertoire / sys / kernel / config , l'exemple suivant montre comment charger une table.

 cd /sys/kernel/config/acpi/table mkdir adxl345 cat ~/adxl354.aml > adxl345/aml 

Conclusion


Bien que l'ASL nécessite plus de supports que les analogues, elle offre néanmoins pas moins de possibilités de décrire les périphériques. Ainsi, il existe un certain nombre d'exemples dans le projet meta-acpi , où vous pouvez notamment trouver des descriptions de LED et de boutons connectés à des lignes GPIO, des puces mémoire, et même une description du module Adafruit 2.8 " - écran TFT avec écran tactile!

Source: https://habr.com/ru/post/fr451668/


All Articles