Escolar Documentos
Profissional Documentos
Cultura Documentos
Embedded Labworks
Por Sergio Prado. So Paulo, Novembro de 2012 Copyright Embedded Labworks 2004-2013. All rights reserved.
Embedded Labworks
Este documento baseado no material de treinamento disponibilizado pela Free Electrons em: http://free-electrons.com/doc/training/linux-kernel Este documento disponibilizado sob a Licena Creative Commons BY-SA 3.0.
http://creativecommons.org/licenses/by-sa/3.0/legalcode
Embedded Labworks
SOBRE O INSTRUTOR
Sergio Prado tem mais de 15 anos de experincia 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. scio da Embedded Labworks, onde atua com consultoria, treinamento e desenvolvimento de software para sistemas embarcados: http://e-labworks.com Mantm um blog pessoal sobre Linux e sistemas embarcados em: http://sergioprado.org
Embedded Labworks
AGENDA DO TREINAMENTO
DIA 1: Introduo ao kernel Linux, mdulos do kernel, dispositivos de hardware, introduo ao device model, hardware I/O. DIA 2: Gerenciamento de processos, trabalhando com interrupes, mecanismos de sincronizao, kernel debugging. DIA 3: Unified Device Model, camada TTY, infraestrutura de barramento, platform driver, frameworks.
Embedded Labworks
DURANTE O TREINAMENTO
Embedded Labworks
AMBIENTE DE LABORATRIO
/opt/labs/ dl/ docs/ guides/ hardware/ training/ ex/ tools/ Ambientedelaboratrio Aplicaesepacotesopensource Queserousadosduranteas atividadesdelaboratrio Documentao Guiaselivrosdeconsulta Documentaodohardware Slideseatividadesdelaboratrio. Exercciosdelaboratrio Ferramentasdeusogeral
Embedded Labworks
Embedded Labworks
Embedded Labworks
HISTRICO
O kernel Linux um dos componentes do sistema operacional, que requer bibliotecas e aplicaes para prover funcionalidades aos usurios. Foi criado em 1991 por um estudante finlands, Linus Torvalds, e comeou a ser usado rapidamente como sistema operacional em projetos de software livre. Linus foi capaz de criar uma comunidade grande e dinmica de desenvolvedores e usurios ao redor do projeto. Atualmente, centenas de pessoas e empresas contribuem com o Linux.
Embedded Labworks
Linux 3.2
Embedded Labworks
PRINCIPAIS CARACTERSTICAS
Extremamente portvel: suporte para mais de 25 arquiteturas e milhares de dispositivos de hardware. Modular: capaz de rodar apenas o que necessrio para o projeto. Escalvel: o mesmo kernel roda em relgios, celulares e servidores da bolsa de valores! Seguro: sistema aberto, revisado por muitos experts, no tem como esconder falhas.
Embedded Labworks
Estvel: capaz de rodar por muito tempo sem precisar de um nico reboot. Compatvel com padres de mercado. Livre de royalties. Fcil de programar e com muitos recursos disponveis na Internet.
Embedded Labworks
ARQUITETURA GERAL
Aplicao Biblioteca Aplicao Biblioteca Biblioteca C Aplicao
User space
Chamadas de sistema
Notificao de eventos
Embedded Labworks
Existe uma separao bem definida entre o kernel (kernel space) e as bibliotecas e aplicaes do usurio (user space). O kernel roda em modo privilegiado, com total acesso todas as instrues da CPU, endereamento de memria e I/O, enquanto que os processos do usurio rodam em modo restrito, com acesso limitado aos recursos da mquina. Por isso, existe uma interface de comunicao, baseada chamadas de sistema (system calls), para que as bibliotecas e aplicaes tenham acesso aos recursos da mquina.
Embedded Labworks
CHAMADAS DE SISTEMA
O Linux possui aproximadamente 300 chamadas de sistema. Operaes em arquivos, operaes de rede, comunicao entre processos, gerenciamento de processos, mapeamento de memria, timers, threads, mecanismos de sincronizao, etc. As chamadas de sistema so abstradas pela biblioteca C padro. As aplicaes normalmente no precisam fazer uma chamada direta. Tudo feito atravs da biblioteca C padro. A interface de chamadas de sistema bem estvel. Durante novos releases do kernel, apenas novas chamadas de sistema podem ser adicionadas.
Embedded Labworks
ESTRUTURA INTERNA
Embedded Labworks
O Linux fortemente baseado em arquivos (quase tudo no sistema representado por um arquivo). O kernel implementa a camada VFS (Virtual Filesystem) que abstrai o acesso aos arquivos, possibilitando que rotinas de acesso ao arquivo (open, read, write, close, etc) sejam mapeadas para diferentes destinos.
Embedded Labworks
Exemplo 1: Mapeando um arquivo fsico em um dispositivo de armzenamento (copiando um arquivo do HD para um pendrive):
$cp/usr/sbin/app/mnt/pendrive/
Embedded Labworks
FONTES DO KERNEL
A verso oficial do cdigo-fonte do kernel liberada por Linus Torvalds encontra-se em: http://www.kernel.org Baixando os fontes por http:
$wgethttp://www.kernel.org/pub/linux/kernel/v3.0/linux3.6.tar.bz2 $tarxjfvlinux3.6.tar.bz2
Embedded Labworks
Fabricantes de hardware podem manter verses especficas do kernel com suporte s suas plataformas de referncia. Comunidades podem manter verses do kernel voltadas arquiteturas especficas (ARM, MIPS, PPC), sub-sistemas (USB, PCI, network), sistemas de tempo-real, etc.
Normalmente nestas verses alternativas so disponibilizados os patches para serem aplicados em uma determinada verso do kernel.
Embedded Labworks
VERSIONAMENTO
Uma rvore de verses estveis (1.0, 2.0, 2.2, 2.4) Uma rvore de verses de desenvolvimento (2.1, 2.3, 2.5)
A partir de 2003, apenas uma rvore: 2.6.X Em 2011, a verso mudou para 3.0.
Embedded Labworks
CICLO DE RELEASE
Merge window: 2 semanas (at sair 3.X-rc1). Bug fixing: 6 a 10 semanas (3.X-rc2, 3.X-rc3, etc).
Em aproximadamente 3 meses temos a liberao do release final 3.X. Para acompanhar as mudanas no kernel: http://wiki.kernelnewbies.org/LinuxChanges http://lwn.net
Embedded Labworks
LINGUAGEM DE PROGRAMAO
Implementado em linguagem C como todos os sistemas UNIX. Um pouco de assembly usado no cdigo dependente de arquitetura em /arch (cdigo de inicializao, tratamento de excees, bibliotecas crticas, etc). Nada de C++! http://www.tux.org/lkml/#s15-3 Compilado normalmente com o GCC, j que usa algumas extenses especficas deste compilador.
Suporta tambm alguns compiladores especficos com o da Intel e o da Marvell. Existe uma iniciativa para usar o Clang do projeto LLVM.
Embedded Labworks
BIBLIOTECA C PADRO
O kernel uma aplicao standalone (baremetal) e no pode usar ou ser dependente de cdigo que roda em espao de usurio. Portanto, voc no pode usar funes da biblioteca C padro (memset(), malloc(), printf(), etc). Por este motivo, o kernel tem sua prpria implementao de rotinas comuns da biblioteca C (memset(), kmalloc(), kprintf(), etc).
Embedded Labworks
PORTABILIDADE
O kernel Linux projetado para ser extremamente portvel. Todo o cdigo fora de arch/ deve ser portvel. Para isso, o kernel prov diversas funes e macros para abstrair os detalhes especficos da arquitetura, por exemplo:
Endianness (cpu_to_be32, cpu_to_le32, be32_to_cpu, le32_to_cpu). Acesso I/O mapeado em memria. Memory barriers. DMA API.
Embedded Labworks
A API interna do Linux pode mudar entre duas verses estveis do kernel. Isso significa que um driver que foi desenvolvido para uma verso do kernel pode no funcionar na prxima verso. Mais informaes em Documentation/stable_api_nonsense.txt . Sempre que um desenvolvedor alterar uma API interna do kernel, ele responsvel por atualizar todo o cdigo que acessa esta API, garantindo que nada no kernel vai parar de funcionar. Funciona muito bem para todo cdigo na rvore oficial do kernel (mainline), mas pode quebrar drivers de cdigo fechado ou fora da rvore do kernel.
Embedded Labworks
LICENA
Todo o cdigo-fonte do Linux software livre e liberado sob a licena GPLv2. Isso significa que:
Quando voc receber ou comprar um equipamento com Linux, voc tem o direito de requisitar os fontes, alter-los e redistribu-los. Quando voc desenvolver um produto com Linux, voc precisa liberar os fontes do kernel sob as mesmas condies, sem restries.
Embedded Labworks
LICENA (cont.)
Portanto, ilegal distribuir um binrio do kernel com mdulos compilados estaticamente. Os mdulos do kernels so uma rea cinza: um trabalho derivado do kernel ou no?
A opinio geral da comunidade de que drivers fechados so ruins. Sob um ponto de vista legal, cada driver provavelmente um caso diferente. Ex: Nvidia. realmente til manter um driver proprietrio?
Embedded Labworks
Voc no precisa escrever um driver do zero, podendo reusar o cdigo de outros drivers. Voc pode integrar o seu driver na rvore oficial do kernel, e no se preocupar com qualquer alterao em APIs internas do Linux. Custo zero de manuteno e melhorias no driver! Com drivers abertos voc tem suporte da comunidade, com mais pessoas revisando e colaborando com seu cdigo. Os usurios e a comunidade tem uma viso positiva da empresa.
Embedded Labworks
LABORATRIO
Embedded Labworks
Embedded Labworks
Embedded Labworks
CARACTERSTICAS
CPU i.MX535 de 1GHz da Freescale (Cortex-A8). 1GB de memria RAM DDR3. Conector para carto SD/MMC, microSD e interface SATA. Sadas de udio estreo e vdeo VGA, e entrada para microfone. Conector de expanso com sadas HDMI, display LCD, cmera e SDIO. Interfaces USB host/device, Ethernet, UART, JTAG, botes, leds, etc.
Embedded Labworks
DIAGRAMA DE BLOCOS
Embedded Labworks
DOCUMENTAO
Documentao do hardware
i.MX53 Datasheet: CPU_DS_iMX53.pdf Board reference: BOARD_DS_IMX53.pdf User's Guide: BOARD_UG_IMX53.pdf Linux BSP: BSP_LINUX_mx53.pdf / BSP_LINUX_DOCS.tar.gz
Embedded Labworks
CONECTANDO O HARDWARE
Embedded Labworks
LABORATRIO
Embedded Labworks
Embedded Labworks
CONFIGURANDO O KERNEL
O kernel possui centenas de drivers de dispositivo, diversos protocolos de rede e muitos outros itens de configurao. O kernel bem modular, so muitas as opes disponveis para serem habilitadas/desabilitadas. O processo de configurao serve para voc configurar o kernel para ser compilado para sua CPU/plataforma. O conjunto de opes que voc ir habilitar depende:
Do seu hardware (device drivers, etc). Das funcionalidades (protocolos de rede, sistemas de arquivo, etc).
Embedded Labworks
CONFIGURAO
As configuraes so salvas em um arquivo chamado .config no diretrio principal dos fontes do kernel, e possuem o formato key=value. Exemplo:
CONFIG_ARM=y
Dificilmente voc vai precisar editar o arquivo .config manualmente. Existem ferramentas de interface grfica para configurar o kernel e gerar o arquivo de configurao automaticamente:
Embedded Labworks
$ make xconfig
Embedded Labworks
$ make gconfig
Embedded Labworks
$ make nconfig
Embedded Labworks
$ make menuconfig
Embedded Labworks
O kernel um binrio nico, resultado do processo de linkagem de todos os arquivos-objeto das funcionalidades habilitadas, incluindo os device drivers. O kernel permite que algumas das funcionalidades disponveis possam ser habilitadas e compiladas de duas formas:
Esttica ou built-in: a funcionalidade selecionada linkada estaticamente imagem final do kernel. Dinmica ou mdulo: gerado um mdulo daquela funcionalidade (arquivo com extenso .ko). Este mdulo no includo na imagem final do kernel. Ele includo no sistema de arquivos e pode ser carregado dinamicamente (em tempo de execuo), conforme a necessidade.
Embedded Labworks
OPES DE CONFIGURAO
Opes de 3 estados:
<>Opodesabilitada <*>Opohabilitada(builtin) <M>Opohabilitada(mdulo)
Embedded Labworks
DEPENDNCIAS
Exemplo 1: o driver de um dispositivo I2C depende da habilitao do barramento I2C para ser habilitado. Exemplo 2: o driver do barramento USB habilitado automaticamente quando o driver de um dispositivo USB habilitado.
Embedded Labworks
Toda a configurao do kernel dependente da arquitetura. Por padro, o kernel considera um build nativo, ento ir usar a arquitetura da mquina de desenvolvimento (normalmente x86) no comando abaixo: $makemenuconfig Portanto, para configurar para ARM por exemplo, voc precisa especificar a arquitetura: $makeARCH=armmenuconfig Ao invs de passar a varivel ARCH na chamada do make, voc pode tambm defini-la como varivel de ambiente ou alterar o arquivo Makefile no diretrio principal do kernel.
Embedded Labworks
CONFIGURAES PR-DEFINIDAS
Arquivos de configurao pr-definidos para diversas plataformas esto disponveis em arch/<arch>/configs/. O uso de arquivos pr-configurados a forma padro de configurar um kernel para uma plataforma especfica. Por exemplo, para carregar a configurao padro do kit de desenvolvimento i.MX53 Quick Start Board:
$makeARCH=armimx_v6_v7_defconfig
Se voc alterou a configurao padro e deseja salv-la, pode criar uma cpia conforme exemplo abaixo:
$cp.configarch/<arch>/configs/myconfig_defconfig
Embedded Labworks
COMPILANDO O KERNEL
Depois de configurado, para compilar nativamente basta executar: $make No precisa de previlgios de root! Para cross-compilar, voc precisa indicar a arquitetura e o prefixo do cross-compiler. Exemplo: $makeARCH=armCROSS_COMPILE=armlinux O comando acima ir gerar uma imagem genrica para ARM. Se voc quiser gerar uma imagem especfica para determinado bootloader, deve adicionar ao fim do comando o nome da imagem. Exemplo para o U-Boot: $makeARCH=armCROSS_COMPILE=armlinuxuImage
Embedded Labworks
COMPILANDO OS MDULOS
Embedded Labworks
Em arch/<arch>/boot/:
Image: imagem final do kernel, inicializvel e descomprimida. *Image: imagem inicializvel e comprimida do kernel (bzImage para x86, zImage para ARM, etc). uImage: imagem do kernel para o U-Boot (opcional).
Embedded Labworks
INSTALANDO O KERNEL
Para instalar o kernel, basta executar o comando abaixo: $makeinstall Este comando ir instalar os seguintes arquivos no diretrio /boot:
vmlinuz<version> (imagem do kernel comprimida) System.map<version> (endereos dos smbolos do kernel) config<version> (arquivo de configurao do kernel)
Normalmente no usado em sistemas embarcados! Em sistemas embarcados, normalmente gravamos o kernel em um dispositivo de armazenamento (carto SD, memria flash, etc).
Embedded Labworks
INSTALANDO OS MDULOS
No caso de um ambiente de compilao cruzada, os mdulos devem ser instalados no rootfs do target. Para isso, devemos passar o parmetro INSTALL_MOD_PATH no comando de instalao:
$makeARCH=<arch>INSTALL_MOD_PATH=<dir>modules_install
Embedded Labworks
FAZENDO A LIMPEZA
Remove todos os arquivos gerados (imagens, arquivos-objeto, etc). $makeclean Remove todos os arquivos de gerados e arquivos de configurao (usado quando pretende-se mudar de plataforma). $makemrproper Alm dos arquivos gerados e arquivos de configurao, remove tambm arquivos de backup (bom para gerar patches). $makedistclean
Embedded Labworks
Ao ser carregado, o kernel pode receber um conjunto de parmetros. Chamamos esses parmetros de linha de comandos do kernel. Esta linha de comandos pode ser passada ao kernel de duas formas diferentes:
Esta linha de comandos uma string com diversas opes no formato key=value.
Embedded Labworks
console = dispositivo que ser usado como console root = dispositivo onde se encontra o sistema de arquivos rootfstype = tipo do sistema de arquivos (JFFS2)
Embedded Labworks
LABORATRIO
Embedded Labworks
Mdulos do kernel
Embedded Labworks
MDULOS
Internamente, o Linux bem modular. Cada funcionalidade abstrada em um mdulo, com uma interface de comunicao bem definida. Por isso, permite um sistema de configurao onde voc pode adicionar/remover determinada funcionalidade. E o Linux permite que voc adicione dinamicamente pedaos de cdigo do kernel em tempo de execuo! Chamamos esses pedaos de cdigo de mdulos do kernel. Um device driver pode ser compilado de forma integrada ao kernel (built-in) ou como um mdulo do kernel.
Embedded Labworks
Ajuda a manter a imagem do kernel bem pequena. Mdulos tornam fcil o desenvolvimento do kernel, como por exemplo device drivers, sem precisar reiniciar o equipamento. O tempo de boot fica menor: menos cdigo para ser executado na inicializao do kernel. Cuidado: mdulos rodam em kernel space. Uma vez carregados, eles tem total controle do sistema! Por isso s podem ser carregados como root.
Embedded Labworks
Alguns mdulos dependem de outros mdulos, que precisam ser carregados primeiro. Exemplo: o mdulo usb_storage depende do mdulo usbcore. As dependncias entre os mdulos esto descritas no arquivo /lib/modules/<kernelversion>/modules.dep . Este arquivo gerado automaticamente quando voc instala os mdulos.
Embedded Labworks
CARREGANDO UM MDULO
$insmod<module_path>.ko Carrega apenas um mdulo. necessrio passar o caminho completo do mdulo. $modprobe<module_name> Carrega um mdulo e todas as suas dependncias. Deve-se passar apenas o nome do mdulo, sem a extenso .ko e sem seu caminho completo.
Embedded Labworks
DESCARREGANDO UM MDULO
$rmmod<module_name> Descarrega apenas um mdulo. Possvel apenas se o mdulo no estiver mais em uso. Deve-se passar apenas o nome do mdulo, sem a extenso .ko e sem seu caminho completo. $modprober<module_name> Descarrega um mdulo e todas as suas dependncias (que no esto sendo usadas). Deve-se passar apenas o nome do mdulo, sem a extenso .ko e sem seu caminho completo.
Embedded Labworks
$modinfo<module_name> L informaes de um mdulo, como sua descrio, parmetros, licena e dependncias. Deve-se passar apenas o nome do mdulo, sem a extenso .ko e sem seu caminho completo. $lsmod Lista todos os mdulos carregados.
Embedded Labworks
PASSANDO PARMETROS
Descobrindo os parmetros disponveis do mdulo: $modinfo<module> Passando um parmetro via insmod: $insmod<module>param=value Para passar um parmetro via modprobe, configurar o parmetro em /etc/modprobe.conf ou em um arquivo em /etc/modprobe.d/: options<module>param=value Para passar um parmetro via linha de comandos do kernel: <module>.param=value
Embedded Labworks
LOGS DO KERNEL
Quando um novo mdulo carregado, informaes relevantes so exibidas no log do kernel. O kernel mantm um log de mensagens na memria em um buffer circular. Este log de mensagens esta disponvel atravs do comando dmesg (diagnostic message). Mensagens de log tambm so exibidas na console. Voc pode filtrar estas mensagens atravs do parmetro loglevel ou desabilitar completamente atravs do parmetro do kernel quiet.
Embedded Labworks
Embedded Labworks
#include<linux/module.h> #include<linux/kernel.h> /*moduleinitialization*/ staticint__initmymodule_init(void) { printk("Mymoduleinitialized.\n"); return0; } /*moduleexit*/ staticvoid__exitmymodule_exit(void) { printk("Exitingmymodule.\n"); } module_init(mymodule_init); module_exit(mymodule_exit); MODULE_LICENSE("GPL");
Embedded Labworks
O PRIMEIRO MDULO
A macro module_init() declara a funo de inicializao que ser chamada ao carregar o mdulo para a memria. A funo de inicializao nomeada de acordo com o padro <modulename>_init(), responsvel por inicializar o mdulo e retornar 0 para OK ou um valor negativo em caso de erro. removida da memria assim que executada. A macro module_exit() declara a funo de limpeza, que ser chamada assim que o mdulo for descarregado da memria. Se o mdulo for compilado estaticamente, esta funo no utilizada, e por este motivo, nem carregada para a memria.
Embedded Labworks
METADADOS DO MDULO
Voc pode declarar informaes (metadados) dos mdulos usando as seguintes macros:
Mensagem
descritiva
do
mdulo
(apenas informativa).
Embedded Labworks
EXPORTANDO SMBOLOS
De dentro de um mdulo, apenas um nmero limitado de funes e variveis globais do kernel podem ser acessadas. As funes e variveis precisam ser exportadas explicitamente para serem usadas externamente, e isso pode ser feito atravs de duas macros:
Embedded Labworks
COMPILANDO UM MDULO
Quando o cdigo do mdulo esta fora do diretrio dos fontes do kernel. Fcil de gerenciar, mas no permite compilar um mdulo estaticamente (built-in). Quando o cdigo do mdulo esta dentro do diretrio dos fontes do kernel. Permite compilar um mdulo estaticamente ou dinamicamente.
Embedded Labworks
Embedded Labworks
VERSO DO KERNEL
Para ser compilado, um mdulo do kernel precisa acessar os arquivos de cabealho (headers) do kernel. Para isso, temos duas opes:
Um mdulo compilado com uma verso X dos headers do kernel no carregado em um kernel com verso Y.
Embedded Labworks
Para integrar um driver nos fontes do kernel, primeiro adicione o arquivo-fonte em um diretrio apropriado. Exemplo:
drivers/serial/8250.c
Descreva a configurao do driver no arquivo Kconfig disponvel no diretrio onde o fonte do driver foi adicionado:
Embedded Labworks
Execute makemenuconfig para habilitar a nova opo. Execute make ou makemodules para compilar. Mais informaes em Documentation/kbuild/.
Embedded Labworks
RECEBENDO PARMETROS
#include<linux/moduleparam.h> /*moduleparametermacro*/ module_param( name, /*nameofanalreadydefinedvariable*/ type, /*eitherbyte,short,ushort,int,uint, long,ulong,charp,orbool. (checkedatcompiletime!)*/ perm /*visibilityinsysfsat /sys/module/<module_name>/parameters/<param> seelinux/stat.h*/ ); /*example*/ intqtd=5; module_param(qtd,int,S_IRUGO);
Embedded Labworks
LABORATRIO
O primeiro mdulo
Embedded Labworks
Dispositivos de hardware
Embedded Labworks
DISPOSITIVOS
Um papel importante do kernel prover um mecanismo de acesso ao hardware para as bibliotecas e aplicaes. No Linux, o acesso ao hardware exportado para as aplicaes atravs de 3 principais classes de dispositivos:
Character device (dispositivo de caractere). Block Device (dispositivo de bloco). Network device (dispositivo de rede).
Embedded Labworks
CLASSES DE DISPOSITIVOS
Char device: pode ser acessado como um stream contnuo de dados (acesso sequencial), sem comeo, meio e fim. acessado atravs de um arquivo em /dev. Ex: porta serial, impressora, placa de som, etc. Block device: trabalha com blocos de dados, pode ser enderevel, tem comeo, meio e fim. acessado atravs 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 fsica ou por software (loopback), responsvel por enviar e receber pacotes de dados atravs da camada de rede do kernel. No possui um arquivo em /dev. A comunicao feita atravs de uma API especfica.
Embedded Labworks
ARQUIVOS DE DISPOSITIVO
Os dispositivos de caractere e bloco so representados para as aplicaes atravs de arquivos chamados arquivos de dispositivos e armazenados no diretrio /dev por conveno. Cada arquivo de dispositivo possui 3 informaes bsicas, que identificam internamente o dispositivo ao qual o arquivo pertence:
Tipo (caractere ou bloco). Major number (categoria do dispositivo). Minor number (identificador do dispositivo).
Embedded Labworks
Embedded Labworks
Como os dispositivos de hardware so exportados atravs de arquivos de dispositivo para as aplicaes, o acesso ao hardware abstrado atravs de uma API comum de acesso arquivos (open, read, write, close). Exemplo de escrita na porta serial:
intfd; fd=open("/dev/ttyS0",O_RDWR); write(fd,"Helloworld!",12); close(fd);
Embedded Labworks
major/minor
Kernel space Trata leitura Trata escrita Device driver
Embedded Labworks
Os arquivos de dispositivo podem ser criados manualmente: $mknod/dev/<device>[c|b]majorminor Neste caso, preciso conhecer o major/minor number definido no driver do dispositivo, alm de ter previlgios de root. Porm, o mais comum a utilizao de mecanismos automticos de criao dos arquivos de dispositivo:
devtmpfs: virtual filesystem do Linux, disponvel deste a verso 2.6.32. udev: daemon, soluo usada em desktop e servidores. mdev: programa disponvel no Busybox, verso mais leve do udev.
Embedded Labworks
DISPOSITIVOS DE CARACTERE
Com exceo dos drivers para dispositivos de armazenamento, a maioria dos drivers so implementados como um driver de dispositivo de caractere. Portanto, a maioria dos drivers que voc ir desenvolver ser do tipo caractere.
Embedded Labworks
Para implementar um driver de dispositivo do tipo caractere, existem trs passos principais:
1. Reservar o major number e o(s) minor number(s) do seu driver. 2. Implementar as operaes que sero disponibilizadas aos usurios do seu driver (open, read, write, close, etc) e associar estas operaes uma estrutura do tipo file_operations. 3. Associar o major e o minor number alocados sua estrutura de operaes de arquivo e registrar o dispositivo de caractere.
Embedded Labworks
DEVICE NUMBER
O primeiro passo para desenvolver um driver de dispositivo de caractere ou bloco registrar um device number para o driver do dispositivo. O device number composto por dois nmeros chamados de major number e minor number. O kernel armazena as informaes de major e minor number no tipo de dados dev_t. O tipo de dados dev_t esta definido em <linux/types.h> e atualmente representado com 32 bits, onde os 12 bits mais significativos representam o major e os 20 bits restantes representam o minor.
Embedded Labworks
Embedded Labworks
REGISTRANDO ESTATICAMENTE
O major number e o minor number podem ser registrados estaticamente ou dinamicamente. Voc estaticamente register_chrdev_region(). pode registrar atravs da funo
Embedded Labworks
FUNO register_chrdev_region()
#include<linux/fs.h> /*allocatedevicenumberstatically*/ intregister_chrdev_region(dev_tfrom, unsignedcount, constchar*name); /*example*/ staticdev_tmydriver_dev=MKDEV(202,128); if(register_chrdev_region(mydriver_dev,4,mydriver)){ pr_err("Failedtoallocatedevicenumber\n"); [...] }
Embedded Labworks
Como voc pode no saber quais dispositivos esto presentes no sistema, pode haver conflito ao tentar alocar estaticamente um major ou minor number j usado por outro dispositivo. Portanto, o melhor alocar dinamicamente com a funo alloc_chrdev_region().
Embedded Labworks
FUNO alloc_chrdev_region()
#include<linux/fs.h> /*allocatedevicenumberdynamically*/ intalloc_chrdev_region(dev_t*dev, unsignedbaseminor, unsignedcount, constchar*name); /*example*/ staticdev_tmydriver_dev; if(alloc_chrdev_region(&mydriver_dev,0,1,"mydriver")){ pr_err("Failedtoallocatedevicenumber\n"); [...] }
Embedded Labworks
Embedded Labworks
Para implementar um driver de dispositivo do tipo caractere, existem trs passos principais:
1. Reservar o major number e o(s) minor number(s) do seu driver. 2. Implementar as operaes que sero disponibilizadas aos usurios do seu driver (open, read, write, close, etc) e associar estas operaes uma estrutura do tipo file_operations. 3. Associar o major e o minor number alocados sua estrutura de operaes de arquivo e registrar o dispositivo de caractere.
Embedded Labworks
FILE OPERATIONS
A estrutura file_operations (tambm chamada de fops) contm todas as operaes implementadas pelo device driver. Como ela genrica para todos os arquivos gerenciados pelo kernel, nem todas as operaes definidas nesta estrutura so necessrias para um driver de dispositivo de caractere.
Embedded Labworks
ESTRUTURA file_operations
#include<linux/fs.h> /*mostimportantfileoperationsforachardevice*/ structfile_operations{ [...] ssize_t(*read)(structfile*,char__user*,size_t,loff_t*); ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*); long(*unlocked_ioctl)(structfile*,unsignedint,unsignedlong); int(*open)(structinode*,structfile*); int(*release)(structinode*,structfile*); [...] };
Embedded Labworks
FUNO open()
intfoo_open(structinode*i,structfile*f);
Chamada quando o arquivo de dispositivo aberto. A estrutura inode uma representao nica do arquivo no sistema (seja ele um arquivo comum, diretrio, link, dispositivo de caractere ou bloco, etc). Uma estrutura do tipo file criada toda vez que um arquivo aberto.
Armazena informaes como a posio corrente do arquivo, modo de abertura, etc. Tem um ponteiro chamado private_data que pode ser usado livremente pelo driver, j que todas as outras operaes recebem este ponteiro.
Embedded Labworks
FUNO release()
intfoo_release(structinode*i,structfile*f);
Chamada quando o arquivo de dispositivo fechado. As estruturas inode e file so as mesmas da funo open().
Embedded Labworks
FUNO read()
ssize_tfoo_read(structfile*f,__userchar*buf, size_tsz,loff_t*off);
Chamada quando realizada uma operao de leitura no arquivo de dispositivo. O driver dever:
Ler at sz bytes do dispositivo. Salvar os dados lidos no buffer buf. Atualizar a posio atual do arquivo na varivel off. Retornar a quantidade de bytes lidos.
Em sistemas UNIX, a operao de leitura normalmente bloqueia enquanto no houver bytes suficientes para serem lidos do dispositivo.
Embedded Labworks
FUNO write()
ssize_tfoo_write(structfile*f,__userconstchar*buf, size_tsz,loff_t*off);
Chamada quando realizada uma operao de escrita no arquivo de dispositivo. O driver dever:
Ler sz bytes do buffer buf. Escrever os dados lidos no dispositivo. Atualizar a posio atual do arquivo na varivel off. Retornar a quantidade de bytes escritos.
Embedded Labworks
Um cdigo do kernel no pode acessar diretamente uma regio de memria de espao de usurio, seja desreferenciando um ponteiro ou usando funes do tipo memcpy().
O endereo de memria virtual pode no estar mapeado. Se o endereo passado invlido, acontecer erro de segmentao de memria (segfault) e o kernel matar o processo.
Portanto, para manter o cdigo do driver portvel e seguro, o driver precisa usar algumas funes especficas para trocar dados com o espao de usurio.
Embedded Labworks
Embedded Labworks
FUNO copy_to_user()
#include<asm/uaccess.h> /*Copynbytesfromkernelbuffertouserbuffer. Return0onsuccessoranegativenumberonerror. */ unsignedlongcopy_to_user(void__user*to, constvoid*from, unsignedlongn); /*example*/ if(copy_to_user(user_buf,kernel_buf,qtd)){ pr_err("Errorcopyingtouserbuffer...\n"); [...] }
Embedded Labworks
FUNO copy_from_user()
#include<asm/uaccess.h> /*Copynbytesfromuserbuffertokernelbuffer. Return0onsuccessoranegativenumberonerror. */ unsignedlongcopy_from_user(void*to, constvoid__user*from, unsignedlongn); /*example*/ if(copy_from_user(kernel_buf,user_buf,qtd)){ pr_err("Errorcopyingfromuserbuffer...\n"); [...] }
Embedded Labworks
OUTROS MTODOS
Dependendo da quantidade de dados e do fluxo de comunicao, o uso das funes de troca de dados entre kernel e espao de usurio pode impactar a performance do sistema. Para estes casos, existem solues alternativas onde no necessrio realizar a cpia dos buffers (zero copy):
Implementar a operao mmap() para permitir que um cdigo rodando em espao de usurio tenha acesso direto memria do dispositivo. Usar a funo get_user_pages() para mapear direto uma pgina de memria do usurio ao invs de copi-la.
Embedded Labworks
EXEMPLO read()
staticssize_tmydriver_read(structfile*file,char__user*buf, size_tcount,loff_t*ppos) { intremaining_size,transfer_size; remaining_size=mydriver_bufsize(int)(*ppos); /*checkifEOF*/ if(remaining_size==0){ return0; } /*Sizeofthistransfer*/ transfer_size=min_t(int,remaining_size,count); if(copy_to_user(buf,mydriver_buf+*ppos,transfer_size)){ returnEFAULT; }else{ *ppos+=transfer_size; returntransfer_size; } }
Embedded Labworks
EXEMPLO write()
staticssize_tmydriver_write(structfile*file,constchar__user*buf, size_tcount,loff_t*ppos) { intremaining_bytes; remaining_bytes=mydriver_bufsize(*ppos); if(count>remaining_bytes){ returnEIO; } if(copy_from_user(mydriver_buf+*ppos,buf,count)){ returnEFAULT; }else{ *ppos+=count; returncount; } }
Embedded Labworks
FUNO unlocked_ioctl()
longunlocked_ioctl(structfile*f,unsignedintcmd, unsignedlongarg);
Esta operao esta associada chamada de sistema ioctl(). Permite estender as capacidades do driver alm da API de leitura e escrita em arquivos. Exemplos de utilizao em drivers: configurar o baud rate de uma porta serial, configurar a resoluo de uma placa de vdeo, etc. O comando a ser executado passado no parmetro cmd, e pode-se usar o parmetro arg para passar alguma informao adicional. A semntica dos argumentos cmd e arg especfica de cada driver.
Embedded Labworks
EXEMPLO unlocked_ioctl()
staticlongphantom_ioctl(structfile*file,unsignedintcmd, unsignedlongarg) { structphm_regr; void__user*argp=(void__user*)arg; switch(cmd){ casePHN_SET_REG: if(copy_from_user(&r,argp,sizeof(r))) returnEFAULT; /*dosomething*/ break; casePHN_GET_REG: if(copy_to_user(argp,&r,sizeof(r))) returnEFAULT; /*dosomething*/ break; default: returnENOTTY; } return0; }
Embedded Labworks
Embedded Labworks
Para definir a estrutura de operaes em arquivo, basta declar-la e inicializ-la com os ponteiros para as operaes que voc implementou. Exemplo:
#include<linux/fs.h> staticstructfile_operationsacme_fops= { .owner=THIS_MODULE, .read=acme_read, .write=acme_write, };
Embedded Labworks
Para implementar um driver de dispositivo do tipo caractere, existem trs passos principais:
1. Reservar o major number e o(s) minor number(s) do seu driver. 2. Implementar as operaes que sero disponibilizadas aos usurios do seu driver (open, read, write, close, etc) e associar estas operaes uma estrutura do tipo file_operations. 3. Associar o major e o minor number alocados sua estrutura de operaes de arquivo e registrar o dispositivo de caractere.
Embedded Labworks
O kernel representa um dispositivo de caractere com a estrutura cdev. Para registrar um dispositivo de caractere, primeiro declare globalmente uma estrutura do tipo cdev e inicialize-a chamando a funo cdev_init(). Depois s adicionar o dispositivo de caractere ao sistema com a funo cdev_add(). Depois desta chamada, o kernel associar o major/minor number registrado com as operaes em arquivo definidas. Seu dispositivo esta pronto para ser usado!
Embedded Labworks
Embedded Labworks
DESREGISTRANDO
Na funo de limpeza do driver necessrio desregistrar o dispositivo de caractere. Para isso, primeiro remova o dispositivo de caractere com a funo cdev_del(). E depois libere o major/minor number alocado com a funo unregister_chrdev_region().
Embedded Labworks
Embedded Labworks
Regra geral: sempre trate o retorno das funes e retorne um cdigo de erro compatvel com o problema apresentado. Os cdigos de erro padro esto disponveis em:
asmgeneric/errnobase.h asmgeneric/errno.h
Embedded Labworks
SUMRIO
Defina e implemente as operaes de arquivo do driver (open, read, write, close, ioctl, etc). Declare a estrutura file_operations e inicialize-a com os ponteiros das operaes de arquivo implementadas. Na funo de inicializao do mdulo, reserve o major/minor number com a funo register_chrdev_region(), inicialize a estrutura cdev com a funo cdev_init() e adicione no sistema com cdev_add(). Na funo de limpeza do mdulo, desregistre o dispositivo de caractere com dev_del() e depois desregistre o major/minor number com a funo unregister_chrdev_region().
Embedded Labworks
LABORATRIO
O primeiro driver
Embedded Labworks
DISPOSITIVOS NO KERNEL
Durante os testes do driver desenvolvido, foi necessrio criar o arquivo de dispositivo manualmente. Como tornar a criao de um arquivo de dispositivo automtica? Temos duas opes:
Delegar para o kernel a criao dos arquivos de dispositivo. Isso possvel atravs do devtmpfs. Fazer com que o kernel gere um evento toda vez que um dispositivo de hardware for registrado no sistema. Uma aplicao como o udev ou o mdev pode capturar estes eventos e cuidar da criao dos arquivos de dispositivo.
Embedded Labworks
Kernel space
devtmpfs
Dispositivo identificado
2
User space
/dev
Embedded Labworks
DEVICE MODEL
Para ambos os casos funcionarem, o dispositivo precisa fazer parte do modelo de dispositivos (device model) do kernel. O device model prov um mecanismo nico para representar os dispositivos de hardware e sua topologia no sistema. O device model nada mais do que um conjunto de objetos do kernel, chamados internamente de kobjects. Estes objetos so conectados entre si, e formam uma hierarquia de dispositivos e barramentos conectados ao sistema.
Embedded Labworks
SYSFS
O sysfs basicamente um sistema de arquivo virtual que exporta esta hierarquia de objetos para user space. Por este motivo, no sysfs podemos colher informaes sobre os dispositivos de hardware conectados ao sistema. montado normalmente normalmente no diretrio /sys:
$mounttsysfsnone/sys
Embedded Labworks
SYSFS (cont.)
sistema.
bus: Dispositivos classificados por barramento (spi, pci, usb, etc). class: Dispositivos classificados por tipo (net, input, block, etc). dev: Dispositivos classificados por major e minor number.
Embedded Labworks
REGISTRANDO O DISPOSITIVO
Para registrar um dispositivo no device model do kernel, precisamos primeiro criar uma classe com a funo class_create() e depois registrar o dispositivo com a funo device_create(). Da mesma forma, para desregistrar o dispositivo precisamos remov-lo com a funo device_destroy() e depois destruir a classe com a funo class_destroy().
Embedded Labworks
DEVICE API
#include<linux/device.h> /** *class_createcreateastructclassstructure */ structclass*class_create(structmodule*owner, constchar*name); /** *device_createcreatesadeviceandregistersit *withsysfs */ structdevice*device_create(structclass*class, structdevice*parent, dev_tdevt,void*drvdata, constchar*fmt,...);
Embedded Labworks
Embedded Labworks
Embedded Labworks
DEVICE API
#include<linux/device.h> staticstructclass*cosa_class; staticvoid__exitcosa_exit(void) { [...] device_destroy(cosa_class,MKDEV(cosa_major,0)); class_destroy(cosa_class); [...] }
Embedded Labworks
UEVENT
Na chamada device_create() ou qualquer outra funo que altere a hierarquia de dispositivos conectados ao sistema, o kernel ir gerar um evento, chamado de uevent. Este evento comunicado para user space atravs de um netlink socket (socket multicast especfico para comunicao entre kernel e user space). Um daemon rodando em user space pode escutar estes eventos e trat-los. isso que faz o udevd (daemon do udev).
Embedded Labworks
UDEV
O udev o gerenciador padro de dispositivos do Linux, presente na maioria das distribuies. composto por um conjunto de ferramentas e daemons como o udevd e o udevinfo. Seu comportamento pode ser configurvel atravs de um conjunto de regras armazenadas em /etc/udev/rules.d/.
Embedded Labworks
HOTPLUG
Kernel space
device_create()
Device Driver
User space
/dev
udevd
Consulta regras
Embedded Labworks
COLDPLUG
Mas o que acontece com os dispositivos que foram identificados e registrados no boot do sistema, quando o daemon do udev ainda no estava rodando? a que o sysfs tem um papel importante na soluo. Durante o boot, o kernel cria um arquivo chamado uevent para cada dispositivo criado no sistema. O udev varre o sysfs procurando por estes arquivos e gera os eventos correspondentes, como se eles estivessem acontecendo naquele momento.
Embedded Labworks
Alm da capacidade de criar os arquivos de dispositivo no /dev, o udev tem ainda outras funcionalidades:
Diferenciar dispositivos e executar qualquer comando, script ou aplicao para determinado dispositivo. Carregar firmware. Carregar mdulos do kernel (para dispositivos conectados em barramentos que suportam hotplug).
Embedded Labworks
MDEV
O mdev uma implementao de gerenciador de dispositivos mais leve presente no Busybox. Tem os mesmos objetivos do udev, porm menos flexvel. Ele capaz de:
Criar dinamicamente arquivos de dispositivo. Executar comandos especficos para cada dispositivo conectado. Realizar a carga de firmware.
Embedded Labworks
DEVTMPFS
O devtmpfs um sistema de arquivo virtual que permite delegar ao kernel o gerenciamento dos arquivos de dispositivo. Esta funcionalidade habilitada na opo CONFIG_DEVTMPFS. Com esta opo habilitada, s montar no /dev o sistema de arquivo devtmpfs:
$mounttdevtmpfsnone/dev
Para o kernel montar este sistema de arquivo automaticamente no boot, habilite a opo CONFIG_DEVTMPFS_MOUNT.
Embedded Labworks
MISC DRIVERS
Misc (miscellaneous) drivers so drivers de dispositivo de caractere que compartilham algumas caractersticas em comum. O kernel abstrai estas caractersticas comuns em uma API (implementao em drivers/char/misc.c). Todos os misc drivers possuem o major number 10, e cada um tem seu minor number. Quando usar? Drivers de dispositivo de caractere bem simples, que precisam de apenas um minor number. Por exemplo, muitos drivers de watchdog (em drivers/watchdog) so implementados atravs de misc drivers.
Embedded Labworks
Alocar o major/minor number, usando por exemplo a funo alloc_chrdev_region(). Criar o dispositivo de caractere com as funes cdev_init() e cdev_add(). Registrar o dispositivo de caractere no device model com as funes class_create() e device_create().
Um misc driver substitui todo este processo apenas pela chamada funo misc_register().
Embedded Labworks
Embedded Labworks
CHAR DRIVER
staticint__initbtn_init(void) { [...] result=alloc_chrdev_region(&btn_dev,0,1,DEVICE_NAME); [...] cdev_init(&btn_cdev,&btn_fops); result=cdev_add(&btn_cdev,btn_dev,1); [...] btn_class=class_create(THIS_MODULE,DEVICE_NAME); device_create(btn_class,NULL,MKDEV(MAJOR(btn_dev),0), "btn"); [...] }
Embedded Labworks
MISC DRIVER
#include<linux/miscdevice.h> staticstructmiscdevicebtn_dev={ MISC_DYNAMIC_MINOR, "btn", &btn_fops }; staticint__initbtn_init(void) { [...] result=misc_register(&btn_dev); [...] }
Embedded Labworks
LABORATRIO
Registrando o dispositivo
Embedded Labworks
Gerenciamento de memria
Embedded Labworks
MEMRIA
O desenvolvimento de alguns tipos de drivers, principalmente aqueles que precisam de performance, requerem um conhecimento maior de como o sub-sistema de memria virtual do Linux funciona. O sub-sistema de memria virtual no Linux fortemente apoiado em componente de hardware chamado MMU. A MMU (Memory Management Unit) o hardware que implementa o mecanismo de memria virtual, gerenciando a memria do sistema e fazendo a converso entre endereos de memria fsicos e virtuais.
Embedded Labworks
CPU
Endereo virtual
MMU
Endereo fsico
Memria
Embedded Labworks
VANTAGENS DA MMU
Maior endereamento de memria para os processos: em uma arquitetura de 32 bits, os processos podem ter acesso um endereamento linear de at 3G de memria virtual. Proteo: cada processo s enxerga seu espao de endereamento, onde um acesso invlido gera uma exceo. Memory mapping: possibilidade de mapear um arquivo fsico em memria. Compartilhamento: os processos podem compartilhar memria (cdigo, dados, etc), usado por exemplo em mecanismos de IPC. SWAP: se faltar memria fsica, possibilita salvar e recuperar pginas de memria do disco.
Embedded Labworks
Esta diviso configurada em tempo de compilao no kernel em MemorySplit, com trs opes 1G/3G, 2G/2G e 3G/1G. Por exemplo, um sistema de 32 bits consegue enderear at 4G de memria virtual. Se configurado com 3G/1G, temos 1G de memria enderevel pelo kernel e 3G de memria enderevel pelos processos.
Embedded Labworks
Kernel
1GB do endereamento de memria virtual reservado para o kernel, contendo o cdigo do kernel e suas estruturas de dados principais. 3GB do endereamento de memria virtual reservado para cada processo, para armazenar cdigo, dados (stack, heap, etc), arquivos mapeados em memria, etc. No necessariamente um endereo virtual reservado para um processo pode estar mapeado para um endereo fsico!
0xC0000000
Processo 1
0x00000000
Embedded Labworks
Kernel
2GB do endereamento de memria virtual reservado para o kernel, contendo o cdigo do kernel e suas estruturas de dados principais. 2GB do endereamento de memria virtual reservado para cada processo, para armazenar cdigo, dados (stack, heap, etc), arquivos mapeados em memria, etc. No necessariamente um endereo virtual reservado para um processo pode estar mapeado para um endereo fsico!
0x80000000
Processo 1
0x00000000
Embedded Labworks
Kernel
0xC0000000
Processo 1
0x00000000
RAM
CPU
0xFFFFFFFF
MMU I/O
Kernel
0xC0000000
Processo 2
0x00000000
Flash
Embedded Labworks
MEMRIA FSICA
Apesar de a menor unidade de memria enderevel pela CPU seja um byte ou uma palavra (word), o kernel divide a memria fsica em pginas de memria. Isso porque, para gerenciar a memria e realizar a converso de endereos virtuais para endereos fsicos, a MMU divide a memria em pginas e mantm uma tabela de pginas de memria do sistema. O tamanho de uma pgina de memria pode variar dependendo da arquitetura (tipicamente 4K em arquiteturas de 32 bits e 8K em arquiteturas de 64 bits). Isso significa que, em um sistema de 32 bits, com pginas de 4K e 1G de memria fsica, teremos 262.144 pginas fsicas de memria.
Embedded Labworks
ZONAS DE MEMRIA
ZONE_DMA e ZONE_DMA32: pginas de memria para operaes de DMA. ZONE_NORMAL: pginas de memria mapeadas normalmente no espao do kernel. ZONE_HIGHMEM: pginas de memria que no podem ser mapeadas no espao de endereamento do kernel. So alocadas dinamicamente, conforme a necessidade.
Desta forma, quando por exemplo um driver precisa alocar memria para realizar uma operao de DMA, ele ir alocar de ZONE_DMA. O uso e o layout das zonas de memria so totalmente dependentes de arquitetura.
Embedded Labworks
Kernel
0xC0000000 0x80000000
Embedded Labworks
A memria para os processos alocada das zonas ZONE_HIGHMEM (se existente) ou ZONE_NORMAL. Durante uma alocao de memria para um processo, o kernel no necessariamente aloca fisicamente esta pgina para o processo. Neste caso, o kernel pode usar uma funcionalidade chamada demand fault paging para alocar dinamicamente uma pgina de memria, atravs da exceo page fault gerada pela MMU quando o processo tentar acessar esta regio de memria.
Embedded Labworks
permitido uma aplicao alocar mais memria do que a disponvel fisicamente no sistema (mas pode levar falta de memria). Neste caso, o OOM Killer (Out of Memory Killer) entra em ao e seleciona um processo para matar e ganhar um pouco mais de memria (melhor do que travar!)
Embedded Labworks
Alocao de memria
Embedded Labworks
ALOCANDO MEMRIA
de alocao de memria, permitindo alocar objetos menores que uma pgina de memria.
Embedded Labworks
Cdigo do kernel
kmalloc()
vmalloc()
SLAB Allocator
Page allocator
Embedded Labworks
PAGE ALLOCATOR
Apropriado para alocaes de grandes regies de memria (maiores que 128K). Trabalha com alocao de pginas de memria (normalmente 4K em 32 bits) e trabalha apenas em potncia de 2 (1 pgina, 2 pginas, 4 pginas, 8 pginas, etc). Aloca no mximo 8MB ( possvel mudar este valor na configurao do kernel). Aloca uma regio de memria virtual contnua, e tambm fisicamente contnua (o que pode ser um problema se a memria estiver muito fragmentada).
Embedded Labworks
Embedded Labworks
FLAGS
DMA.
Embedded Labworks
SLAB ALLOCATOR
Camada que usa a API da page allocator para criar um cache de alocao de memria, permitindo alocar objetos menores que o tamanho de uma pgina de memria. Existem trs implementaes da camada SLAB (todas implementam a mesma API):
SLAB: verso original. SLOB: mais simples, economiza espao, mas no escala bem. SLUB: mecanismo padro a partir da verso 2.6.23. Simples e escala melhor que o SLAB, gerando menos fragmentao de memria.
Sua API usada internamente no kernel (vide <linux/slab.h>), mas dificilmente ser usada em um driver comum.
Embedded Labworks
KMALLOC
Em um driver comum, o mecanismo padro de alocao atravs da funo kmalloc(). Permite objetos de 8 bytes a 128KB /proc/slabinfo,necessrio habilitar SLUB_DEBUG). alocar (vide
A rea alocada ser fisicamente contnua e arredondada potncia de 2. Usa os mesmos flags do page allocator (GFP_KERNEL, GFP_ATOMIC, GFP_DMA, etc), e com a mesma semntica.
Embedded Labworks
KMALLOC API
#include<linux/slab.h> /*allocatesizebytesandreturnapointer tothearea(virtualaddress)*/ void*kmalloc(size_tsize,intflags); /*freeanallocatedarea*/ voidkfree(constvoid*objp); /*example*/ structib_update_work*work; work=kmalloc(sizeof*work,GFP_ATOMIC); [...] kfree(work);
Embedded Labworks
Embedded Labworks
VMALLOC ALLOCATOR
Permite alocar um endereo de memria virtual contnuo, mas no fisicamente contnuo. Permite alocaes de grandes reas de memria j que no sofre de problemas de fragmentao, mas no pode ser usado para regies de memria de DMA, que requer uma regio de memria fisicamente contnua.
Embedded Labworks
Embedded Labworks
KMEMCHECK:
verifica dinamicamente por memria no inicializada, apenas disponvel no x86 (32/64 bits). Documentao em:
Documentation/kmemcheck.txt DEBUG_KMEMLEAK:
verifica dinamicamente por memory leaks, disponvel em todas as arquiteturas. Documentao em:
Documentation/kmemleak.txt
Embedded Labworks
Hardware I/O
Embedded Labworks
ACESSANDO I/O
Existem basicamente dois mecanismos de acesso I/O, de acordo com a arquitetura da CPU:
Memory-mapped I/O: quando a CPU utiliza o mesmo barramento de endereos para enderear memria e I/O. Neste caso, o acesso realizado normalmente atravs de instrues de acesso memria. o mecanismo mais usado por diferentes arquiteturas suportadas pelo Linux. Port I/O: quando a CPU utiliza barramentos de endereos diferentes para acessar memria e I/O. Neste caso, o acesso I/O realizado atravs do uso de instrues especiais da CPU (ex: instrues IN e OUT na arquitetura x86).
Embedded Labworks
PORT I/O
Antes de usar um port I/O, o driver deve requisitar ao kernel a regio de I/O que deseja usar com a funo request_region(). Voc pode listar todos os I/Os registrados pelos drivers no arquivo /proc/ioports. Isso evita que outros drivers usem a mesma regio de I/O (mas um procedimento puramente voluntrio). Depois de usada, a regio de I/O deve ser liberada com a funo release_region().
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
MEMORY-MAPPED I/O
O primeiro passo para o uso de memory-mapped I/O requisitar a regio de I/O para o kernel atravs da funo request_mem_region(), normalmente chamada na inicializao do device driver. Esta funo ir registrar o uso de determinada regio de I/O mapeada em memria. Em /proc/iomem temos todas as regies de I/O mapeadas em memria j reservadas no kernel. Ao driver, devemos chamar a funo release_mem_region() para notificar o kernel de que esta regio de I/O mapeado em memria esta livre para uso. descarregar o
Embedded Labworks
Embedded Labworks
Embedded Labworks
O kernel s trabalha com memria virtual! Portanto, para acessar um endereo de memria correspondente determinado I/O, precisamos converter o endereo fsico desta porta de I/O em um endereo virtual antes de us-lo. Isso pode ser feito com a funo ioremap().
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Existe uma nova API para acessar dispositivos de I/O de forma transparente, seja port I/O ou memory-mapped I/O. Alguns drivers usam esta funcionalidade, mas parece no existir ainda um consenso se todos os drivers devem ser desenvolvidos/migrados para este novo mecanismo.
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
MEMORY BARRIERS
Imagine que, para acessar um byte de uma E2PROM, voc precise configurar o endereo que deseja acessar no registrador A e depois fazer a leitura no registrador B. Para ler o byte do endereo 8 ficaria assim:
A=8;//setaddress x=B;//readbyte
Neste exemplo, a ordem de execuo das instrues extremamente importante, mas para a CPU ou para o compilador, elas parecem ser totalmente independentes e podem ser executadas em qualquer ordem!
Embedded Labworks
Portanto, o compilador ou a CPU podem reordenar a execuo das instrues ou o acesso memria (desde que no influenciem a operao aparente do programa em execuo). Existe uma tcnica chamada Memory Barriers para previnir este tipo de problema.
A=5;//setaddress insert_barrier();//insertmemorybarrier x=B;//readbyte
Embedded Labworks
A API do kernel prov algumas funes que funcionam como memory barriers:
no funcionamento do hardware.
rmb(): memory barrier para leitura. wmb(): memory barrier para escrita. mb(): memory barrier para leitura e escrita.
Embedded Labworks
Embedded Labworks
Mecanismos de sincronizao do kernel como spinlocks tambm server como memory barriers (veremos spinlocks mais adiante). Mais detalhes na documentao do kernel:
Documentation/memorybarriers.txt
Embedded Labworks
LABORATRIO
Acessando o hardware
Embedded Labworks
Gerenciamento de processos
Embedded Labworks
PROCESSOS E THREADS
Um processo um programa em execuo. Em sistemas Unix, um processo criado atravs da chamada de sistema fork(). Um processo composto por:
Um espao de endereamento virtual, que contm cdigo, dados, stack, bibliotecas carregadas dinamicamente, etc. Uma thread, cujo ponto de entrada a funo main().
Embedded Labworks
Dentro de um processo, threads adicionais podem ser criadas com a funo pthread_create():
As threads compartilham o mesmo espao de endereamento virtual do processo. O ponto de entrada da thread passado como argumento em pthread_create().
Embedded Labworks
Internamente, o kernel no diferencia processos e threads. Uma thread nada mais do que um processo que compartilha dados com outros processos. Por este motivo, o Linux escalona threads e no processos! A partir de agora, pelo fato do kernel tratar tudo como tarefa (task), vamos nos referir thread ou processo apenas como tarefa.
Embedded Labworks
Processo 2 Thread 1
User space
task_struct
Tarefa 1 Tarefa 2 Tarefa 3 Tarefa 4 Tarefa 5 Tarefa 6
Kernel space
Embedded Labworks
TASK_RUNNING: O processo esta em execuo ou pronto para ser executado. TASK_INTERRUPTIBLE: O processo esta bloqueado esperando alguma condio, mas pode ser interrompido se receber um sinal. TASK_UNINTERRUPTIBLE: O processo esta bloqueado esperando alguma condio, mas ignora qualquer sinal. EXIT_ZOMBIE: O processo terminou mas o processo-pai ainda no fez a limpeza. __TASK_TRACED: O processo esta sendo restreado por outro processo (tracing) via chamada de sistema ptrace(). __TASK_STOPPED: O processo parou sua execuo porque recebeu algum sinal (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU) via debugger ou controle de job.
Embedded Labworks
fork() ou pthread_create()
TAREFA CRIADA
EXIT_ZOMBIE
Finalizada, aguardando ACK do processo-pai
Tarefa selecionada pelo escalonador
TASK_RUNNING
Pronta aguardando execuo
TASK_RUNNING
Em execuo
Tarefa interrompida pelo escalonador Para executar outra tarefa
TASK_INTERRUPTIBLE ou TASK_UNINTERRUPTIBLE
Bloqueada
Embedded Labworks
O ESCALONADOR
Como e quando escalonar uma tarefa? Trade-off entre capacidade de processamento e tempo de resposta (latncia). O Linux um sistema multitasking preemptivo. Possui o conceito de classes de escalonador, onde cada classe possui um algoritmo de escalonamento, que decide qual processo deve ser executado, quando e por quanto tempo. O escalonador padro do Linux o CFS (Completely Fair Scheduler), onde cada processo recebe uma "porcentagem justa" da CPU (foco em performance).
Embedded Labworks
ESCALONANDO TAREFAS
O kernel pode interromper uma tarefa em execuo tanto em espao de usurio (padro) quanto em espao de kernel (configurvel via opo CONFIG_PREEMPT). Existem diversos pontos onde o kernel pode interromper uma tarefa em execuo para executar outra tarefa, incluindo:
Ao fim do time slice (quantum) da tarefa. No retorno do tratamento de uma interrupo. No retorno de uma chamada de sistema.
Embedded Labworks
O Linux possui tambm um escalonador para processos de tempo real, que tem prioridade sobre o CFS. Mas mesmo assim, o Linux no pode ser considerado um sistema operacional determinstico (em alguns trechos do cdigo a latncia para atender um pedido de interrupo pode ser muito grande). Existe um conjunto de patches (PREEMPT_RT) que pode ser aplicado ao kernel e melhorar este cenrio de alta latncia. Uma opo para o uso do Linux em aplicaes hard real-time a utilizao de um kernel de tempo real em conjunto com o Linux (RTLinux, RTAI, Xenomai).
Embedded Labworks
CONTEXTO DE EXECUO
Uma tarefa pode rodar tanto em espao de usurio (user space) quanto em espao de kernel (kernel space). Quando uma tarefa rodando em espao de usurio (user space) executa uma chamada de sistema, ela entra em espao de kernel (kernel space). Porm, apesar de estar executando em kernel space, a chamada de sistema executada no contexto da tarefa que a requisitou. Aps finalizar a execuo da chamada de sistema, o kernel pode retornar para a execuo da tarefa em espao de usurio ou escalonar uma outra tarefa para execuo.
Embedded Labworks
KERNEL THREADS
Kernel threads so tarefas comuns, mas que so executadas em kernel space. Muito til para o kernel ou algum device driver executar operaes em background. As threads do kernel aparecem na listagem do programa ps entre colchetes. A API para a criao de threads do kernel esta disponvel em <linux/kthread.h>.
Embedded Labworks
Voc pode usar a funo kthread_create() para criar uma thread do kernel. Neste caso a thread criada de forma bloqueada, e voc precisa acord-la com a funo wake_up_process(). Voc pode tambm usar a funo kthread_run() para criar e executar uma thread do kernel. Neste caso a thread criada e colocada no estado TASK_RUNNING, pronta para execuo. Para parar uma thread do kernel, voc pode usar a funo kthread_stop().
Embedded Labworks
Embedded Labworks
Embedded Labworks
EVENTOS
Boa parte das tarefas que desenvolvemos so baseadas em eventos, ou seja, elas devem esperar um evento para continuar seu processamento. Exemplos:
Eventos temporais ou delay (ex: esperar 100ms). Operao de I/O (ex: esperar a leitura de um arquivo). Evento de hardware (ex: esperar uma tecla ser pressionada). Mecanismos de sincronizao (ex: esperar a liberao de um mutex).
Uma forma de implementar tarefas que esperam eventos atravs de polling. Mas ao usar polling, a tarefa ir monopolizar e disperdiar ciclos preciosos de CPU.
Embedded Labworks
SLEEPING
O ideal nestes casos trabalhar com interrupo. Ou seja, colocar a tarefa para dormir e pedir para o kernel acord-la assim que o evento acontecer. Quando uma tarefa dorme, o kernel coloca ela em um dos estados TASK_INTERRUPTIBLE ou TASK_UNINTERRUPTIBLE, e seleciona outra tarefa para execuo. Assim que o evento acontecer, o kernel coloca a tarefa novamente no estado TASK_RUNNING, pronta para ser executada.
Embedded Labworks
SLEEPING (cont.)
Processo de comunicao via RS232
L um byte da porta serial
chamada de sistema
Embedded Labworks
WAIT QUEUES
Para dormir, voc deve declarar uma wait queue, que mantm uma lista de tarefas esperando um evento acontecer. Uma
queue definida atravs da varivel wait_queue_head_t, que pode ser inicializada de suas formas:
Estaticamente com a macro DECLARE_WAIT_QUEUE_HEAD(). Dinamicamente com a funo init_waitqueue_head().
wait
Os processos devem dormir usando uma das funes do tipo wait_event*() e devem ser acordados atravs das funes do tipo wake_up*().
Embedded Labworks
SLEEPING API
#include<linux/wait.h> #include<linux/sched.h> /*declarewaitqueuestatically*/ DECLARE_WAIT_QUEUE_HEAD(my_queue); /*declarewaitqueuedynamically*/ wait_queue_head_tmy_queue; init_waitqueue_head(&my_queue);
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
IMPLEMENTAO WAIT_EVENT()
#define__wait_event(wq,condition) do{ DEFINE_WAIT(__wait); for(;;){ prepare_to_wait(&wq,&__wait, TASK_UNINTERRUPTIBLE); if(condition) break; schedule(); } finish_wait(&wq,&__wait); }while(0);
Embedded Labworks
EXCLUSIVE E NON-EXCLUSIVE
Todas as funes que vimos at aqui (wait_event*()) colocam a tarefa em uma espera no exclusiva. Isso significa que todas as tarefas esperando no queue podem ser acordadas com as funes wake_up() e wake_up_interruptible(). Mas voc pode esperar um evento de forma exclusiva com a funo wait_event_interruptible_exclusive() .
Embedded Labworks
Desta forma, se voc tiver vrias tarefas esperando de forma esclusiva, as funes wake_up() e wake_up_interruptible() acordaro apenas uma delas. Portanto, o modo exclusivo faz sentido quando apenas uma tarefa ir "consumir" o evento. Mas se mesmo assim voc quiser acordar todas as tarefas que esto esperando de forma exclusiva, basta usar as funes wake_up_all() e wake_up_interruptible_all().
Embedded Labworks
LABORATRIO
Embedded Labworks
Gerenciamento de interrupes
Embedded Labworks
INTERRUPO
Um dos principais trabalhos do sistema operacional gerenciar e se comunicar com os dispositivos de hardware conectados ao sistema. Para isso, o kernel pode checar o status do hardware periodicamente (polling) e atuar de acordo. Mas como os dispositivo de hardware so muito mais lentos que a CPU, este mecanimos de acesso ao hardware disperdia preciosos ciclos de CPU, e no normalmente usado. Por este motivo, para conversar com o hardware, a CPU, e consequentemente o kernel, usam o mecanismo de interrupo.
Embedded Labworks
INTERRUPO (cont.)
O mecanismo de interrupo possibilita ao hardware a capacidade de sinalizar a CPU quando acontecer algum evento (o boto do mouse foi pressionado, uma tecla foi digitada, um pacote foi recebido da interface Ethernet, etc). Diferentes dispositivos esto associados diferentes nmeros de interrupo, tambm chamadas de linhas de IRQ (Interrupt Request). Quando a CPU recebe o sinal de interrupo, interrompe a execuo atual, e de acordo com a linha de IRQ, executa uma rotina de tratamento de interrupo registrada no sistema (tambm chamada de interrupt handler ou ISR - Interrupt Service Routine).
Embedded Labworks
INTERRUPO NO KERNEL
Uma rotina de tratamento de interrupo nada mais do que uma funo definida pelo device driver (com um prottipo bem definido que veremos mais adiante). Para um device driver usar uma linha de interrupo, ele deve:
Requisitar o uso da linha de IRQ quando for iniciar o uso do dispositivo de hardware atravs da funo request_irq(). Implementar a ISR (veremos as regras de implementao da ISR mais adiante). Liberar o uso da linha de IRQ quando no for mais usar o dispositivo atravs da funo free_irq().
Embedded Labworks
IRQ API
#include<linux/interrupt.h> /*requestIRQ,returns0onsuccess*/ intrequest_irq(unsignedintirq, irq_handler_thandler, unsignedlongirq_flags, constchar*devname, void*dev_id); /*freeIRQ*/ voidfree_irq(unsignedintirq,void*dev_id);
Embedded Labworks
IRQ FLAGS
Estas so as principais flags que podem ser passadas para registrar uma IRQ:
ISRs. Neste caso, o hardware precisa prover um mecanismo para que a ISR possa verificar a origem da interrupo.
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Como no existe uma garantia de qual espao de endereamento o sistema estar quando uma interrupo acontecer, no possvel trocar dados com user space. A execuo da rotina de tratamento de interrupo gerenciada pela CPU, e no pelo escalonador. Ou seja, uma ISR roda em contexto de interrupo, e no em contexto de processo! Por este motivo, uma ISR no pode dormir, j que ela no roda em contexto de processo, e no pode ser escalonada. Em especfico, alocaes de memria devem ser feitas passando a flag GFP_ATOMIC.
Embedded Labworks
A linha de IRQ da interrupo desabilitada em todas as CPUs (por isso uma ISR no precisa ser reentrante). Todas as interrupes locais (da mesma CPU) so desabilitadas. Por este motivo, uma ISR deve executar seu trabalho rapidamente e retornar.
Embedded Labworks
Reconhecer a interrupo, por exemplo setando um bit em um registrador do controlador de interrupes. Ler ou escrever dados do dispositivo. Sinalizar o processo esperando um evento do dispositivo, normalmente usando wait queues:
wake_up_interruptible(&mydriver_queue);
Embedded Labworks
ISR EXEMPLO 1
irqreturn_tmydriver_interrupt(intirq,void*dev_id) { /*ackinterrupt*/ ack(); /*readdevicedata*/ dev_id>data=getdata(); /*wakeupprocesswaitingonwaitqueue*/ wake_up(&mydriver_queue); /*returnIRQhandled*/ returnIRQ_HANDLED; }
Embedded Labworks
Em alguns casos, uma interrupo precisa realizar uma quantidade grande de trabalho, ao mesmo tempo em que sua execuo precisa ser bem rpida. So necessidades conflitantes! Para estes casos, o processamento pode ser dividido em duas partes:
Embedded Labworks
TOP HALF
Este prprio cdigo da ISR, que executado assim que acontece a interrupo. Deve retornar o mais rpido possvel, j que as interrupes esto desabilitadas. Por esse motivo, ele deve delegar o tratamento dos dados ou evento recebido para um mecanismo de bottom half.
Embedded Labworks
BOTTOM HALF
Ser executado em algum momento no futuro, com todas as interrupes habilitadas. Desta forma, o impacto menor se levar mais tempo para realizar o processamento delegado pela interrupo. No Linux, pode ser implementado atravs de trs mecanismos diferentes: softirqs, tasklets ou workqueues.
Embedded Labworks
ISR EXAMPLE 2
/*driverISR*/ irqreturn_tmydriver_interrupt(intirq,void*dev_id) { ack(); dev_id>data=getdata(); enable_bottom_half(); returnIRQ_HANDLED; } /*bottomhalfexecutewithinterruptsenabled*/ voidbottom_half_function() { /*dotheheavyworkhere!*/ [...] wake_up(&mydriver_queue); }
Embedded Labworks
SOFTIRQS
Softirqs so uma forma de processamento em bottom half. So executadas depois que todas as interrupes forem processadas, normalmente no fim do tratamento das interrupes. Rodam portanto em contexto de interrupo, por isso no podem bloquear (dormir). Mas como so executadas com todas as interrupes habilitadas, o impacto no tempo de resposta do sistema bem menor. Dependendo da carga do sistema, podem ser tratadas tambm em threads do kernel (vide ksoftirqd/X, onde X o nmero da CPU).
Embedded Labworks
SOFTIRQS (cont.)
A mesma softirq pode rodar em mltiplas CPUs ao mesmo tempo, por esse motivo preciso tomar cuidado extra com sua implementao (em especfico, ela precisa ser thread-safe). A quantidade de softirqs disponveis no sistema limitada (por esse motivo ela no usada normalmente por drivers, e sim por sub-sistemas do kernel, como o sub-sistema de rede). A lista de softirqs esta definida em <linux/interrupt.h>: HI, TIMER, NET_TX, NET_RX, BLOCK, BLOCK_IOPOLL, TASKLET, SCHED, HRTIMER, RCU. No muito comum o uso direto de softirqs por drivers. O mais comum usar as softirqs atravs da implementao de tasklets.
Embedded Labworks
TASKLETS
As tasklets so executadas nas softirqs HI e TASKLET. Como um tipo de softirq, tem as mesmas caractersticas desta, rodando em contexto de interrupo com todas as interrupes habilitadas. A nica diferena com relao s softirqs que garantido que s uma instncia da tasklet estar rodando ao mesmo tempo, mesmo em sistemas com mltiplas CPUs (SMP).
Embedded Labworks
TASKLETS (cont.)
Uma tasklet pode ser declarada estaticamente com a macro DECLARE_TASKLET() ou criada dinamicamente com a funo tasklet_init(). Uma ISR pode delegar trabalho para uma tasklet usando uma das duas funes abaixo:
tasklet_schedule(): executa a tasklet na softirq TASKLET. tasklet_hi_schedule(): executa a tasklet na softirq HI, que
Embedded Labworks
TASKLET API
#include<linux/interrupt.h> /*inittasklet*/ voidtasklet_init(structtasklet_struct*t, void(*func)(unsignedlong), unsignedlongdata); /*killtasklet*/ voidtasklet_kill(structtasklet_struct*t); /*scheduletasklet*/ voidtasklet_schedule(structtasklet_struct*t) /*taskletfunction*/ staticvoidtasklet_func(unsignedlongdata);
Embedded Labworks
Embedded Labworks
WORK QUEUES
Work queue um mecanismo genrico de deferir trabalho, no s limitado ao tratamento de interrupes. A funo definida como work queue executada em uma thread do kernel (kworker) com todas as interrupes habilitadas. Como uma work queue roda em uma thread do kernel, ela executada em contexto de processo, e por este motivo pode bloquear (dormir). Portanto, se o processamento deferido pela CPU precisa bloquear (dormir), em vez de usar tasklets, voc dever usar work queues.
Embedded Labworks
Em sua forma mais comum, a work queue uma interface para deferir trabalho para uma thread genrica do kernel (events/n ou kworker/n:id, dependendo da verso do kernel, onde n o nmero da CPU e id o id da work queue). Um trabalho a ser delegado (work) pode ser criado com DECLARE_WORK() ou INIT_WORK(), e normalmente acionado com schedule_work().
Embedded Labworks
Embedded Labworks
As funes schedule_work() e schedule_delayed_work() iro delegar o trabalho para uma thread de tratamento de work queues genrica do sistema. Isso significa que seu processamento poder competir com o trabalho delegado por outros drivers ou sub-sistemas do kernel. Se voc precisa de mais performance ou exclusividade no tratamento dos trabalhos, voc pode criar uma nova work queue com a funo alloc_workqueue().
Embedded Labworks
Embedded Labworks
Embedded Labworks
COMPARANDO
Bottom Half Softirq Tasklet Work queues Contexto Interrupo Interrupo Processo Serializado No Sim (na mesma tasklet) No
Embedded Labworks
Work queues envolvem um overhead maior pelo uso de threads do kernel e pelas trocas de contexto envolvidas. Voc dever usar work queues quando existir a possibilidade do trabalho ser escalonado, ou seja, se o trabalho precisar dormir. Por outro lado, tasklets envolvem menos overhead e devem ser o mtodo preferido se seu trabalho no precisar dormir e puder ser executado em contexto de interrupo. Se voc precisar de muita performance, avalie a possibilidade de usar softirqs no lugar de tasklets.
Embedded Labworks
OUTROS MECANISMOS
Existem ainda outros mecanismos que podem ser usados no tratamento de interrupes no Linux, dentre eles:
Embedded Labworks
THREADED INTERRUPTS
O suporte threaded interrupts tem suas origens na rvore de realtime do kernel e foi adicionado ao Linux a partir da verso 2.6.30. Seu principal objetivo diminuir a latncia do sistema como um todo, fazendo com que uma interrupo seja tratada dentro de uma thread do kernel, rodando em contexto de processo. Por este motivo, permitido bloquear (dormir) em uma threaded interrupt. Para threaded request_threaded_irq(). registrar uma interrupt, basta usar a funo
Embedded Labworks
KERNEL TIMERS
Kernel timers um mecanismo usado para programar a execuo de um trabalho em determinado momento no futuro. Para us-lo, voc precisa declarar uma estrutura do tipo timer_list e inicializar esta estrutura basicamente com o valor do timer e a funo de callback. Os kernel timers rodam em uma softirq (TIMER_SOFTIRQ), ou seja, em contexto de interrupo, e portanto no podem bloquear! Mais informaes em <linux/timer.h>.
Embedded Labworks
LABORATRIO
Embedded Labworks
Mecanismos de sincronizao
Embedded Labworks
MULTITHREAD E CONCORRNCIA
Em um ambiente multithread, os recursos compartilhados do sistema precisam ser protegidos de acesso concorrente. Um trecho de cdigo que acessa recursos compartilhados chamado de regio crtica (critical session). Para previnir o acesso concorrente uma regio crtica, o acesso deve ser atmico, ou seja, a operao em cima do recurso compartilhado deve ser executada o comeo ao fim sem interrupo.
Embedded Labworks
CONCORRNCIA NO KERNEL
Em termos de concorrncia, o kernel tem as mesmas restries de um programa multithread: o seu estado global e visvel todos os contextos de execuo (interrupo e processos). E os problemas de concorrncia no kernel podem acontecer porque:
Uma interrupo pode interromper a execuo de um processo, e ambos podem estar usando recursos compartilhados. A preempo do kernel pode interromper a execuo de uma chamada de sistema para executar outra chamada de sistema, e ambas podem estar usando recursos compartilhados. Em sistemas SMP (com mltiplas CPUs) podemos ter processos rodando realmente em paralelo em diferentes processadores, que podem estar usando recursos compartilhados.
Embedded Labworks
SOLUO
Sempre que possvel, mantenha um estado local dos processos. Caso voc precise de recursos compartilhados, identifique quais so estes recursos:
Se o seu recurso compartilhado for um nmero inteiro, voc pode usar as funes atmicas disponibilizadas pelo kernel. Em outros casos, como estruturas de dados mais complexas ou recursos de hardware, voc dever usar um mecanismo de locking.
Embedded Labworks
ATOMIC OPERATIONS
O recurso de operaes atmicas do kernel til quando o recurso compartilhado esta armazenado em uma varivel do tipo inteiro. Mesmo uma operao simples em inteiros do tipo x++ ou x|=1 no garantida que seja atmica em todas as arquiteturas! O uso das funes de operaes atmicas garantem acesso atmico s variveis do tipo inteiro. O Linux fornece duas APIs de operaes atmicas:
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
LOCKING
Nem sempre um recurso compartilhado pode ser representado por uma varivel do tipo inteiro. Na maioria das vezes, a regio crtica que precisamos proteger atua em cima de estruturas de dados mais complexas. Para estes casos, devemos proteger o acesso ao recurso compartilhado atravs de mecanismos de locking.
Embedded Labworks
LOCKING (cont.)
Processo 1 Processo 2
lock()
wait_lock()
Seo crtica
unlock()
Embedded Labworks
SEMFORO
O semforo um mecanismo de comunicao entre tarefas. Quando uma tarefa tenta adquirir um semforo que esta indisponvel, a tarefa colocada em uma fila de espera e bloqueia (dorme). Quando o semforo ficar disponvel, a tarefa acordada, adquire o semforo e pode realizar seu trabalho. Aps realizar o processamento, a tarefa dever liberar o semforo para outra tarefa utiliz-lo se necessrio.
Embedded Labworks
SEMFORO (cont.)
Um semforo pode ser usado como mecanismo de comunicao de eventos entre tarefas (sincronizao) ou como um mecanismo de locking. Durante bastante tempo, o Linux implementava o mecanismo de locking atravs de semforos. Mais informaes sobre a API de semforos em <asm/semaphore.h>. A partir da verso 2.6.16, a funcionalidade de mutex (abreviao de mutual exclusion) foi implementada e adotada como mecanismo padro de locking para gerenciar o acesso recursos compartilhados no kernel.
Embedded Labworks
MUTEX
Antes de entrar em uma regio crtica, um lock deve ser adquirido. Se o lock no estiver disponvel, a tarefa dever bloquear (dormir) aguardando o lock ficar disponvel. Assim que o lock ficar disponvel, a tarefa acordada, adquire o lock e realiza seu processamento. Aps o processamento, a tarefa deve liberar o lock. Como o processo que requisita o lock pode bloquear (dormir) se este lock estiver indisponvel, um mutex s pode ser usado em contexto de processo.
Embedded Labworks
MUTEX API
#include<linux/mutex.h> /*initializingamutexstatically*/ DEFINE_MUTEX(mutex_name); /*initializingamutexdynamically*/ voidmutex_init(structmutex*lock);
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Os mutexes devem ser o mecanismo preferido para proteger o acesso concorrente regies crticas, mas eles possuem duas principais deficincias:
Existe um overhead de pelo menos duas trocas de contexto na sua execuo (colocar a tarefa para dormir quando o mutex estiver sendo usado e acordar a tarefa quando o mutex for liberado). O fato de bloquear no permite seu uso em interrupes. Por exemplo, um sistema multicore onde temos uma CPU executando uma ISR e outra CPU executando um processo, ambos acessando um recurso compartilhado.
Embedded Labworks
SPINLOCKS (cont.)
O spinlock um mecanismo de locking criado para ser usado em trechos de cdigo que no podem (ou no querem) bloquear, como por exemplo ISRs ou bottom halves, e so importantes em sistemas multicore onde temos processos e interrupes acessando um recurso compartilhado ao mesmo tempo. Ele implementado como um loop que fica verificando (spinning) em um loop at que o lock esteja disponvel. Por este motivo, a seo crtica protegida pelo spinlock deve ser executada rapidamente e no pode bloquear (dormir).
Embedded Labworks
SPINLOCKS (cont.)
Alm de verificar o lock, um spinlock desabilita a preempo do kernel na CPU em que esta executando. O lock do spinlock s faz sentido em sistemas multicore. Por este motivo, em sistemas com um nico core o tratamento do lock removido, e s o cdigo que habilita/desabilita a preempo compilado. Em sistemas com um nico core e com a preempo do kernel desabilitada, o cdigo relacionado ao spinklock removido completamente!
Embedded Labworks
SPINLOCK API
#include<linux/spinlock.h> /*initializingaspinlockstatically*/ DEFINE_SPINLOCK(my_lock); /*initializingaspinlockdynamically*/ voidspin_lock_init(spinlock_t*lock);
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
DESABILITANDO PREEMPO
Em sistemas com apenas uma CPU, onde o recurso compartilhado acessado apenas por processos, no precisamos de um spinlock, j que este recurso no ser acessado por outra CPU. Neste caso, temos duas opes: usar um mutex ou desabilitar a preempo do kernel. Se voc quiser evitar o overhead do uso de um mutex, pode usar a famlia de funes para habilitar e desabilitar a preempo, como as funes preempt_enable() e preempt_disable(). Estas funes esto definidas em <linux/preempt.h>.
Embedded Labworks
DESABILITANDO INTERRUPES
Em sistemas com uma nica CPU, ao compartilhar dados entre um processo e uma interrupo, voc pode simplesmente desabilitar as interrupes. Para isso, voc pode usar a famlia de funes de habilitao e desabilitao de interrupes, como por exemplo as funes local_irq_disable(), local_irq_enable(), local_irq_save() e local_irq_restore(). Mais informaes sobre estas funes em <linux/irqflags.h>. Lembre-se de que ao desabilitar as interrupes, voc estar aumentando o tempo de latncia do sistema.
Embedded Labworks
RESUMO
Como padro, use mutex. Caso a performance seja importante, avalie a possibilidade do uso de spinlocks, mas lembre-se de que spinlocks aumentam o tempo de latncia do sistema.
Lembre-se: desenvolva o driver sempre levando em considerao que ele pode rodar em um sistema SMP e com a preempo do kernel habilitada!
Embedded Labworks
DEADLOCKS
SITUAO 1 SITUAO 2
lock(1)
lock(1)
lock(2)
lock(1)
lock(2)
lock(1)
deadlock
deadlock
Embedded Labworks
READER-WRITE SPINLOCKS
Quando um processo pretende escrever em um recurso compartilhado, importante que nenhum outro processo tenha acesso ao recurso compartilhado. Porm, quando um processo pretende ler de um recurso compartilhado, no existe problema se outro processo tambm tentar ler deste mesmo recurso compartilhado. Neste caso podemos ter um lock exclusivo para escritas e um lock compartilhado para leituras. O Linux implementa esta funcionalidade atravs de spinlocks do tipo Reader-Writer.
Embedded Labworks
Embedded Labworks
OUTROS MECANISMOS
Sequencial locks: tambm chamado de seqlock, um mecanismo parecido com o Reader-Write lock, mas prioriza escritas ao invs de leituras. Mais informaes em <linux/seqlock.h>. RCU (Read Copy Update): um outro mecanismo parecido com o Reader-Write lock, com as rotinas de leitura muito mais rpidas, porm com a rotina de escrita mais lenta. Mais informaes em <linux/rcupdate.h>.
Embedded Labworks
COMPLETION VARIABLE
A varivel completion um exemplo de uso de semforos como mecanismo de comunicao de eventos (notificao) entre tarefas. Uma tarefa espera (dorme) na varivel completion enquanto outra tarefa realiza algum processamento. Quando a outra tarefa finalizar o processamento, ela utiliza a varivel completion para acordar qualquer outra tarefa que esteja esperando. Diferentemente de semforos ou wait queues, usando completion voc consegue acordar vrias tarefas ao mesmo tempo.
Embedded Labworks
Embedded Labworks
LABORATRIO
Embedded Labworks
Kernel Debugging
Embedded Labworks
KERNEL DEBUGGING
Debugging do kernel bem mais difcil quando comparado ao debugging de aplicaes. Um bug em uma aplicao derruba apenas a aplicao, j um bug no kernel pode derrubar todo o sistema! Debugging do kernel exige conhecimentos do sistema operacional e das diversas tcnicas de anlise, tracing e profiling que estudaremos nesta seo do treinamento.
Embedded Labworks
A funo printk(), definida em <linux/printk.h>, a responsvel por imprimir mensagens no kernel, podendo ser chamada tanto em contexto de processo quanto em contexto de interrupo. Ela tem o mesmo prottipo da funo printf() usada em user space:
intprintk(constchar*s,...);
Todas as mensagens do kernel so armazenadas em um buffer circular (ring buffer), cujo tamanho pode ser definido em tempo de compilao na opo CONFIG_LOG_BUF_SHIFT ou em tempo de execuo no parmetro de boot log_buf_len. As mensagens so normalmente exibidas na console e podem ser emitidas a qualquer momento com a ferramenta dmesg.
Embedded Labworks
NVEIS DE LOG
Por padro, passa-se uma macro indicando o nvel (ou prioridade) da mensagem ao imprim-la:
printk(KERN_WARNING"warning:skippingphysicalpage0\n");
Todas as mensagens so armazenadas, mas apenas as mensagens com nvel de log menor ou igual ao configurado sero exibidas na console. O kernel define os seguintes nveis de mensagens de log:
0(KERN_EMERG)systemisunusable 1(KERN_ALERT)actionmustbetakenimmediately 2(KERN_CRIT)criticalconditions 3(KERN_ERR)errorconditions 4(KERN_WARNING)warningconditions 5(KERN_NOTICE)normalbutsignificantcondition 6(KERN_INFO)informational 7(KERN_DEBUG)debuglevelmessages
Embedded Labworks
O nvel de log padro pode ser definido em tempo de compilao na opo CONFIG_DEFAULT_MESSAGE_LOGLEVEL, no boot passando o parmetro loglevel ou em tempo de execuo no arquivo /proc/sys/kernel/printk. Outros parmetros de boot que podem alterar o comportamento das mensagens de log do kernel:
debug: Habilita o nvel 7 (KERN_DEBUG) de mensagens de log. ignore_loglevel: Habilita todos os nveis de mensagens (tambm pode ser habilitado em /sys/module/printk/parameters/ ignore_loglevel). quiet: Configura o nvel de log como 4 (KERN_WARNING).
Embedded Labworks
NOVAS FUNES
Hoje temos outras opes para exibir mensagens de log no kernel, e no mais comum o uso da funo printk() para debugging. Pode-se usar a famlia de funes pr_*(), definida em <linux/printk.h>:
pr_emerg(),pr_alert(),pr_crit(),pr_err(),pr_warning(), pr_notice(),pr_info(),pr_cont(),pr_debug().
Ou a famlia de funes dev_*(), definida em <linux/device.h>. Estas funes recebem como argumento um ponteiro para uma estrutura do tipo device (estudaremos esta estrutura mais adiante).
dev_emerg(),dev_alert(),dev_crit(),dev_err(), dev_warning(),dev_notice(),dev_info(),dev_dbg().
Embedded Labworks
MENSAGENS DE DEBUG
As funes pr_debug() e dev_dbg() s so compiladas se voc habilit-las no kernel. Quando o kernel compilado com a opo CONFIG_DEBUG, estas mensagens de debug so compiladas e exibidas com a funo printk() no nvel de debug do kernel. Quando o kernel compilado com a opo CONFIG_DYNAMIC_DEBUG, as mensagens de debug podem ser habilitadas por arquivo, por mdulo ou at por mensagem! Veja a documentao do kernel em Documentation/dynamicdebughowto.txt. Quando nenhuma destas duas opes do kernel estiverem habilitadas, as mensagens de debug impressas com pr_debug() e dev_dbg() no so compiladas.
Embedded Labworks
DEBUGFS
O debugfs um sistema de arquivos virtual que exporta informaes de debug para user space. Habilite a opo CONFIG_DEBUG_FS em Kernel hacking -> Debug Filesystem. Depois s montar o debugfs:
#mounttdebugfsnone/sys/kernel/debug #ls/sys/kernel/debug/ asocbluetoothhidmmc1 bdigpiommc0usb
Embedded Labworks
DEBUGFS API
#include<linux/debugfs.h> /*createasubdirectoryforyourdriver*/ structdentry*debugfs_create_dir(constchar*name, structdentry*parent); /*exposeanintegerasafileindebugfs,whereuisfor decimalrepresentationandxforhexadecimal representation*/ structdentry*debugfs_create_{u,x}{8,16,32}( constchar*name,mode_tmode, structdentry*parent,u8*value); /*exposeabinaryblobasafileindebugfs*/ structdentry*debugfs_create_blob(constchar*name, mode_tmode,structdentry*parent, structdebugfs_blob_wrapper*blob);
Embedded Labworks
OUTROS MECANISMOS
Alguns mecanismos de debugging foram bastante usados, mas agora seu uso no mais comum:
Usar comandos especiais de ioctl() para debugging (use debugfs). Usar entradas especiais no sistema de arquivos proc (use debugfs). Usar entradas especiais no sysfs (use debugfs). Usar printk() (use a famlia de funes pr_*() ou dev_*()).
Embedded Labworks
A Magic Sysrq Key uma combinao de teclas manipulada pelo kernel, que pode ser usada como ferramenta de anlise, debug e recuperao do kernel:
No PC: [Alt] + [SysRq] + <caractere>. Em alguns teclados, a tecla SysRq a tecla Print Screen. Pela console serial: <break> + <caractere>. Em todas plataformas: escrever o caractere diretamente no arquivo /proc/sysrqtrigger.
Deve
habilitada no kernel atravs da opo CONFIG_MAGIC_SYSRQ, e pode ser habilitada ou desabilitada em tempo de execuo atravs do arquivo /proc/sys/kernel/sysrq.
ser
Embedded Labworks
Exemplos de comandos:
b: Reinicia o sistema automaticamente. e: Envia o sinal SIGTERM para todos os processos (menos o init). t: Mostra o stack (dump) de todos os processos em execuo. w: Mostra o stack (dump) dos processos bloqueados (dormindo). c: Fora um crash do kernel desreferenciando um ponteiro nulo.
Embedded Labworks
KERNEL OOPS
Um oops um mecanismo de comunicao do kernel para notificar o usurio que um erro aconteceu. Este erro pode acontecer por diversos motivos, como por exemplo acesso ilegal regies de memria ou execuo de instrues invlidas. Quando acontece um oops o kernel emite uma mensagem na console, exibindo o status atual do sistema no momento em que aconteceu o problema, incluindo um dump dos registradores e o back trace do stack. Aps o oops, o kernel ir tentar se recuperar e resumir a execuo, mas dependendo do erro, nem sempre isso possvel. Portanto, o kernel pode travar aps o oops (kernel panic!).
Embedded Labworks
Embedded Labworks
CONFIGURANDO O OOPS
No exemplo anterior, os endereos estavam convertidos para os nomes das respectivas funes, facilitando o processo de debugging. Para que esta funcionalidade esteja disponvel, habilite a opo CONFIG_KALLSYMS na configurao do kernel (antes o kernel s exibia os endereos e era necessrio usar um programa chamado ksymoops para fazer a anlise).
Embedded Labworks
NOTIFICANDO PROBLEMAS
Se necessrio, possvel gerar um kernel oops atravs das macros BUG() ou BUG_ON(). Exemplos:
if(erro)BUG(); BUG_ON(erro);
J se o que voc quer s imprimir o back trace do stack, use a funo dump_stack().
Embedded Labworks
O Linux possui diversas funcionalidades de debugging integradas ao kernel. Para us-las basta habilitar a opo CONFIG_DEBUG_KERNEL no menu de configurao, e depois habilitar a funcionalidade de debug desejada no menu "Kernel hacking". Alguns exemplos:
CONFIG_DEBUG_MUTEXES: habilita checagem do uso de mutexes. CONFIG_DEBUG_SPINLOCK: habilita checagem de spinlocks. CONFIG_SLUB_DEBUG_ON: checagem na camada de alocao de memria. CONFIG_DEBUG_KMEMLEAK: habilita checagem de memory leak. CONFIG_DEBUG_LL (arm e unicore32): habilita o debugging de baixo nvel, til
Embedded Labworks
GDB
O GDB (GNU Debugger) o debugger padro do projeto GNU, disponvel para diversas arquiteturas. http://www.gnu.org/software/gdb/ Interface via console, mas com diversos frontends disponveis (Eclipse, DDD, GDB/Insight, etc). Permite iniciar o processo de debugging de um kernel em execuo:
$gdbvmlinux/proc/kcore
O acesso somente de leitura. Voc consegue listar o contedo de uma funo, exibir o valor de variveis, etc; mas no consegue fazer alteraes ou colocar breakpoints por exemplo.
Embedded Labworks
KDB
O kdb um debugger que permite examinar a memria e as estruturas de dados do kernel enquanto o sistema esta em execuo. Durante um bom tempo era disponibilizado atravs de um conjunto de patches, mas foi integrado ao mainline na verso 2.6.35. Fornece uma interface de linha de comandos, permitindo realizar operaes tpicas de um debugger como step, stop, run, colocar breakpoints, disassembly de instrues, etc. A tecla Pause pode ser usada para entrar no modo de debug. No trabalha no nvel do cdigo-fonte, apenas no nvel de instrues assembly!
Embedded Labworks
KGDB
O KGDB permite que a execuo do kernel seja controlada remotamente via conexo serial (ou rede) atravs do gdb rodando em uma outra mquina. Esta funcionalidade foi includa no kernel deste a verso 2.6.26 (x86 e sparc) e 2.6.27 (arm, mips e ppc). possvel controlar quase tudo, ler e escrever em variveis, executar passo-a-passo, e at colocar breakpoints em rotinas de tratamento de interrupo!
Embedded Labworks
CONFIGURANDO O KERNEL
Alm destas configuraes, algumas outras opes podem ajudar se forem habilitadas:
debugging.
confiveis.
Embedded Labworks
USANDO O KGDB
Para habilitar o kgdb, basta passar os seguintes parmetros de boot para o kernel:
kgdboc=<ttydevice>,[baud]kgdbwait
Exemplo:
kgdboc=ttyS0,115200kgdbwait
Onde:
kgdboc: indica a conexo fsica com o KGDB. kgdbwait: faz o kgdb esperar por uma conexo de debug.
Embedded Labworks
Lembre-se de usar o gdb do seu (cross-compiling) toolchain. No target, interrompa o kernel com [Alt] + [SyrRq] + [g]. Assim que estabelecer a conexo, voc poder debugar o kernel como se ele fosse uma aplicao!
Embedded Labworks
Voc tambm pode debugar via KGDB pela rede (UDP/IP), passando o parmetro de boot kgdboe para o kernel (precisa aplicar um patch, j que esta funcionalidade ainda no esta no mainline). Mais informaes sobre o KGDB em: http://free-electrons.com/kerneldoc/latest/DocBook/kgdb/
Embedded Labworks
JTAG uma interface fsica que permite acesso modulos de debug integrados ao core da CPU, onde podemos coloc-la em halt, inspecionar registradores, memria, colocar breakpoints, etc. uma interface de debugging necessria quando trabalhamos no porte do bootloader ou do kernel para determinada plataforma, trabalho tambm chamado de board bring-up.
Embedded Labworks
Hardware (kit de desenvolvimento) com suporte JTAG. Adaptador JTAG (Ex: Flyswatter). Debugger (Ex: GDB). Software de interface entre o adaptador JTAG e o debugger (Ex: OpenOCD).
Embedded Labworks
Kexec uma chamada de sistema que torna possvel executar um novo kernel sem reiniciar ou passar pelo bootloader/BIOS. til no processo de debugging quando utilizado em conjunto com o kdump, um mecanismo para analisar um dump do kernel. Para mais detalhes consulte a documentao do kdump em
Documentation/kdump/kdump.txt .
Embedded Labworks
Se voc esgotar todas as possibilidades de debugging, e mesmo assim no encontrar o problema... no se desespere! Voc ainda tem a comunidade! Se o problema esta em uma verso do kernel fornecida pelo fabricante do chip, estes fabricantes mantm um frum com engenheiros especializados para te ajudar. Se o problema esta na verso atual do kernel, voc pode mandar um e-mail para a lista de discusso do kernel (LKML) descrevendo o problema e as suas descobertas.
Embedded Labworks
Se o problema esta em um driver que voc fez, existem listas de discusso ou canais de IRC que podem te ajudar, como o Kernel Newbies. http://kernelnewbies.org/ E lembre-se, voc sempre ter o e-mail do Sergio Prado!
Embedded Labworks
Tracing
Embedded Labworks
KERNEL PROBES
Kernel probes fornecem um mecanismo de instrumentao no kernel. Com esta funcionalidade possvel extrair informaes do kernel e alterar seu comportamento (aplicar patches) em tempo de execuo, sem precisar reiniciar o sistema! A implementao genrica de kernel probes chamada de kprobes, e pode ser usada para instrumentar qualquer instruo do kernel. Os kprobes possuem ainda duas variantes:
jprobes: usados para instrumentar chamadas de funo. returnprobes: usados para instrumentar retornos de funo.
Embedded Labworks
O principio bsico do kprobe baseado no uso de interrupes de software. Para usar a infraestrutura de kprobes, voc precisa desenvolver um mdulo do kernel e gerenciar os pontos de instrumentao atravs de uma estrutura do tipo kprobe. A limitao do uso de kprobes esta na dificuldade de associar o cdigo-fonte com o binrio gerado (otimizaes do compilador, recursos da linguagem C como macros e funes inline, etc). Mais informaes sobre kprobes em Documentation/kprobes.txt.
Embedded Labworks
SYSTEMTAP
O SystemTap uma infraestrutura de tracing que usa kprobes para facilitar o trabalho de instrumentao no kernel. http://sourceware.org/systemtap/ Assim como os kprobes, ele tambm elimina a necessidade de modificar e recompilar o kernel para investigar um problema funcional ou de performance. Utiliza uma linguagem simples de script (diversos exemplos disponveis na Internet). Tutorial e exemplos do SystemTap disponveis no ambiente de laboratrio do treinamento em /opt/labs/docs/guides/systemtap.pdf.
Embedded Labworks
SYSTEMTAP (EXEMPLO)
#straceopen.stp probesyscall.open { printf("%s(%d)open(%s)\n",execname(),pid(),argstr) } probetimer.ms(4000)#after4seconds { exit() }
Embedded Labworks
Embedded Labworks
KERNEL TRACEPOINTS
Kprobes possibilitam instrumentar qualquer instruo do kernel, mas adicionam um overhead ao processamento pelo fato de trabalharem com interrupes de software. Uma soluo mais leve so os tracepoints, que adicionam ponto de trace estticos no kernel, definidos em tempo de compilao. A implementao bem simples: se uma funo de probe estiver associada determinado tracepoint, esta funo ser chamada. Mais informaes sobre tracepoints nos fontes do kernel em Documentation/trace/tracepoints.txt .
Embedded Labworks
LTTng
Toolkit que permite coletar e analisar informaes de tracing do kernel, baseado em kernel tracepoints. At ento (Linux 3.6), necessrio aplicar patches no kernel para utilizar esta ferramenta de tracing. Capacidade de gerar timestamps extremamente precisos e com muito pouco overhead. Mais informaes na documentao do projeto: http://lttng.org/documentation
Embedded Labworks
LTTV VIEWER
Embedded Labworks
Profiling
Embedded Labworks
OPROFILE
O principal objetivo de uma ferramenta de profiling analisar a performance do sistema (consumo de ciclos de CPU). A ferramenta OProfile usa eventos de timer ou contadores de performance providos pelo processador para capturar dados em intervalos regulares. Mais informaes sobre o projeto em: http://oprofile.sourceforge.net/
Embedded Labworks
OPROFILE (EXEMPLO)
$opreportexcludedependent CPU:PIII,speed863.195MHz(estimated) CountedCPU_CLK_UNHALTEDevents(clocksprocessorisnot halted)withaunitmaskof0x00(Nounitmask)count50000 45038575.6634cc1plus 6021310.1156lyx 293134.9245XFree86 116331.9543as 102041.7142oprofiled 72891.2245vmlinux 70661.1871bash 64171.0780oprofile 63971.0747vim 30270.5085wineserver 11650.1957kdeinit 8320.1398wine ...
Embedded Labworks
LABORATRIO
Embedded Labworks
Embedded Labworks
Antes da verso 2.6, o kernel no possuia um padro unificado de desenvolvimento de drivers que descrevesse os dispositivos conectados ao sistema e sua topologia. A partir do kernel 2.6 foi implementado o modelo de dispositivos unificado (unified device model), que basicamente um framework para o desenvolvimento de drivers para os diferentes tipos de dispositivos suportados pelo Linux.
Embedded Labworks
ALGUMAS VANTAGENS
Padro para o desenvolvimento de drivers, evitando duplicao de cdigo. Capacidade de identificar todos os dispositivos disponveis no sistema, e em qual barramento eles esto conectados. Capacidade de ligar dispositivos e drivers. Capacidade de dividir os dispositivos por classes, sem se importar com sua topologia fsica. Facilita o gerenciamento de energia (conhecendo o topologia do sistema, fica simples identificar qual dispositivo desligar primeiro).
Embedded Labworks
ARQUITETURA
Framework de drivers: como o dispositivo se apresenta para a camada de usurio. Infraestrutura de barramento: como o driver conversa com o dispositivo de hardware.
Embedded Labworks
ARQUITETURA (cont.)
User space Bibliotecas/aplicaes
Kernel space
Hardware
Embedded Labworks
FRAMEWORK DE DRIVERS
Muitos drivers no so implementados diretamente como um driver de dispositivo de caractere. Eles so implementados sob um framework especfico de um tipo de dispositivo (exemplos: framebuffer, tty, input, etc). Vantagens do uso de um framework:
Padro (API comum) para o desenvolvimento de um tipo de driver. A mesma interface provida para as aplicaes, independente do driver.
Embedded Labworks
FRAMEWORKS
Aplicao Aplicao Interface de chamada de sistema Aplicao
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
Embedded Labworks
EXEMPLO: FRAMEBUFFER
o framework padro para dispositivos de vdeo (monitor, display LCD, etc). habilitado na opo do kernel CONFIG_FB. Fontes disponveis em drivers/video/ e definio da API em <linux/fb.h>. Implementa um dispositivo de caractere (/dev/fbX), onde as aplicaes podem ler, escrever e enviar comandos ioctl para o dispositivo.
Embedded Labworks
Definir e inicializar uma estrutura do tipo fb_info. Prover um conjunto de operaes que podem ser realizadas no dispositivo atravs da implementao da estrutura fb_ops. Registrar de register_framebuffer(). o dispositivo framebuffer com a funo
Embedded Labworks
STRUCT FB_OPS
#include<linux/fb.h> staticstructfb_info*info; staticstructfb_opsxxxfb_ops={ .owner=THIS_MODULE, .fb_open=xxxfb_open, .fb_read=xxxfb_read, .fb_write=xxxfb_write, .fb_release=xxxfb_release, .fb_blank=xxxfb_blank, .fb_fillrect=xxxfb_fillrect, .fb_copyarea=xxxfb_copyarea, .fb_sync=xxxfb_sync, .fb_ioctl=xxxfb_ioctl, .fb_mmap=xxxfb_mmap, [...] };
Embedded Labworks
REGISTRANDO O FRAMEBUFFER
staticint__devinitxxxfb_probe(structpci_dev*dev, conststructpci_device_id*ent) { [...] info=framebuffer_alloc(sizeof(structxxx_par), device); info>fbops=&xxxfb_ops; if(register_framebuffer(info)<0) returnEINVAL; [...] }
Embedded Labworks
A CAMADA TTY
o framework padro para dispositivos de comunicao serial (porta serial, conversor USB/serial, etc). Fontes disponveis em drivers/tty/ e definio da API em <linux/tty.h>. Implementa um dispositivo de caractere (normalmente /dev/ttyXX), onde as aplicaes podem ler, escrever e enviar comandos ioctl para o dispositivo.
Embedded Labworks
Driver de baixo nvel: conversa diretamente com o dispositivo de hardware. Driver TTY: faz interface do driver de baixo nvel com o core TTY, provendo uma interface comum de acesso ao dispositivo serial. Core TTY: camada de abstrao entre user space (bibliotecas e aplicaes) e o driver TTY. Line discipline: permite com que o core TTY manipule os dados enviados e recebidos pelo usurio de diferentes formas (terminal, conexo PPP, etc).
Embedded Labworks
Line Discipline
Hardware
Dispositivo serial
Embedded Labworks
Executar uma sesso de terminal atravs de uma conexo RS232. Se conectar Internet via modem dial-up. Se comunicar com dispositivos infravermelho. Emular uma porta serial atravs de um conversor USB/serial. Se comunicar atravs de uma porta RS485. Se conectar remotamente uma mquina via Telnet ou SSH. Etc!
Embedded Labworks
TTY Core
Kernel space
Line Disciplines
Virtual Terminal
Input
Driver
Driver
Driver
Driver
Hardware
Porta RS232
Porta RS485
Conversor USB/Serial
Modem PCMCIA
Monitor
Teclado
Embedded Labworks
UART DRIVER
Portanto, para ser integrado ao kernel, um driver de porta serial precisa fazer parte da camada TTY. Levando em considerao os quatro componentes da camada TTY, isso significa que:
Driver de baixo nvel: precisa ser desenvolvido. Driver TTY: j existe uma implementao do driver TTY para portas seriais chamado serial core. O driver de baixo nvel dever se registrar neste driver TTY. Core TTY: padro, no precisa mexer. Line discipline: tambm padro, e o comum usar N_TTY para que a porta serial funcione como um terminal.
Embedded Labworks
n_tty.c
UART driver
Hardware
UART
Embedded Labworks
Definir uma estrutura do tipo uart_driver que representar o driver. Definir uma estrutura do tipo uart_port para cada porta serial presente no sistema. Definir uma estrutura do tipo uart_ops com as operaes que podem ser realizadas na porta serial, e criar o link com a estrutura
uart_port.
Embedded Labworks
Registrar a estrutura uart_driver na inicializao do driver com uart_register_driver() e desregistrar esta estrutura na rotina de limpeza do driver com uart_unregister_driver(). Registrar a estrutura uart_port com uart_add_one_port() e desregistrar com uart_remove_one_port().
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
LABORATRIO
Embedded Labworks
INFRAESTRUTURA DE BARRAMENTO
Os drivers dependem de uma infraestrutura de barramento que possa identificar, enumerar e se comunicar com os dispositivos conectados ao barramento. A infraestrutura de barramento composta por:
Um driver de barramento (bus driver), que implementa a API para um driver conversar com determinado barramento. Um driver adaptador (adapter driver), capaz de conversar fisicamente com o dispositivo atravs de determinado barramento (USB controllers, I2C adapters).
Embedded Labworks
Embedded Labworks
Existe um driver para cada tipo de barramento (USB, SPI, I2C, PCI, MMC, etc). Podem existir um ou mais drivers adaptadores, um para cada controlador de barramento existente no hardware. Para usar determinado barramento, os drivers adaptadores precisam se registrar no driver do barramento.
Embedded Labworks
DRIVER DE BARRAMENTO
Registrar o barramento, tambm chamado de core infrastructure, atravs da estrutura structbus_type. Permitir o registro de drivers adaptadores (USB controllers, I2C adapters, etc). Permitir o registro de drivers de dispositivo (USB devices, I2C devices, etc). Prover uma API tanto para os drivers de dispositivo quanto para os drivers adaptadores. Implementar as estruturas para a definio do dispositivo e do driver, tipicamente xxx_driver e xxx_device.
Embedded Labworks
Embedded Labworks
NA INICIALIZAO
Core I2C
i2c_add_adapter() i2c-imx
Embedded Labworks
EXEMPLO DE DRIVER
Para ilustrar como os drivers so implementados, vamos estudar o driver do acelermetro MMA8450.
Ele um dispositivo conectado ao barramento I2C, portanto um driver I2C. Ele um dispositivo que gera eventos, portanto usa o framework de input do kernel.
Embedded Labworks
IMPLEMENTANDO O DRIVER
Como este dispositivo esta conectado ao barramento I2C, ele deve implementar um driver I2C. Para isso, necessrio:
Definir uma estrutura do tipo structi2c_driver. Registrar o driver i2c com a funo i2c_add_driver() na inicializao do driver. Desregistrar o driver com a funo i2c_del_driver() na finalizao do driver.
Embedded Labworks
ESTRUTURA I2C
staticstructi2c_drivermma8450_driver={ .driver={ .name="mma8450", .owner=THIS_MODULE, }, .suspend=mma8450_suspend, .resume=mma8450_resume, .probe=mma8450_probe, .remove=__devexit_p(mma8450_remove), [...] };
Embedded Labworks
ADICIONANDO E REMOVENDO
staticint__initmma8450_init(void) { [...] res=i2c_add_driver(&mma8450_driver); [...] } staticvoid__exitmma8450_exit(void) { [...] i2c_del_driver(&mma8450_driver); [...] } module_init(mma8450_init); module_exit(mma8450_exit);
Embedded Labworks
NA INICIALIZAO
Core I2C
i2c_add_driver() mma8450
Embedded Labworks
INSTANCIANDO O DRIVER
A partir deste momento, o barramento I2C sabe que existe um driver para tratar dispositivos do tipo mma8450. Mas para ser usado, o driver precisa ser instanciado. O que instanciar o driver? chamar sua funo probe(). Quando o driver instanciado? Quando o sistema identifica um dispositivo de hardware que pode ser tratado por aquele driver.
Embedded Labworks
Dinamicamente se o barramento possuir suporte enumerao de dispositivos conectados a ele (ex: USB). Estaticamente atravs de uma funo disponibilizada pela infraestrutura do barramento. Estaticamente usando uma funcionalidade chamada de device tree.
Embedded Labworks
Embedded Labworks
DEVICE PROBE
Driver mma8450
i2c_add_driver()
Core I2C
mma8450_probe()
Driver mma8450
Embedded Labworks
O MTODO PROBE
O mtodo probe() recebe como argumento uma estrutura descrevendo o dispositivo de acordo com o barramento (i2c_client, pci_dev, usb_interface, etc). Esta funo responsvel por:
Inicializar o dispositivo, mapear I/O em memria e registrar ISRs. A infraestrutura de barramento normalmente prov mecanismos para ler endereamento de I/O, nmero de interrupes e outras informaes especficas do dispositivo. Registrar o dispositivo no framework correto do kernel.
Embedded Labworks
MMA8450 PROBE
staticint__devinitmma8450_probe( structi2c_client*client, conststructi2c_device_id*id) { [...] result=i2c_smbus_read_byte_data(client, MMA8450_WHO_AM_I); [...] result=input_register_polled_device(idev); [...] }
Embedded Labworks
O MODELO RECURSIVO!
ALSA Network stack Input framework Input driver I2C device driver I2C core Network driver USB device driver I2C adapter driver USB device driver
USB core ALSA driver PCI device driver PCI core PCI Adapter USB Adapter driver PCI device driver
Embedded Labworks
PLATFORM DEVICES
Alguns dispositivos podem no estar conectados em um barramento, como por exemplo uma UART ou algum dispositivo conectado um GPIO. E como prover a mesma soluo sem uma infraestrutura de barramento? Criando a sua prpria infraestrutura de barramento! Esta implementao realizada atravs da infraestrutura de platform device e platform driver.
Embedded Labworks
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, necessrio:
Definir uma estrutura do tipo structplatform_driver. Registrar driver com a funo platform_driver_register() na inicializao do driver. Desregistrar com a funo platform_driver_unregister() na rotina de limpeza do driver. o driver o platform
Embedded Labworks
Embedded Labworks
Embedded Labworks
Como a infraestrutura de platform devices no possui um mecanismo de hotplug, um platform driver pode ser instanciado de duas formas:
Estaticamente atravs da criao e inicializao de uma estrutura do tipo platform_device. Estaticamente atravs da funcionalidade de device tree.
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
USANDO RECURSOS
Todo driver normalmente usa um ou mais recursos de hardware, como portas de I/O, linhas de interrupo ou canais de DMA. Estas informaes podem ser representadas em uma estrutura do tipo structresource, e um vetor de estruturas deste tipo esto associadas um platform device. Este tipo de mecanismo permite que determinado driver possa ser instanciado para gerenciar mltiplos dispositivos, que usam recursos de hardware diferentes, sem que uma linha de cdigo seja alterada.
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
PLATFORM DATA
Alm dos recursos de hardware comuns que podem ser alocados para um determinado dispositivo, muitos dispositivos requerem informaes especficas que no esto disponveis em outros dispositivos de hardware (ex: modos de vdeo de um display). Estas informaes podem ser passadas para um driver em uma outra estrutura chamada de platform_data. Esta estrutura nada mais do que um ponteiro para void dentro da estrutura platform_device.
Embedded Labworks
Embedded Labworks
Embedded Labworks
Embedded Labworks
LABORATRIO
Embedded Labworks
Frameworks
Embedded Labworks
RELEMBRANDO...
User space Bibliotecas/aplicaes
Kernel space
Hardware
Embedded Labworks
TTY
O que ? Subsistema para dispositivos seriais. Quem usa? Porta serial RS232, porta serial RS485, conversor USB/Serial, etc. Interface: /dev/tty*. Fontes: drivers/tty/. Documentao: Documentation/serial/.
Embedded Labworks
INPUT
O que ? Subsistema para dispositivos de entrada. Quem usa? Mouse, teclado, touch screen, acelermetro, boto, etc. Interface: /dev/input/event*. Fontes: drivers/input/. Documentao: Documentation/input/.
Embedded Labworks
FRAMEBUFFER
O que ? Subsistema de vdeo. Quem usa? Controladores de vdeo em geral para conexo com monitores e displays. Interface: /dev/fb* e /sys/class/graphics/fb*/. Fontes: drivers/video/. Documentao: Documentation/fb/.
Embedded Labworks
ALSA
O que ? Subsistema de som (Advanced Linux Sound Architecture). Quem usa? Controladores de udio, placas de som, etc. Interface: /dev/snd/*. Fontes: sound/. Documentao: Documentation/sound/.
Embedded Labworks
V4L2
O que ? Interface para dispositivos de captura de udio e vdeo. Quem usa? Webcam, sintonizador de TV, receptor de rdio, receptor de TV digital, etc. Interface: /dev/dvb/* e /dev/v4l/*. Fontes: drivers/media/. Documentao: Documentation/video4linux/.
Embedded Labworks
BLOCK LAYER
O que ? Subsistema para dispositivos de armazenamento com capacidade de acesso randmico. Quem usa? Discos rgido, CD/DVD, pendrive, etc. Interface: /dev/sd*, /dev/sr*, etc. Fontes: drivers/block/. Documentao: Documentation/block/.
Embedded Labworks
MTD
O que ? Subsistema para memrias flash. Quem usa? Memrias flash NAND e NOR. Interface: /dev/mtd* e /dev/mtdblock*. Fontes: drivers/mtd/. Documentao: Documentation/mtd/.
Embedded Labworks
NETWORK
O que ? Subsistema de rede TCP/IP. Quem usa? Placas de rede em geral. Interface: Socket. Fontes: net/ e drivers/net/. Documentao: Documentation/networking/.
Embedded Labworks
BLUETOOTH
O que ? Subsistema para dispositivos bluetooth. Quem usa? Dispositivos bluetooth em geral. Interface: /dev/rfcomm* para emulao serial, interface de rede ppp*, /dev/input/event* para dispositivo de entrada, etc. Fontes: drivers/bluetooth/. Documentao: -
Embedded Labworks
NFC
O que ? Subsistema para dispositivos NFC. Quem usa? Dispositivos NFC em geral. Interface: Socket. Fontes: net/nfc/ e drivers/nfc/. Documentao: Documentation/nfc/.
Embedded Labworks
IrDA
O que ? Subsistema para comunicao via infravermelho. Quem usa? Dispositivos de comunicao infravermelho. Interface: /dev/rfcomm* para emulao serial, interface de rede ppp*, etc. Fontes: drivers/net/irda/. Documentao: Documentation/networking/irda.txt .
Embedded Labworks
HWMON
O que ? Subsistema para dispositivos de monitoramento do hardware. Quem usa? Sensores em geral (temperatura, corrente, tenso, etc), ventoinha, etc. Interface: /sys/class/hwmon/hwmon*/. Fontes: drivers/hwmon/. Documentao: Documentation/hwmon/.
Embedded Labworks
O que ? Subsistema (recente) para dispositivos conversores analgico/digital. Quem usa? Conversor A/D e D/A, acelermetro, sensor de luz, sensor de proximidade, compasso, giroscpio, magnetrmetro, etc. Interface: /sys/bus/iio/devices/*. Fontes: drivers/iio/. Documentao: drivers/staging/iio/Documentation/ .
Embedded Labworks
WATCHDOG
O que ? Subsistema para dispositivos watchdog. Quem usa? Qualquer chip com funcionalidade de watchdog. Interface: /dev/watchdog. Fontes: drivers/watchdog/. Documentao: Documentation/watchdog/.
Embedded Labworks
RTC
O que ? Subsistema para relgios de tempo real. Quem usa? RTCs em geral. Interface: /dev/rtc* e /sys/class/rtc/rtc*/. Fontes: drivers/rtc/. Documentao: Documentation/rtc.txt.
Embedded Labworks
PWM
O que ? Subsistema (recente) para dispositivos PWM. Quem usa? Qualquer chip com funcionalidade de PWM. Interface: /sys/class/pwm/*. Fontes: drivers/pwm/. Documentao: Documentation/pwm.txt.
Embedded Labworks
O que ? Subsistema para gerenciar pinos de I/O. Quem usa? Toda e qualquer CPU ou SoC que possuir pinos de I/O para serem gerenciados, como o MUX presente nos SoCs atuais. Interface: Fontes: drivers/pinctrl/. Documentao: Documentation/pinctrl.txt.
Embedded Labworks
GPIO
O que ? Subsistema para gerenciar GPIOs. Quem usa? Toda e qualquer CPU ou SoC com GPIOs disponveis, expansor de I/O, shift register, etc. Interface: /sys/class/gpio/*. Fontes: drivers/gpio/. Documentao: Documentation/gpio.txt.
Embedded Labworks
LEDS
O que ? Subsistema para gerenciar leds. Quem usa? Todo e qualquer led disponvel no hardware. Interface: /sys/class/leds/*. Fontes: drivers/leds/. Documentao: Documentation/leds/.
Embedded Labworks
PARPORT
O que ? Subsistema para portas paralelas. Quem usa? Qualquer dispositivo de porta paralela. Interface: /dev/lp*. Fontes: drivers/parport/. Documentao: Documentation/parport.txt.
Embedded Labworks
CLOCK
O que ? Subsistema para gerenciar as fontes de clock do sistema. Quem usa? Todo e qualquer device driver que dependa de um clock para seu funcionamento (Ex: UART). Interface: Fontes: drivers/clk/. Documentao: Documentation/clk.txt.
Embedded Labworks
CPUFREQ
O que ? Subsistema para gerenciamento de energia. Quem usa? Sistema (CPU, SoC, etc). Interface: /sys/devices/system/cpu/cpu*/cpufreq/ . Fontes: drivers/cpufreq/ ou arch/<arch>/*. Documentao: Documentation/cpufreq/.
Embedded Labworks
POWER MANAGEMENT
O que ? Subsistema para gerenciar o estado de gerenciamento de energia do sistema (standby, suspend-to-RAM, suspend-to-disk). Quem usa? Toda plataforma que deseje este tipo de suporte. Interface: /sys/power/. Fontes: drivers/base/power/. Documentao: Documentation/power/.
Embedded Labworks
CPU IDLE
O que ? Subsistema para gerenciar o modo idle da CPU. Quem usa? Qualquer CPU que possua um ou mais modos idle. Interface: /sys/devices/system/cpu/cpu*/cpuidle/ . Fontes: drivers/cpuidle/. Documentao: Documentation/cpuidle/.
Embedded Labworks
POWER SUPPLY
O que ? Subsistema para fontes de energia. Quem usa? Dispositivos de controle de bateria, fontes de alimentao, etc. Interface: /sys/class/power_supply/*. Fontes: drivers/power/. Documentao: Documentation/power/power_supply_class.txt.
Embedded Labworks
REGULATOR
O que ? Subsistema para reguladores de corrente e tenso. Quem usa? Qualquer chip regulador de corrente e tenso. Interface: /sys/class/regulator/*. Fontes: drivers/regulator/. Documentao: Documentation/power/regulator/.
Embedded Labworks
MFD
O que ? Subsistema para chips multifuncionais. Quem usa? Qualquer chip com mltiplas funes. Interface: Fontes: drivers/mfd/. Documentao: -
Embedded Labworks
SEM FRAMEWORK?
So raros os casos onde um dispositivo no se encaixa em nenhum destes frameworks. Mas estes casos ainda existem. Exemplos:
Criar uma interface especfica no /sys. Criar um misc driver com interface no /dev.
Embedded Labworks
LABORATRIO
Embedded Labworks
E agora?
Embedded Labworks
Embedded Labworks
Embedded Labworks
LEIA A DOCUMENTAO
kernel
tem
no
diretrio
O kernel tambm possui um conjunto de documentos em Documentation/DocBook, que podem ser compilados com um dos comandos abaixo:
$makepdfdocs $makehtmldocs
Embedded Labworks
Documentation/ManagementStyle :
descreve gerenciamento do Linux, e um pouco de sua cultura. Linux no tem uma interface (API) estvel.
estilo
de
Embedded Labworks
PROCESSO DE DESENVOLVIMENTO
-next Linus Torvalds Andrew Morton
Mantenedor do subsistema
Mantenedor do subsistema
Desenvolvedor
Desenvolvedor
Desenvolvedor
Desenvolvedor
Desenvolvedor
Desenvolvedor
Embedded Labworks
Boa documentao sobre o processo de desenvolvimento em Documentation/developmentprocess/ . A maioria das rvores git dos subsistemas do kernel encontram-se no link abaixo: http://git.kernel.org/ Cada subsistema possui uma lista de discusso e um ou mais mantenedores.
Embedded Labworks
O e-mail do mantenedor, bem como a lista de discusso do subsistema, esto disponveis no arquivo MAINTAINERS no diretrio principal do kernel. O script scripts/get_maintainer.pl pode te ajudar a identificar o e-mail da lista de discusso e o nome e e-mail dos mantenedores de determinado arquivo ou patch!
Embedded Labworks
GET MAINTAINER
$./scripts/get_maintainer.plfinit/main.c RustyRussell<rusty@rustcorp.com.au>(commit_signer:4/20=20%) JimCromie<jim.cromie@gmail.com>(commit_signer:3/20=15%) AlViro<viro@zeniv.linux.org.uk>(commit_signer:3/20=15%) "H.PeterAnvin"<hpa@linux.intel.com>(commit_signer:3/20=15%) AndrewMorton<akpm@linuxfoundation.org>(commit_signer:2/20=10%) linuxkernel@vger.kernel.org(openlist)
Embedded Labworks
CONTRIBUINDO
Todo o processo de contribuio acontece por e-mail atravs das listas de discusso. A principal lista de discusso a LKML (Linux Kernel Mailing List): http://lkml.org/ Mas muitos subsistemas possuem listas especficas. http://vger.kernel.org/vger-lists.html
Embedded Labworks
CONTRIBUINDO (cont.)
Para colaborar, s preparar o patch e enviar para a lista de discusso e para todos os mantenedores responsveis pelo subsistema. O gerenciamento dos patches enviados feito com a ferramenta patchwork. https://patchwork.kernel.org/
Embedded Labworks
CONTRIBUINDO (cont.)
Embedded Labworks
CONTRIBUINDO (cont.)
$gitclonegit://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $cdlinux/ $gitbranchsmeagol $gitcheckoutsmeagol #changeLinux,andchangetheworld! $scripts/checkpatch.plf<changed_files> $gitcommita $gitformatpatchmaster..smeagol $scripts/get_maintainer.pl<patch_file> $gitsendemailtoemail@email.comccemail@email.com<patch_file>
Embedded Labworks
AGUARDANDO APROVAO
Ao enviar um patch, voc pode esperar por crticas, comentrios, pedidos para alterar o cdigo ou pedidos para explicar determinado ponto da alterao. Voc deve ser capaz de aceitas as crticas, analisar tecnicamente o problema, alterar o cdigo ou explicar claramente os motivos pelos quais o cdigo no foi alterado, e reenviar o patch. Se no receber resposta, espere alguns dias e reenvie o patch.
Embedded Labworks
Publicly making fun of people is half the fun of open source programming. In fact, the real reason to eschew programming in closed environments is that you can't embarrass people in public. Linus Torvalds. um processo que exige muita pacincia e perseverana!
Embedded Labworks
PROCURANDO AJUDA
O website Kernel Newbies um ponto de referncia para buscar ajuda sobre o funcionamento interno do Kernel. http://kernelnewbies.org Possui uma lista de discusso e um canal IRC onde so discutidos qualquer tipo de assunto relacionado ao kernel, do mais bsico ao mais avanado. Lembre-se de procurar nos arquivos da lista antes de postar alguma pergunta!
Embedded Labworks
REPORTANDO PROBLEMAS
Um documento descrevendo como reportar bugs chamado REPORTINGBUGS encontra-se no diretrio principal do kernel. O kernel tambm tem um bug tracker no link abaixo: https://bugzilla.kernel.org Voc pode contribuir reportando ou corrigindo problemas!
Embedded Labworks
PARA COMEAR
Kernel Janitors um projeto do site Kernel Newbies para quem quiser aprender a desenvolver para o kernel revisando o cdigo, fazendo limpezas, convertendo o uso de APIs e dando manuteno em cdigo antigo. http://kernelnewbies.org/KernelJanitors Linux Driver Project um projeto criado para quem quiser ajudar no desenvolvimento de drivers. http://www.linuxdriverproject.org/
Embedded Labworks
LINKS
Site do kernel Linux: http://www.kernel.org Linux kernel mailing list: http://www.tux.org/lkml Acompanhar as mudanas nas novas verses do kernel: http://wiki.kernelnewbies.org/LinuxChanges Notcias e novidades sobre o desenvolvimento do kernel: http://lwn.net
Embedded Labworks
Embedded Labworks
Embedded Labworks
BECOMING A MASTER
Leia muito cdigo! Desenvolva! Leia mais cdigo! Desenvolva! Leia muito mais cdigo! Contribua com a comunidade!
OBRIGADO!
E-mail Website sergio.prado@e-labworks.com http://e-labworks.com
Embedded Labworks
Por Sergio Prado. So Paulo, Novembro de 2012 Copyright Embedded Labworks 2004-2013. All rights reserved.