ACPI: Adicionando dispositivos sem recompilação do kernel

Como se vê, poucos sabem da existência de um modo de sobreposição no ACPICA e de seu suporte no Linux. Quero preencher essa lacuna com o exemplo de adição de escravos I2C ao sistema sem recompilar.

Condições iniciais


Digamos na inicialização

i2cdetect -y -r 0 

nós temos a seguinte imagem:

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


onde o acelerômetro ADXL345 é detectado no endereço 0x53 e o chip 24c128 EEPROM está localizado no endereço 0x57. As descrições desses dispositivos não estão disponíveis no ACPI, principalmente na tabela DSDT .

Adicionar acelerômetro ADXL345


Tudo o que precisamos saber aqui é o endereço no qual o dispositivo responde, seus IDs suportados pelo motorista, a frequência do barramento no qual ele deve trabalhar. Observe que a frequência do barramento I2C no lado do motorista geralmente é definida como o mínimo suportado por todos os dispositivos escravos nesse barramento!

Ah, sim, houve um tempo em que o subsistema IIO não existia e o driver ADXL345 já existia. Portanto, estamos usando um novo que está disponível no subsistema IIO.

Total

  • Endereço: 0x53
  • Frequência de barramento: 400kHz
  • Link para o dispositivo mestre (controlador): \ _SB.PCI0.I2C1
  • ID: adi, adxl345

Deve-se notar que usamos aqui um identificador especial, destinado a sistemas com OF . Como uma camada na ACPI, foi adicionado um identificador especial PRP0001 , que garante a compatibilidade com os drivers escritos anteriormente para o OF.

Traduzimos as informações recebidas em ASL :

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


Adicionar EEPROM 24c128


Como no caso anterior, obtemos as informações necessárias sobre o dispositivo e seu driver:

  • Endereço: 0x57
  • Frequência de barramento: 400kHz
  • Link para o dispositivo mestre (controlador): \ _SB.PCI0.I2C1
  • Número de identificação: INT3499
  • Volume: 1024
  • Tamanho da 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 a diferença com a opção anterior. Ele usa o ID da ACPI diretamente, que é alocado no espaço controlado pela Intel, graças à plataforma Intel Galileo. A segunda diferença, passamos parâmetros adicionais do dispositivo na forma de cadeias de valores-chave.

Possíveis opções de inicialização


O que fazer agora com tudo isso? O algoritmo é simples. Primeiro, você precisa compilar os arquivos resultantes no bytecode ASL. Conseguido chamando um comando

 iasl adxl345.asl 

e por analogia para EEPROM. Em segundo lugar, escolha uma maneira de inicializar a tabela recém-criada. Na verdade, existem três deles: 1) ingressando no initramfs, 2) carregando no sistema de trabalho via ConfigFS, 3) carregando a tabela a partir da variável EFI. Considere os dois primeiros abaixo.

Juntando initramfs

Não faremos nada com o próprio arquivo initramfs ; no entanto, é recomendável que você salve o original em outro lugar.

 #  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 

Após este procedimento, você pode substituir o arquivo antigo por um novo e reiniciar o computador.
Algo assim deve aparecer na saída dmesg:

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

Observe que o kernel suporta apenas uma cadeia de até 64 desses arquivos.

Download via ConfigFS

Esse recurso está disponível quando o kernel é compilado com a opção CONFIG_ACPI_CONFIGFS e o ConfigFS é montado. Supondo que ele esteja montado no subdiretório / sys / kernel / config , o exemplo a seguir mostra como carregar uma tabela.

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

Conclusão


Embora o ASL exija mais parênteses do que os análogos, ele ainda oferece menos oportunidades para descrever dispositivos. Portanto, existem vários exemplos no projeto meta-acpi , onde você pode encontrar descrições de LEDs e botões conectados a linhas GPIO, chips de memória e até mesmo uma descrição do módulo Adafruit 2.8 " - tela TFT com uma tela sensível ao toque!

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


All Articles