ACPI: Agregar dispositivos sin recompilación del núcleo

Como resultado, muy pocos son conscientes de la existencia de un modo de superposición en ACPICA y su soporte en Linux. Quiero llenar este vacío con el ejemplo de agregar esclavos I2C al sistema sin recompilar.

Condiciones iniciales


Digamos al inicio

i2cdetect -y -r 0 

Tenemos la siguiente imagen:

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


donde se detecta el acelerómetro ADXL345 en la dirección 0x53, y el chip EEPROM de memoria 24c128 se encuentra en la dirección 0x57. Las descripciones de estos dispositivos no están disponibles en ACPI, es decir, en la tabla DSDT .

Agregar acelerómetro ADXL345


Todo lo que necesitamos saber aquí es la dirección a la que responde el dispositivo, sus ID compatibles con el controlador, la frecuencia del bus en el que debería funcionar. ¡Tenga en cuenta que la frecuencia del bus I2C en el lado del controlador a menudo se establece en el mínimo que admiten todos los dispositivos esclavos en este bus!

Ah, sí, hubo un momento en que el subsistema IIO no existía y el controlador ADXL345 ya existía. Entonces, estamos usando uno nuevo que está disponible a través del subsistema IIO.

Total

  • Dirección: 0x53
  • Frecuencia de bus: 400 kHz
  • Enlace al dispositivo maestro (controlador): \ _SB.PCI0.I2C1
  • ID: adi, adxl345

Cabe señalar que aquí utilizamos un identificador especial, que está destinado a sistemas con OF . Como una capa en ACPI, se agregó un identificador especial PRP0001 , que garantiza la compatibilidad con los controladores escritos anteriormente para OF.

Traducimos la información recibida a ASL :

Código ASL para el acelerómetro 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" }, } }) } } } 


Agregar EEPROM 24c128


Como en el caso anterior, obtenemos la información necesaria sobre el dispositivo y su controlador:

  • Dirección: 0x57
  • Frecuencia de bus: 400 kHz
  • Enlace al dispositivo maestro (controlador): \ _SB.PCI0.I2C1
  • Número de identificación: INT3499
  • Volumen: 1024
  • Tamaño de página: 32

Código ASL para 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 }, } }) } } } 


Observe la diferencia con la opción anterior. Utiliza la ID ACPI directamente, que se asigna en el espacio controlado por Intel, gracias a la plataforma Intel Galileo. La segunda diferencia es que pasamos parámetros adicionales del dispositivo en forma de cadenas de valor clave.

Posibles opciones de inicialización


¿Qué hacer ahora con todo esto? El algoritmo es simple. Primero, debe compilar los archivos resultantes en el código de bytes ASL. Logrado al llamar a un comando

 iasl adxl345.asl 

y por analogía para EEPROM. En segundo lugar, elija una forma de inicializar la tabla recién creada. Hay tres de ellos: 1) unirse a initramfs, 2) cargar en el sistema de trabajo a través de ConfigFS, 3) cargar la tabla desde la variable EFI. Considere los dos primeros a continuación.

Unirse a initramfs

No haremos nada con el archivo initramfs en sí mismo , sin embargo, se recomienda guardar el original en algún lugar aparte.

 #  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 

Después de este procedimiento, puede reemplazar el archivo antiguo por uno nuevo y reiniciar la computadora.
Algo así debería aparecer en la salida de dmesg:

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

Tenga en cuenta que el núcleo solo admite una cadena de hasta 64 archivos de este tipo.

Descargar a través de ConfigFS

Esta característica está disponible cuando el núcleo se compila con la opción CONFIG_ACPI_CONFIGFS y se monta ConfigFS. Suponiendo que esté montado en el subdirectorio / sys / kernel / config , el siguiente ejemplo muestra cómo cargar una tabla.

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

Conclusión


Aunque el ASL requiere más soportes que los análogos, no obstante, ofrece no menos oportunidades para describir dispositivos. Por lo tanto, hay una serie de ejemplos en el proyecto meta-acpi , donde en particular puede encontrar descripciones de LED y botones conectados a líneas GPIO, chips de memoria e incluso una descripción del módulo Adafruit 2.8 " : ¡pantalla TFT con pantalla táctil!

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


All Articles