O modelo de desenvolvimento de drivers do kernel Linux

1.004 visualizações

Publicada em

Palestra apresentada no Seminário Programação para
Sistemas Embarcados 2014.

Publicada em: Software
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
1.004
No SlideShare
0
A partir de incorporações
0
Número de incorporações
26
Ações
Compartilhamentos
0
Downloads
58
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

O modelo de desenvolvimento de drivers do kernel Linux

  1. 1. Embedded Labworks Por Sergio Prado. São Paulo, Novembro de 2014 ® Copyright Embedded Labworks 2004-2014. All rights reserved. Seminário Programação para Sistemas Embarcados 2014 O modelo de desenvolvimento de drivers do kernel Linux
  2. 2. Embedded Labworks SOBRE ESTE DOCUMENTO ✗ Este documento é disponibilizado sob a Licença Creative Commons BY-SA 3.0. http://creativecommons.org/licenses/by-sa/3.0/legalcode ✗ Os fontes deste documento estão disponíveis em: http://sergioprado.org/palestras/spse2014/linux-drivers
  3. 3. Embedded Labworks SOBRE O INSTRUTOR ✗ Sergio Prado tem mais de 18 anos de experiência em desenvolvimento de software para sistemas embarcados, em diversas arquiteturas de CPU (ARM, PPC, MIPS, x86, 68K), atuando em projetos com Linux embarcado e sistemas operacionais de tempo real. ✗ É sócio da Embedded Labworks, onde atua com consultoria, treinamento e desenvolvimento de software para sistemas embarcados: http://e-labworks.com ✗ Mantém um blog pessoal sobre Linux e sistemas embarcados em: http://sergioprado.org
  4. 4. Embedded Labworks LINUX, SIMPLES ASSIM... :)
  5. 5. Embedded Labworks Biblioteca C Hardware Biblioteca Biblioteca Aplicação User space Kernel Linux AplicaçãoAplicação Chamadas de sistema Notificação de eventos Exportação de informações Gerenciamento do hardware Notificação de eventos ARQUITETURA SISTEMAS LINUX
  6. 6. Embedded Labworks ACESSO AO HARDWARE ✗ Um papel importante do kernel é prover um mecanismo de acesso ao hardware para as bibliotecas e aplicações. ✗ No Linux, o acesso ao hardware é exportado para as aplicações através de 3 principais classes de dispositivos: ✗ Character device (dispositivo de caractere). ✗ Block Device (dispositivo de bloco). ✗ Network device (dispositivo de rede).
  7. 7. Embedded Labworks CLASSES DE DISPOSITIVOS ✗ Char device: pode ser acessado como um stream contínuo de dados (acesso sequencial), sem começo, meio e fim. É acessado através de um arquivo em /dev. Ex: porta serial, impressora, placa de som, etc. ✗ Block device: trabalha com blocos de dados, pode ser endereçável, tem começo, meio e fim. É acessado através de um arquivo em /dev. Ex: HD, CDROM, DVD, pendrive, etc. ✗ Network device: dispositivo totalmente diferente, que pode ser representado por uma interface de rede física ou por software (loopback), responsável por enviar e receber pacotes de dados através da camada de rede do kernel. Não possui um arquivo em /dev. A comunicação é feita através de uma API específica.
  8. 8. Embedded Labworks ARQUIVOS DE DISPOSITIVO ✗ Os dispositivos de caractere e bloco são representados para as aplicações através de arquivos chamados arquivos de dispositivos e armazenados no diretório /dev por convenção. ✗ Cada arquivo de dispositivo possui 3 informações básicas, que identificam internamente o dispositivo ao qual o arquivo pertence: ✗ Tipo (caractere ou bloco). ✗ Major number (categoria do dispositivo). ✗ Minor number (identificador do dispositivo).
  9. 9. Embedded Labworks ARQUIVOS DE DISPOSITIVO (cont.) ✗ Exemplos de arquivos de dispositivo: brw­r­­­­­  1 root   root  31,   0 Feb  7  2012 /dev/mtdblock0 brw­r­­­­­  1 root   root   8,   1 Feb  7  2012 /dev/sda1 crw­rw­rw­  1 root   root   4,  64 Feb  7  2012 /dev/ttyS0 crw­rw­rw­  1 root   root   4,  65 Feb  7  2012 /dev/ttyS1 crw­rw­rw­  1 root   root  29,   0 Feb  7  2012 /dev/fb0 crw­rw­rw­  1 root   root   1,   1 Feb  7  2012 /dev/mem crw­rw­rw­  1 root   root   1,   3 Feb  7  2012 /dev/null
  10. 10. Embedded Labworks CONVERSANDO COM O HARDWARE ✗ Como os dispositivos de hardware são exportados através de arquivos de dispositivo para as aplicações, o acesso ao hardware é abstraído através de uma API comum de acesso à arquivos (open, read, write, close). ✗ Exemplo de escrita na porta serial: int fd; fd = open("/dev/ttyS0", O_RDWR); write(fd, "Hello world!", 12); close(fd);
  11. 11. Embedded Labworks ACESSANDO UM ARQUIVO DE DISPOSITIVO /dev/ttyS0 major/minor Aplicação Device driver Leitura Escrita User space Kernel space Trata leitura Trata escrita
  12. 12. Embedded Labworks IMPLEMENTANDO UM CHAR DEVICE ✗ Para implementar um driver de dispositivo do tipo caractere, existem três passos principais: 1. Reservar o major number e o(s) minor number(s) do seu driver. 2. Implementar as operações em arquivo do driver (open, read, write, close, ioctl, etc). 3. Registrar o driver de dispositivo de caractere.
  13. 13. Embedded Labworks HANDS-ON Implementando um driver de dispositivo de caractere
  14. 14. Embedded Labworks DRIVER DE DISPOSITIVO DE CARACTERE SoC LED Driver /dev/led0 Kernel space User space HardwareGPIO 2.21 GPIOLIB GPIO 53 Problema 1 Problema 2 LED
  15. 15. Embedded Labworks UNIFIED DEVICE MODEL ✗ A solução para estes problemas é o modelo de desenvolvimento de drivers do kernel (Unified Device Model). ✗ Disponível a partir da versão 2.6 do kernel, provê algumas camadas de abstração para o desenvolvimento de drivers. ✗ Contém dois principais componentes: ✗ A interface exportada pelo driver é padronizada através de frameworks. ✗ A separação entre o driver e a descrição do dispositivo de hardware é realizada através de uma infraestrutura de barramento.
  16. 16. Embedded Labworks UNIFIED DEVICE MODEL (cont.) SoC LED Driver /sys/class/leds/led0/... Kernel space User space HardwareGPIO 2.21 GPIOLIB LED Framework Bus Infrastructure LED Device Description Led name = “led0” GPIO = 53
  17. 17. Embedded Labworks FRAMEWORKS Aplicação Aplicação Aplicação Interface de chamada de sistema Char driver Framebuffer core Input core TTY core Block core Framebuffer driver Input driver TTY driver Serial core IDE core SCSI core Serial driver IDE driver SCSI driver Char driver Block driver
  18. 18. Embedded Labworks ALGUNS FRAMEWORKS ✗ TTY: dispositivos seriais (porta serial RS232, porta serial RS485, conversor USB/Serial, etc). ✗ INPUT: dispositivos de entrada do usuário (mouse, teclado, touchscreen, joystick, botão, etc). ✗ FRAMEBUFFER: dispositivos de saída de vídeo (controladores de vídeo em geral para conexão com monitores e displays). ✗ ALSA: dispositivos de som (controladores de áudio, placas de som, etc).
  19. 19. Embedded Labworks LEDS ✗ Existe um framework específico para dispositivos de led. ✗ Habilitado na opção do kernel CONFIG_NEW_LEDS. ✗ Fontes disponíveis em drivers/leds/ e definição da API em <linux/leds.h>. ✗ Documentação em Documentation/leds/leds­class.txt.
  20. 20. Embedded Labworks LEDS (cont.) ✗ Implementa um diretório em /sys/class/leds/ para cada led registrado, disponibilizando alguns arquivos para manipular estes leds. $ ls /sys/class/leds/imx6:blue:power brightness  device  max_brightness   power  subsystem  trigger  uevent
  21. 21. Embedded Labworks IMPLEMENTAÇÃO ✗ Tudo o que um driver de led precisa fazer é: ✗ Definir e inicializar uma estrutura do tipo led_classdev. ✗ Prover uma função de callback para mudar o status do led. ✗ Registrar o dispositivo de led com a função led_classdev_register(). ✗ Vários exemplos disponíveis em drivers/leds/.
  22. 22. Embedded Labworks HANDS-ON Registrando o driver no framework de leds
  23. 23. Embedded Labworks INFRAESTRUTURA DE BARRAMENTO Hardware Bus adapter Bus core Framework Device driver Device Description
  24. 24. Embedded Labworks PRINCIPAIS VANTAGENS ✗ Possibilidade de separar o código do driver da descrição do dispositivo de hardware. ✗ Centralizar o acesso à determinado barramento do sistema. ✗ Capacidade de identificar hierarquicamente todos os dispositivos e barramentos conectados ao sistema, facilitando o gerenciamento de energia.
  25. 25. Embedded Labworks GERENCIAMENTO DE ENERGIA CPU PCI USB I2C PLATFORM SOUND USB ETH ACCEL E2PROM RTC DISK MODEM
  26. 26. Embedded Labworks COMPONENTES ✗ A infraestrutura de barramento é composta por: ✗ Um driver de barramento (bus core), que implementa a API para determinado barramento. ✗ Um driver adaptador (bus adapter), que implementa o driver da controladora de barramento.
  27. 27. Embedded Labworks COMPONENTES (cont.) ✗ Existe um bus core para cada tipo de barramento (USB core, SPI core, I2C core, PCI core, etc). ✗ Podem existir um ou mais drivers adaptadores, um para cada controlador de barramento existente no hardware. ✗ Durante o boot do sistema, os drivers adaptadores se registram no core do barramento.
  28. 28. Embedded Labworks REGISTRANDO OS BARRAMENTOS USB core I2C core Hardware USB0 Adapter Driver I2C0 Adapter Driver I2C1 Adapter Driver USB0 I2C0 I2C1
  29. 29. Embedded Labworks BARRAMENTO I2C ✗ Barramento de baixa velocidade para conectar dispositivos próximos ao processador (na mesma placa). ✗ Comunicação através de dois fios: SDA (dado) e SCL (clock). ✗ Barramento do tipo master/slave: ✗ Em um sistema Linux, o processador é normalmente o master. ✗ Cada slave tem um endereço associado à ele.
  30. 30. Embedded Labworks BARRAMENTO I2C Touchscreen GPIO Expander Audio codec Controladora I2C SoC addr = 0x10 addr = 0x24addr = 0x5A
  31. 31. Embedded Labworks CORE I2C ✗ O código fonte do core I2C está disponível em drivers/i2c/. ✗ Os drivers de controladoras de barramento I2C estáo disponíveis em drivers/i2c/busses/. ✗ Driver da controladora I2C da Beaglebone Black: drivers/i2c/busses/i2c­omap.c
  32. 32. Embedded Labworks DRIVERS I2C ✗ Os drivers de dispositivos I2C estão espalhados no código-fonte do kernel em drivers/, de acordo com o tipo do driver. ✗ Driver da memória E2PROM CAT24C256W da Beaglebone Black: drivers/misc/eeprom/at24.c
  33. 33. Embedded Labworks IMPLEMENTANDO O DRIVER ✗ Para implementar um driver conectado ao barramento I2C, é necessário: ✗ Definir uma estrutura do tipo i2c_device_id com a lista de dispositivos tratados por este driver. ✗ Definir uma estrutura do tipo i2c_driver com informações gerais do driver. ✗ Registrar o driver i2c com a função i2c_add_driver() na inicialização do driver. ✗ Desregistrar o driver com a função i2c_del_driver() na rotina de limpeza do driver.
  34. 34. Embedded Labworks HANDS-ON Estudando o driver da E2PROM CAT24C256W
  35. 35. Embedded Labworks PLATFORM DEVICES ✗ Alguns dispositivos podem não estar conectados em um barramento, como por exemplo uma UART ou um dispositivo conectado à um GPIO. ✗ E como prover a mesma solução de infraestrutura de barramento sem um barramento físico? ✗ Criando a sua própria infraestrutura de barramento! ✗ Esta implementação é realizada através da infraestrutura de barramento chamada de platform device.
  36. 36. Embedded Labworks IMPLEMENTANDO PLATFORM DRIVERS ✗ Um dispositivo de hardware é representado por um platform device e o driver para tratar este dispositivo é representado por um platform driver. ✗ Para implementar um platform driver, é necessário: ✗ Implementar uma estrutura do tipo platform_device_id. ✗ Definir uma estrutura do tipo platform_driver. ✗ Registrar o platform driver com a função platform_driver_register() na inicialização do driver. ✗ Desregistrar o driver com a função platform_driver_unregister() na rotina de limpeza do driver.
  37. 37. Embedded Labworks HANDS-ON Implementando um platform driver
  38. 38. Embedded Labworks NA INICIALIZAÇÃO ✗ Durante sua inicialização, o driver irá se registrar em uma infraestrutura de barramento. I2C Core at24.c i2c_add_driver() Platform Core drvled.c platform_driver_register()
  39. 39. Embedded Labworks REGISTRANDO O DISPOSITIVO ✗ A partir deste momento, o barramento saberá que existe um driver para tratar dispositivos do tipo registrado pelo driver. ✗ Mas ele não sabe (ainda) quais são os dispositivos conectados fisicamente no barramento. ✗ Para isso, você deve registrar o dispositivo no barramento. ✗ Quando você registrar o dispositivo no barramento, o driver correspondente será instanciado e o barramento chamará sua função de probe.
  40. 40. Embedded Labworks REGISTRANDO O DISPOSITIVO (cont.) ✗ Como registrar um dispositivo? ✗ Um dispositivo pode ser registrado dinamicamente pelo barramento se este possuir suporte à enumeração de dispositivos (ex: USB e PCI). ✗ Um dispositivo pode ser registrado estaticamente através de uma função disponibilizada pela infraestrutura do barramento. Ex: i2c_register_board_info(). ✗ Usando o mecanismo de device tree, disponível em algumas arquiteturas, incluindo ARM (mecanismo padrão nas versões mais atuais do kernel).
  41. 41. Embedded Labworks HANDS-ON Analisando o driver do joystick do X-Box (xpad.c)
  42. 42. Embedded Labworks REGISTRANDO DISPOSITIVO ESTATICAMENTE /* arch/arm/mach­omap2/board­omap3beagle.c */ static struct i2c_board_info __initdata beagle_i2c0_devices[] = {         {                 I2C_BOARD_INFO("24c256", 0x50),         }, }; static int __init omap3_beagle_i2c_init(void) {         [...]         i2c_register_board_info(0, beagle_i2c0_devices,                             ARRAY_SIZE(beagle_i2c0_devices));         [...] }
  43. 43. Embedded Labworks DEVICE PROBE I2C Core Driver 24c256 i2c_add_driver() at24_probe() I2C Devices Description Driver 24c256 i2c_register_board_info()
  44. 44. Embedded Labworks O MÉTODO PROBE ✗ O método probe() é responsável por: ✗ Inicializar o hardware, mapear I/O em memória e registrar ISRs. ✗ Registrar o dispositivo no framework correto do kernel. ✗ O método probe() recebe como argumento uma estrutura descrevendo o dispositivo de acordo com o barramento (i2c_client, pci_dev, usb_interface, platform_device, etc). ✗ O driver deve utilizar esta estrutura para se comunicar com o barramento.
  45. 45. Embedded Labworks HANDS-ON Descrevendo dispositivos e analisando o método probe do driver de E2PROM
  46. 46. Embedded Labworks REGISTRANDO DISPOSITIVOS NO CÓDIGO ✗ Descrever os dispositivos de hardware no código traz muitas desvantagens, dentre elas: ✗ Muito código duplicado (diferentes implementações para diferentes plataformas/placas). ✗ Qualquer alteração de hardware requer alteração do código e recompilação do kernel. ✗ Fica difícil utilizar uma mesma imagem do kernel que rode em diferentes plataformas de hardware.
  47. 47. Embedded Labworks SOLUÇÃO ✗ Precisamos então de um mecanismo para identificar a topologia e a configuração de hardware (CPU, memória e dispositivos de I/O) em tempo de execução. ✗ A solução adotada para este problema em diversas plataformas (incluindo ARM) é o Device Tree.
  48. 48. Embedded Labworks DEVICE TREE ✗ Em linhas gerais, o device tree é uma estrutura de dados capaz de descrever a topologia e a configuração do hardware presente no sistema. ✗ Foi criado originalmente pelo projeto Open Firmware, um padrão de firmware de boot desenvolvido inicialmente pela Sun. ✗ Atualmente o device tree é suportado diversas arquiteturas, incluindo ARM, PowerPC, OpenRISC, ARC e Microblaze.
  49. 49. Embedded Labworks DEVICE TREE (cont.) ✗ Com o device tree é possível descrever: ✗ O tipo e a quantidade de CPUs presentes no sistema. ✗ O endereço base e o tamanho da memória RAM. ✗ Os barramentos presentes no sistema. ✗ Os dispositivos conectados aos barramentos, além de informações específicas de cada dispositivo como linhas de interrupção, endereços de I/O, etc. ✗ O kernel Linux é capaz de usar o device tree para identificar em tempo de execução a topologia e a configuração de hardware da placa (CPU, memória e I/O), possibilitando inicializar e configurar o sistema de forma dinâmica.
  50. 50. Embedded Labworks DEVICE TREE EM ARM ✗ Cada placa ARM possui um arquivo de especificação do device tree, disponível em arch/arm/boot/dts: $ ls arch/arm/boot/dts/ aks­cdu.dts                     at91sam9x35ek.dts am335x­bone.dts                 at91sam9x5cm.dtsi am335x­evm.dts                  at91sam9x5.dtsi   am335x­evmsk.dts                at91sam9x5ek.dtsi am33xx.dtsi                     bcm11351­brt.dts  am3517­evm.dts                  bcm11351.dtsi     am3517_mt_ventoux.dts           bcm2835.dtsi      animeo_ip.dts                   bcm2835­rpi­b.dts armada­370­db.dts               ccu9540.dts       [...]
  51. 51. Embedded Labworks HANDS-ON Estudando o device tree da Beaglebone Black
  52. 52. Embedded Labworks GERANDO O DTB ✗ Uma ferramenta chamada Device Tree Compiler (dtc), disponível em scripts/dtc/, é responsável por compilar o device tree. ✗ Para compilar o device tree de todas as placas habilitadas no arquivo de configuração do kernel: $ make ARCH=arm CROSS_COMPILE=arm­linux­ dtbs ✗ Para compilar apenas o device tree da Beaglebone Black: $ make ARCH=arm CROSS_COMPILE=arm­linux­ am335x­boneblack.dtb ✗ Os arquivos DTB são gerados em arch/arm/boot/dts.
  53. 53. Embedded Labworks USANDO O DTB ✗ Durante o processo de boot, o bootloader é o responsável por passar o DTB para o kernel. ✗ Exemplo para o U-Boot: > bootm ${loadaddr} ­ ${fdt_addr} ✗ Caso o bootloader não seja capaz de passar o DTB para o kernel, é possível indicar ao kernel que o DTB está integrado à sua imagem habilitando a opção CONFIG_ARM_APPENDED_DTB, e depois gerando uma imagem com o DTB integrado: $ cat zImage board.dtb > zImage_dtb
  54. 54. Embedded Labworks HANDS-ON Driver de led com suporte ao Device Tree
  55. 55. Embedded Labworks A FLEXIBILIDADE DO DEVICE MODEL SoC LED Driver /sys/class/leds/... Kernel space User space HardwareGPIO 2.21 GPIOLIB LED Framework Platform Core LED Device Tree GPIO SoC Driver LED { GPIO 53 }
  56. 56. Embedded Labworks A FLEXIBILIDADE DO DEVICE MODEL (cont.) SoC LED Driver /sys/class/leds/... LED Framework Platform Core Device Tree I2C GPIOLIB GPIO SoC Driver GPIO Expander Driver I2C Core I2C SoC Adapter LED { GPIO 230 } EXP I/O { I2C0, 0x10 } LED GPIO Expander
  57. 57. Embedded Labworks A FLEXIBILIDADE DO DEVICE MODEL (cont.) SoC LED Driver /sys/class/leds/... LED Framework Platform Core LED GPIO Expander GPIOLIB GPIO SoC Driver GPIO Expander Driver I2C Core I2C SoC Adapter I2C Bit Banging Device Tree LED { GPIO 230 } EXP I/O { I2C1, 0x10 } I2C GPIO Adapter
  58. 58. Embedded Labworks PERGUNTAS OU COMENTÁRIOS FINAIS?
  59. 59. Embedded Labworks Por Sergio Prado. São Paulo, Novembro de 2014 ® Copyright Embedded Labworks 2004-2014. All rights reserved. OBRIGADO! E-mail sergio.prado@e-labworks.com Website http://e-labworks.com

×