Drivers de Dispositivos Linux
       2 de Setembro de 2008
Conteúdo

I Sobre essa apostila                                                                                           ...
CDTC                     Centro de Difusão de Tecnologia e Conhecimento                                                   ...
Parte I

Sobre essa apostila




         3
CDTC                   Centro de Difusão de Tecnologia e Conhecimento                Brasília/DF


Conteúdo
    O conteúdo...
Parte II

Informações Básicas




         5
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                Brasília/DF




Sobre o CDTC

   Obj...
CDTC                  Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


     É dada permissão p...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


todos participantes. ...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento                Brasília/DF


A classificação por um t...
Parte III

GNU Free Documentation License




               10
CDTC                   Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


    (Traduzido pelo Jo...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


O quot;Documentoquot;aba...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


FAZENDO CÓPIAS EXATAS
  ...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


MODIFICAÇÕES
    Você...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


seção e preservar a se...
CDTC                  Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


cada seção único adiciona...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


versão original em Inglê...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


tal como a GNU General P...
Parte IV

Driver de Dsipositivo Linux




             19
Capítulo 1

Driver de Dispositivo Linux




Drivers de dispositivo são a interface necessária entre o sistema operacional ...
Capítulo 2

Plano de ensino

2.1   Objetivo
  Capacitar o usuário para o desenvolviemento de drivers de dispositivo para o...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


   • Alocação e manip...
CDTC                 Centro de Difusão de Tecnologia e Conhecimento   Brasília/DF


2.8    Bibliografia
  • The Linux Kerne...
Capítulo 3

Introdução

    O que são drivers de dispositivo e como eles funcionam? Quais os tipos de driver de disposi-
t...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


3.2    Tipos de Dispo...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


na tabela de disposit...
Capítulo 4

Hello Kernel!

   Um Driver simples e que não faz nada!


4.1     Kello Hernell!
    Para exemplificar a interf...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                 Brasília/DF


disponibiliza module_...
Capítulo 5

Arquivos de Dispositivo

   Acesso aos dispositivos via os arquivos do /dev. Arquivos de dispositivos? Como as...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


do mundo: vai saber dife...
CDTC                     Centro de Difusão de Tecnologia e Conhecimento             Brasília/DF


   Os parâmetros first e ...
Capítulo 6

Estruturas

   As estruturas mais importantes para um driver de dispositivo: filp, fops e inode.


6.1    File ...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                   Brasília/DF


  ÐÓÒ ´¶
ÓÑÔ Ø Ó
ØÐ...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                   Brasília/DF


escrita. geralmente...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                  Brasília/DF


pipe_inode_info *, s...
CDTC                  Centro de Difusão de Tecnologia e Conhecimento              Brasília/DF


    ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ     Ö...
CDTC                     Centro de Difusão de Tecnologia e Conhecimento           Brasília/DF


××   Þ   Ø ÑÝ Ú    Ö      ...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                  Brasília/DF


      ÔÖ ÒØ ´Ã ÊÆ   ...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF


6.3     Estrutura de Ino...
CDTC                    Centro de Difusão de Tecnologia e Conhecimento                  Brasília/DF


Bom, cada membro des...
Capítulo 7

Mydev

    Sabendo todas as estruturas importantes, já é hora de fazer algo mais funcional: Vamos agora
criar ...
CDTC                Centro de Difusão de Tecnologia e Conhecimento           Brasília/DF



×Ø Ø 
 ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ß
    ...
CDTC                   Centro de Difusão de Tecnologia e Conhecimento               Brasília/DF



ÑÓ ÙÐ     Ò Ø´ÑÝ Ú     ...
Drivers de Dispositivos Linux
Drivers de Dispositivos Linux
Drivers de Dispositivos Linux
Drivers de Dispositivos Linux
Drivers de Dispositivos Linux
Drivers de Dispositivos Linux
Upcoming SlideShare
Loading in...5
×

Drivers de Dispositivos Linux

2,792

Published on

Drivers de dispositivo são a interface necessária entre o sistema operacional e o hardware do seu computador. Drivers são responsáveis por controlar de forma correta os dispositivos e esconder do próprio sistema operacional os detalhes de baixo nível.

Published in: Education, Technology
1 Comment
1 Like
Statistics
Notes
  • Didatica simplesmente perfeita !!
    Desmistificou algo que a meses eu buscava, em apenas 20 minutos !!
    Parabéns !!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
2,792
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
144
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide

Drivers de Dispositivos Linux

  1. 1. Drivers de Dispositivos Linux 2 de Setembro de 2008
  2. 2. Conteúdo I Sobre essa apostila 2 II Informações Básicas 4 III GNU Free Documentation License 9 IV Driver de Dsipositivo Linux 18 1 Driver de Dispositivo Linux 19 2 Plano de ensino 20 2.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.2 Público Alvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.3 Pré-requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.4 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.5 Cronograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.6 Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.7 Avaliação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.8 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3 Introdução 23 3.1 Driver de Dispositivo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2 Tipos de Dispositivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.3 Interface do Driver com o Sistema Operacional . . . . . . . . . . . . . . . . . . . . . 24 4 Hello Kernel! 26 4.1 Kello Hernell! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.2 Como funciona? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 5 Arquivos de Dispositivo 28 5.1 Tudo é um arquivo! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 5.2 Major e Minor Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6 Estruturas 31 6.1 File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 6.1.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 6.1.2 Fops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 1
  3. 3. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 6.1.3 Inicializando a fops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 6.1.4 Algumas operações de mentirinha . . . . . . . . . . . . . . . . . . . . . . . . 35 6.2 Filp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 6.3 Estrutura de Inode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 6.3.1 Links e inodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 6.3.2 inode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 7 Mydev 40 8 A memória e o Kernel 43 8.1 Como funciona a memória? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 9 Mydev completo 45 9.1 mydev.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 9.2 Utilização do mydev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 2
  4. 4. Parte I Sobre essa apostila 3
  5. 5. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Conteúdo O conteúdo dessa apostila é fruto da compilação de diversos materiais livres publicados na in- ternet, disponíveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br. O formato original deste material bem como sua atualização está disponível dentro da licença GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seção de mesmo nome, tendo inclusive uma versão traduzida (não oficial). A revisão e alteração vem sendo realizada pelo CDTC (suporte@cdtc.org.br), desde outubro de 2006. Criticas e sugestões construtivas são bem-vindas a qualquer tempo. Autores A autoria deste conteúdo, atividades e avaliações é de responsabilidade de Leonardo Gui- lherme de Freitas (lgfreitas@cdtc.org.br) . O texto original faz parte do projeto Centro de Difusão de Tecnolgia e Conhecimento, que vem sendo realizado pelo ITI em conjunto com outros parceiros institucionais, atuando em conjunto com as universidades federais brasileiras que tem produzido e utilizado Software Livre, apoiando inclusive a comunidade Free Software junto a outras entidades no país. Informações adicionais podem ser obtidas atréves do email ouvidoria@cdtc.org.br, ou da home page da entidade, através da URL http://www.cdtc.org.br. Garantias O material contido nesta apostila é isento de garantias e o seu uso é de inteira responsabi- lidade do usuário/leitor. Os autores, bem como o ITI e seus parceiros, não se responsabilizam direta ou indiretamente por qualquer prejuízo oriundo da utilização do material aqui contido. Licença Copyright ©2006,Leonardo Guilherme de Freitas (lgfreitas@cdtc.org.br) . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Chapter being SOBRE ESSA APOS- TILA. A copy of the license is included in the section entitled GNU Free Documentation License. 4
  6. 6. Parte II Informações Básicas 5
  7. 7. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Sobre o CDTC Objetivo Geral O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a dissemina- ção de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira. Objetivo Específico Auxiliar o Governo Federal na implantação do plano nacional de software não-proprietário e de código fonte aberto, identificando e mobilizando grupos de formadores de opinião dentre os servidores públicos e agentes políticos da União Federal, estimulando e incentivando o mercado nacional a adotar novos modelos de negócio da tecnologia da informação e de novos negócios de comunicação com base em software não-proprietário e de código fonte aberto, oferecendo treinamento específico para técnicos, profissionais de suporte e funcionários públicos usuários, criando grupos de funcionários públicos que irão treinar outros funcionários públicos e atuar como incentivadores e defensores de produtos de software não proprietários e código fonte aberto, ofe- recendo conteúdo técnico on-line para serviços de suporte, ferramentas para desenvolvimento de produtos de software não proprietários e de seu código fonte livre, articulando redes de terceiros (dentro e fora do governo) fornecedoras de educação, pesquisa, desenvolvimento e teste de pro- dutos de software livre. Guia do aluno Neste guia, você terá reunidas uma série de informações importantes para que você comece seu curso. São elas: • Licenças para cópia de material disponível • Os 10 mandamentos do aluno de Educação a Distância • Como participar dos fóruns e da wikipédia • Primeiros passos É muito importante que você entre em contato com TODAS estas informações, seguindo o roteiro acima. Licença Copyright ©2006, Leonardo Guilherme de Freitas (lgfreitas@cdtc.org.br) . 6
  8. 8. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior publicada pela Free Software Foundation; com o Capítulo Invariante SOBRE ESSA APOSTILA. Uma cópia da licença está inclusa na seção entitulada quot;Licença de Docu- mentação Livre GNUquot;. Os 10 mandamentos do aluno de educação online • 1. Acesso a Internet: ter endereço eletrônico, um provedor e um equipamento adequado é pré-requisito para a participação nos cursos a distância. • 2. Habilidade e disposição para operar programas: ter conhecimentos básicos de Informá- tica é necessário para poder executar as tarefas. • 3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distân- cia conta muitos pontos, pois irá colaborar para o processo ensino-aprendizagem pessoal, dos colegas e dos professores. • 4. Comportamentos compatíveis com a etiqueta: mostrar-se interessado em conhecer seus colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo. • 5. Organização pessoal: planejar e organizar tudo é fundamental para facilitar a sua revisão e a sua recuperação de materiais. • 6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigações e realizá-las em tempo real. • 7. Curiosidade e abertura para inovações: aceitar novas idéias e inovar sempre. • 8. Flexibilidade e adaptação: requisitos necessário a mudança tecnológica, aprendizagens e descobertas. • 9. Objetividade em sua comunicação: comunicar-se de forma clara, breve e transparente é ponto-chave na comunicação pela Internet. • 10. Responsabilidade: ser responsável por seu próprio aprendizado. O ambiente virtual não controla a sua dedicação, mas reflete os resultados do seu esforço e da sua colaboração. Como participar dos fóruns e Wikipédia Você tem um problema e precisa de ajuda? Podemos te ajudar de 2 formas: A primeira é o uso dos fóruns de notícias e de dúvidas gerais que se distinguem pelo uso: O fórum de notícias tem por objetivo disponibilizar um meio de acesso rápido a informações que sejam pertinentes ao curso (avisos, notícias). As mensagens postadas nele são enviadas a 7
  9. 9. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF todos participantes. Assim, se o monitor ou algum outro participante tiver uma informação que interesse ao grupo, favor postá-la aqui. Porém, se o que você deseja é resolver alguma dúvida ou discutir algum tópico específico do curso, é recomendado que você faça uso do Fórum de dúvidas gerais que lhe dá recursos mais efetivos para esta prática. . O fórum de dúvidas gerais tem por objetivo disponibilizar um meio fácil, rápido e interativo para solucionar suas dúvidas e trocar experiências. As mensagens postadas nele são enviadas a todos participantes do curso. Assim, fica muito mais fácil obter respostas, já que todos podem ajudar. Se você receber uma mensagem com algum tópico que saiba responder, não se preocupe com a formalização ou a gramática. Responda! E não se esqueça de que antes de abrir um novo tópico é recomendável ver se a sua pergunta já foi feita por outro participante. A segunda forma se dá pelas Wikis: Uma wiki é uma página web que pode ser editada colaborativamente, ou seja, qualquer par- ticipante pode inserir, editar, apagar textos. As versões antigas vão sendo arquivadas e podem ser recuperadas a qualquer momento que um dos participantes o desejar. Assim, ela oferece um ótimo suporte a processos de aprendizagem colaborativa. A maior wiki na web é o site quot;Wikipé- diaquot;, uma experiência grandiosa de construção de uma enciclopédia de forma colaborativa, por pessoas de todas as partes do mundo. Acesse-a em português pelos links: • Página principal da Wiki - http://pt.wikipedia.org/wiki/ Agradecemos antecipadamente a sua colaboração com a aprendizagem do grupo! Primeiros Passos Para uma melhor aprendizagem é recomendável que você siga os seguintes passos: • Ler o Plano de Ensino e entender a que seu curso se dispõe a ensinar; • Ler a Ambientação do Moodle para aprender a navegar neste ambiente e se utilizar das ferramentas básicas do mesmo; • Entrar nas lições seguindo a seqüência descrita no Plano de Ensino; • Qualquer dúvida, reporte ao Fórum de Dúvidas Gerais. Perfil do Tutor Segue-se uma descrição do tutor ideal, baseada no feedback de alunos e de tutores. O tutor ideal é um modelo de excelência: é consistente, justo e profissional nos respectivos valores e atitudes, incentiva mas é honesto, imparcial, amável, positivo, respeitador, aceita as idéias dos estudantes, é paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar. 8
  10. 10. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF A classificação por um tutor desta natureza proporciona o melhor feedback possível, é crucial, e, para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem.’ Este tutor ou instrutor: • fornece explicações claras acerca do que ele espera, e do estilo de classificação que irá utilizar; • gosta que lhe façam perguntas adicionais; • identifica as nossas falhas, mas corrige-as amavelmente’, diz um estudante, ’e explica por- que motivo a classificação foi ou não foi atribuída’; • tece comentários completos e construtivos, mas de forma agradável (em contraste com um reparo de um estudante: ’os comentários deixam-nos com uma sensação de crítica, de ameaça e de nervosismo’) • dá uma ajuda complementar para encorajar um estudante em dificuldade; • esclarece pontos que não foram entendidos, ou corretamente aprendidos anteriormente; • ajuda o estudante a alcançar os seus objetivos; • é flexível quando necessário; • mostra um interesse genuíno em motivar os alunos (mesmo os principiantes e, por isso, talvez numa fase menos interessante para o tutor); • escreve todas as correções de forma legível e com um nível de pormenorização adequado; • acima de tudo, devolve os trabalhos rapidamente; 9
  11. 11. Parte III GNU Free Documentation License 10
  12. 12. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF (Traduzido pelo João S. O. Bueno através do CIPSGA em 2001) Esta é uma tradução não oficial da Licençaa de Documentação Livre GNU em Português Brasileiro. Ela não é publicada pela Free Software Foundation, e não se aplica legalmente a dis- tribuição de textos que usem a GFDL - apenas o texto original em Inglês da GNU FDL faz isso. Entretanto, nós esperamos que esta tradução ajude falantes de português a entenderem melhor a GFDL. This is an unofficial translation of the GNU General Documentation License into Brazilian Por- tuguese. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GFDL–only the original English text of the GFDL does that. However, we hope that this translation will help Portuguese speakers understand the GFDL better. Licença de Documentação Livre GNU Versão 1.1, Março de 2000 Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA É permitido a qualquer um copiar e distribuir cópias exatas deste documento de licença, mas não é permitido alterá-lo. INTRODUÇÃO O propósito desta Licença é deixar um manual, livro-texto ou outro documento escrito quot;livrequot;no sentido de liberdade: assegurar a qualquer um a efetiva liberdade de copiá-lo ou redistribui-lo, com ou sem modificações, comercialmente ou não. Secundariamente, esta Licença mantém para o autor e editor uma forma de ter crédito por seu trabalho, sem ser considerado responsável pelas modificações feitas por terceiros. Esta Licença é um tipo de quot;copyleftquot;(quot;direitos revertidosquot;), o que significa que derivações do documento precisam ser livres no mesmo sentido. Ela complementa a GNU Licença Pública Ge- ral (GNU GPL), que é um copyleft para software livre. Nós fizemos esta Licença para que seja usada em manuais de software livre, por que software livre precisa de documentação livre: um programa livre deve ser acompanhado de manuais que provenham as mesmas liberdades que o software possui. Mas esta Licença não está restrita a manuais de software; ela pode ser usada para qualquer trabalho em texto, independentemente do assunto ou se ele é publicado como um livro impresso. Nós recomendamos esta Licença prin- cipalmente para trabalhos cujo propósito seja de introdução ou referência. APLICABILIDADE E DEFINIÇÕES Esta Licença se aplica a qualquer manual ou outro texto que contenha uma nota colocada pelo detentor dos direitos autorais dizendo que ele pode ser distribuído sob os termos desta Licença. 11
  13. 13. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF O quot;Documentoquot;abaixo se refere a qualquer manual ou texto. Qualquer pessoa do público é um licenciado e é referida como quot;vocêquot;. Uma quot;Versão Modificadaquot;do Documento se refere a qualquer trabalho contendo o documento ou uma parte dele, quer copiada exatamente, quer com modificações e/ou traduzida em outra língua. Uma quot;Seção Secundáriaquot;é um apêndice ou uma seção inicial do Documento que trata ex- clusivamente da relação dos editores ou dos autores do Documento com o assunto geral do Documento (ou assuntos relacionados) e não contém nada que poderia ser incluído diretamente nesse assunto geral (Por exemplo, se o Documento é em parte um livro texto de matemática, a Seção Secundária pode não explicar nada de matemática). Essa relação poderia ser uma questão de ligação histórica com o assunto, ou matérias relaci- onadas, ou de posições legais, comerciais, filosóficas, éticas ou políticas relacionadas ao mesmo. As quot;Seções Invariantesquot;são certas Seções Secundárias cujos títulos são designados, como sendo de Seções Invariantes, na nota que diz que o Documento é publicado sob esta Licença. Os quot;Textos de Capaquot;são certos trechos curtos de texto que são listados, como Textos de Capa Frontal ou Textos da Quarta Capa, na nota que diz que o texto é publicado sob esta Licença. Uma cópia quot;Transparentequot;do Documento significa uma cópia que pode ser lida automatica- mente, representada num formato cuja especificação esteja disponível ao público geral, cujos conteúdos possam ser vistos e editados diretamente e sem mecanismos especiais com editores de texto genéricos ou (para imagens compostas de pixels) programas de pintura genéricos ou (para desenhos) por algum editor de desenhos grandemente difundido, e que seja passível de servir como entrada a formatadores de texto ou para tradução automática para uma variedade de formatos que sirvam de entrada para formatadores de texto. Uma cópia feita em um formato de arquivo outrossim Transparente cuja constituição tenha sido projetada para atrapalhar ou de- sencorajar modificações subsequentes pelos leitores não é Transparente. Uma cópia que não é quot;Transparentequot;é chamada de quot;Opacaquot;. Exemplos de formatos que podem ser usados para cópias Transparentes incluem ASCII sim- ples sem marcações, formato de entrada do Texinfo, formato de entrada do LaTex, SGML ou XML usando uma DTD disponibilizada publicamente, e HTML simples, compatível com os padrões, e projetado para ser modificado por pessoas. Formatos opacos incluem PostScript, PDF, formatos proprietários que podem ser lidos e editados apenas com processadores de texto proprietários, SGML ou XML para os quais a DTD e/ou ferramentas de processamento e edição não estejam disponíveis para o público, e HTML gerado automaticamente por alguns editores de texto com finalidade apenas de saída. A quot;Página do Títuloquot;significa, para um livro impresso, a página do título propriamente dita, mais quaisquer páginas subsequentes quantas forem necessárias para conter, de forma legível, o material que esta Licença requer que apareça na página do título. Para trabalhos que não tenham uma página do título, quot;Página do Títuloquot;significa o texto próximo da aparição mais proe- minente do título do trabalho, precedendo o início do corpo do texto. 12
  14. 14. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF FAZENDO CÓPIAS EXATAS Você pode copiar e distribuir o Documento em qualquer meio, de forma comercial ou não comercial, desde que esta Licença, as notas de copyright, e a nota de licença dizendo que esta Licença se aplica ao documento estejam reproduzidas em todas as cópias, e que você não acres- cente nenhuma outra condição, quaisquer que sejam, às desta Licença. Você não pode usar medidas técnicas para obstruir ou controlar a leitura ou confecção de cópias subsequentes das cópias que você fizer ou distribuir. Entretanto, você pode aceitar com- pensação em troca de cópias. Se você distribuir uma quantidade grande o suficiente de cópias, você também precisa respeitar as condições da seção 3. Você também pode emprestar cópias, sob as mesmas condições colocadas acima, e também pode exibir cópias publicamente. FAZENDO CÓPIAS EM QUANTIDADE Se você publicar cópias do Documento em número maior que 100, e a nota de licença do Documento obrigar Textos de Capa, você precisará incluir as cópias em capas que tragam, clara e legivelmente, todos esses Textos de Capa: Textos de Capa da Frente na capa da frente, e Textos da Quarta Capa na capa de trás. Ambas as capas também precisam identificar clara e legivelmente você como o editor dessas cópias. A capa da frente precisa apresentar o titulo com- pleto com todas as palavras do título igualmente proeminentes e visíveis. Você pode adicionar outros materiais às capas. Fazer cópias com modificações limitadas às capas, tanto quanto estas preservem o título do documento e satisfaçam a essas condições, pode ser tratado como cópia exata em outros aspectos. Se os textos requeridos em qualquer das capas for muito volumoso para caber de forma legível, você deve colocar os primeiros (tantos quantos couberem de forma razoável) na capa verdadeira, e continuar os outros nas páginas adjacentes. Se você publicar ou distribuir cópias Opacas do Documento em número maior que 100, você precisa ou incluir uma cópia Transparente que possa ser lida automaticamente com cada cópia Opaca, ou informar, em ou com, cada cópia Opaca a localização de uma cópia Transparente completa do Documento acessível publicamente em uma rede de computadores, a qual o público usuário de redes tenha acesso a download gratuito e anônimo utilizando padrões públicos de protocolos de rede. Se você utilizar o segundo método, você precisará tomar cuidados razoavel- mente prudentes, quando iniciar a distribuição de cópias Opacas em quantidade, para assegurar que esta cópia Transparente vai permanecer acessível desta forma na localização especificada por pelo menos um ano depois da última vez em que você distribuir uma cópia Opaca (direta- mente ou através de seus agentes ou distribuidores) daquela edição para o público. É pedido, mas não é obrigatório, que você contate os autores do Documento bem antes de redistribuir qualquer grande número de cópias, para lhes dar uma oportunidade de prover você com uma versão atualizada do Documento. 13
  15. 15. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF MODIFICAÇÕES Você pode copiar e distribuir uma Versão Modificada do Documento sob as condições das se- ções 2 e 3 acima, desde que você publique a Versão Modificada estritamente sob esta Licença, com a Versão Modificada tomando o papel do Documento, de forma a licenciar a distribuição e modificação da Versão Modificada para quem quer que possua uma cópia da mesma. Além disso, você precisa fazer o seguinte na versão modificada: A. Usar na Página de Título (e nas capas, se houver alguma) um título distinto daquele do Do- cumento, e daqueles de versões anteriores (que deveriam, se houvesse algum, estarem listados na seção quot;Histórico do Documentoquot;). Você pode usar o mesmo título de uma versão anterior se o editor original daquela versão lhe der permissão; B. Listar na Página de Título, como autores, uma ou mais das pessoas ou entidades responsá- veis pela autoria das modificações na Versão Modificada, conjuntamente com pelo menos cinco dos autores principais do Documento (todos os seus autores principais, se ele tiver menos que cinco); C. Colocar na Página de Título o nome do editor da Versão Modificada, como o editor; D. Preservar todas as notas de copyright do Documento; E. Adicionar uma nota de copyright apropriada para suas próprias modificações adjacente às outras notas de copyright; F. Incluir, imediatamente depois das notas de copyright, uma nota de licença dando ao público o direito de usar a Versão Modificada sob os termos desta Licença, na forma mostrada no tópico abaixo; G. Preservar nessa nota de licença as listas completas das Seções Invariantes e os Textos de Capa requeridos dados na nota de licença do Documento; H. Incluir uma cópia inalterada desta Licença; I. Preservar a seção entitulada quot;Históricoquot;, e seu título, e adicionar à mesma um item dizendo pelo menos o título, ano, novos autores e editor da Versão Modificada como dados na Página de Título. Se não houver uma sessão denominada quot;Históricoquot;no Documento, criar uma dizendo o título, ano, autores, e editor do Documento como dados em sua Página de Título, então adicionar um item descrevendo a Versão Modificada, tal como descrito na sentença anterior; J. Preservar o endereço de rede, se algum, dado no Documento para acesso público a uma cópia Transparente do Documento, e da mesma forma, as localizações de rede dadas no Docu- mento para as versões anteriores em que ele foi baseado. Elas podem ser colocadas na seção quot;Históricoquot;. Você pode omitir uma localização na rede para um trabalho que tenha sido publicado pelo menos quatro anos antes do Documento, ou se o editor original da versão a que ela se refira der sua permissão; K. Em qualquer seção entitulada quot;Agradecimentosquot;ou quot;Dedicatóriasquot;, preservar o título da 14
  16. 16. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF seção e preservar a seção em toda substância e fim de cada um dos agradecimentos de contri- buidores e/ou dedicatórias dados; L. Preservar todas as Seções Invariantes do Documento, inalteradas em seus textos ou em seus títulos. Números de seção ou equivalentes não são considerados parte dos títulos da seção; M. Apagar qualquer seção entitulada quot;Endossosquot;. Tal sessão não pode ser incluída na Versão Modificada; N. Não reentitular qualquer seção existente com o título quot;Endossosquot;ou com qualquer outro título dado a uma Seção Invariante. Se a Versão Modificada incluir novas seções iniciais ou apêndices que se qualifiquem como Seções Secundárias e não contenham nenhum material copiado do Documento, você pode optar por designar alguma ou todas aquelas seções como invariantes. Para fazer isso, adicione seus títulos à lista de Seções Invariantes na nota de licença da Versão Modificada. Esses títulos preci- sam ser diferentes de qualquer outro título de seção. Você pode adicionar uma seção entitulada quot;Endossosquot;, desde que ela não contenha qual- quer coisa além de endossos da sua Versão Modificada por várias pessoas ou entidades - por exemplo, declarações de revisores ou de que o texto foi aprovado por uma organização como a definição oficial de um padrão. Você pode adicionar uma passagem de até cinco palavras como um Texto de Capa da Frente , e uma passagem de até 25 palavras como um Texto de Quarta Capa, ao final da lista de Textos de Capa na Versão Modificada. Somente uma passagem de Texto da Capa da Frente e uma de Texto da Quarta Capa podem ser adicionados por (ou por acordos feitos por) qualquer entidade. Se o Documento já incluir um texto de capa para a mesma capa, adicionado previamente por você ou por acordo feito com alguma entidade para a qual você esteja agindo, você não pode adicionar um outro; mas você pode trocar o antigo, com permissão explícita do editor anterior que adicionou a passagem antiga. O(s) autor(es) e editor(es) do Documento não dão permissão por esta Licença para que seus nomes sejam usados para publicidade ou para assegurar ou implicar endossamento de qualquer Versão Modificada. COMBINANDO DOCUMENTOS Você pode combinar o Documento com outros documentos publicados sob esta Licença, sob os termos definidos na seção 4 acima para versões modificadas, desde que você inclua na com- binação todas as Seções Invariantes de todos os documentos originais, sem modificações, e liste todas elas como Seções Invariantes de seu trabalho combinado em sua nota de licença. O trabalho combinado precisa conter apenas uma cópia desta Licença, e Seções Invariantes Idênticas com multiplas ocorrências podem ser substituídas por apenas uma cópia. Se houver múltiplas Seções Invariantes com o mesmo nome mas com conteúdos distintos, faça o título de 15
  17. 17. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF cada seção único adicionando ao final do mesmo, em parênteses, o nome do autor ou editor origianl daquela seção, se for conhecido, ou um número que seja único. Faça o mesmo ajuste nos títulos de seção na lista de Seções Invariantes nota de licença do trabalho combinado. Na combinação, você precisa combinar quaisquer seções entituladas quot;Históricoquot;dos diver- sos documentos originais, formando uma seção entitulada quot;Históricoquot;; da mesma forma combine quaisquer seções entituladas quot;Agradecimentosquot;, ou quot;Dedicatóriasquot;. Você precisa apagar todas as seções entituladas como quot;Endossoquot;. COLETÂNEAS DE DOCUMENTOS Você pode fazer uma coletânea consitindo do Documento e outros documentos publicados sob esta Licença, e substituir as cópias individuais desta Licença nos vários documentos com uma única cópia incluida na coletânea, desde que você siga as regras desta Licença para cópia exata de cada um dos Documentos em todos os outros aspectos. Você pode extrair um único documento de tal coletânea, e distribuí-lo individualmente sob esta Licença, desde que você insira uma cópia desta Licença no documento extraído, e siga esta Licença em todos os outros aspectos relacionados à cópia exata daquele documento. AGREGAÇÃO COM TRABALHOS INDEPENDENTES Uma compilação do Documento ou derivados dele com outros trabalhos ou documentos se- parados e independentes, em um volume ou mídia de distribuição, não conta como uma Ver- são Modificada do Documento, desde que nenhum copyright de compilação seja reclamado pela compilação. Tal compilação é chamada um quot;agregadoquot;, e esta Licença não se aplica aos outros trabalhos auto-contidos compilados junto com o Documento, só por conta de terem sido assim compilados, e eles não são trabalhos derivados do Documento. Se o requerido para o Texto de Capa na seção 3 for aplicável a essas cópias do Documento, então, se o Documento constituir menos de um quarto de todo o agregado, os Textos de Capa do Documento podem ser colocados em capas adjacentes ao Documento dentro do agregado. Senão eles precisarão aparecer nas capas de todo o agregado. TRADUÇÃO Tradução é considerada como um tipo de modificação, então você pode distribuir traduções do Documento sob os termos da seção 4. A substituição de Seções Invariantes por traduções requer uma permissão especial dos detentores do copyright das mesmas, mas você pode incluir traduções de algumas ou de todas as Seções Invariantes em adição às versões orignais dessas Seções Invariantes. Você pode incluir uma tradução desta Licença desde que você também in- clua a versão original em Inglês desta Licença. No caso de discordância entre a tradução e a 16
  18. 18. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF versão original em Inglês desta Licença, a versão original em Inglês prevalecerá. TÉRMINO Você não pode copiar, modificar, sublicenciar, ou distribuir o Documento exceto como expres- samente especificado sob esta Licença. Qualquer outra tentativa de copiar, modificar, sublicen- ciar, ou distribuir o Documento é nula, e resultará automaticamente no término de seus direitos sob esta Licença. Entretanto, terceiros que tenham recebido cópias, ou direitos de você sob esta Licença não terão suas licenças terminadas, tanto quanto esses terceiros permaneçam em total acordo com esta Licença. REVISÕES FUTURAS DESTA LICENÇA A Free Software Foundation pode publicar novas versões revisadas da Licença de Documen- tação Livre GNU de tempos em tempos. Tais novas versões serão similares em espirito à versão presente, mas podem diferir em detalhes ao abordarem novos porblemas e preocupações. Veja http://www.gnu.org/copyleft/. A cada versão da Licença é dado um número de versão distinto. Se o Documento especificar que uma versão particular desta Licença quot;ou qualquer versão posteriorquot;se aplica ao mesmo, você tem a opção de seguir os termos e condições daquela versão específica, ou de qualquer versão posterior que tenha sido publicada (não como rascunho) pela Free Software Foundation. Se o Documento não especificar um número de Versão desta Licença, você pode escolher qualquer versão já publicada (não como rascunho) pela Free Software Foundation. ADENDO: Como usar esta Licença para seus documentos Para usar esta Licença num documento que você escreveu, inclua uma cópia desta Licença no documento e ponha as seguintes notas de copyright e licenças logo após a página de título: Copyright (c) ANO SEU NOME. É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior publicada pela Free Soft- ware Foundation; com as Seções Invariantes sendo LISTE SEUS TÍTULOS, com os Textos da Capa da Frente sendo LISTE, e com os Textos da Quarta-Capa sendo LISTE. Uma cópia da li- cença está inclusa na seção entitulada quot;Licença de Documentação Livre GNUquot;. Se você não tiver nenhuma Seção Invariante, escreva quot;sem Seções Invariantesquot;ao invés de dizer quais são invariantes. Se você não tiver Textos de Capa da Frente, escreva quot;sem Textos de Capa da Frentequot;ao invés de quot;com os Textos de Capa da Frente sendo LISTEquot;; o mesmo para os Textos da Quarta Capa. Se o seu documento contiver exemplos não triviais de código de programas, nós recomenda- mos a publicação desses exemplos em paralelo sob a sua escolha de licença de software livre, 17
  19. 19. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF tal como a GNU General Public License, para permitir o seu uso em software livre. 18
  20. 20. Parte IV Driver de Dsipositivo Linux 19
  21. 21. Capítulo 1 Driver de Dispositivo Linux Drivers de dispositivo são a interface necessária entre o sistema operacional e o hardware do seu computador. Drivers são responsáveis por controlar de forma correta os dispositivos e esconder do próprio sistema operacional os detalhes de baixo nível. 20
  22. 22. Capítulo 2 Plano de ensino 2.1 Objetivo Capacitar o usuário para o desenvolviemento de drivers de dispositivo para o Kernel 2.6.x do SO GNU/Linux. 2.2 Público Alvo Técnicos e Programadores com experiência em programação usando C que desejam um caminho para criar os próprios drivers de dispositivo. 2.3 Pré-requisitos É necessário sólido conhecimento em lógica de programação e familiaridade com a linguagem C, além de domínio do SO GNU/Linux. 2.4 Descrição O curso de Driver de Dispositivo Linux será realizado na modalidade EAD e utilizará a plata- forma Moodle como ferramenta de aprendizagem. O material didático estará disponível on-line de acordo com as datas pré-estabelecidas no calendário. A versão utilizada para o Kernel do Linux será a 2.6.18; O curso está dividido da seguinte maneira: 2.5 Cronograma • Introdução; • Interface SO<->driver. • Código de exemplo. • Estruturas do dispositivo. • Aprimoração do driver exemplo 21
  23. 23. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF • Alocação e manipulação de memória • Finalização do driver exemplo As lições contém o contéudo principal. Elas poderão ser acessadas quantas vezes forem neces- sárias, desde que esteja dentro da semana programada. Ao final de uma lição, você receberá uma nota de acordo com o seu desempenho. Responda com atenção às perguntas de cada lição, pois elas serão consideradas na sua nota final. Caso sua nota numa determinada lição for menor do que 6.0, sugerimos que você faça novamente esta lição. Ao final do curso será disponibilizada a avaliação referente ao curso. Tanto as notas das lições quanto a da avaliação serão consideradas para a nota final. Todos os módulos ficarão visíveis para que possam ser consultados durante a avaliação final. Aconselhamos a leitura da quot;Ambientação do Moodlequot;para que você conheça a plataforma de Ensino a Distância, evitando dificuldades advindas do quot;desconhecimentoquot;sobre a mesma. Os instrutores estarão a sua disposição ao longo de todo curso. Qualquer dúvida deverá ser enviada no fórum. Diariamente os monitores darão respostas e esclarecimentos. 2.6 Programa O curso de Driver de Dispositivo Linux oferecerá o seguinte conteúdo: • Estudo das estruturas do kernel • Estudo das áreas de memória • Estudo da criação de arquivos de dispositivo • Programação em C dos drivers de exemplo 2.7 Avaliação Toda a avaliação será feita on-line. Aspectos a serem considerados na avaliação: • Iniciativa e autonomia no processo de aprendizagem e de produção de conhecimento; • Capacidade de pesquisa e abordagem criativa na solução dos problemas apresentados. Instrumentos de avaliação: • Participação ativa nas atividades programadas. • Avaliação ao final do curso. • O participante fará várias avaliações referente ao conteúdo do curso. Para a aprovação e obtenção do certificado o participante deverá obter nota final maior ou igual a 6.0 de acordo com a fórmula abaixo: • Nota Final = ((ML x 7) + (AF x 3)) / 10 = Média aritmética das lições • AF = Avaliações 22
  24. 24. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 2.8 Bibliografia • The Linux Kernel: http://www.kernel.org • LinuxDevCenter: http://www.linuxdevcenter.com 23
  25. 25. Capítulo 3 Introdução O que são drivers de dispositivo e como eles funcionam? Quais os tipos de driver de disposi- tivo? Como funciona a interação do sistema operacional com o driver? 3.1 Driver de Dispositivo? Quando um programa precisa fazer um acesso a sua impressora para imprimir qualquer coisa, é utilizado um device driver. Sem um desses, o programa necessitaria de acesso direto a im- pressora e, pior ainda, teria que saber exatamente como o controlador físico dessa impressora funciona. Isso provavelmente ficaria ainda pior: todo programa que fosse imprimir funcionaria so- mente para uma impressora ou teria que saber como funcionam todas as impressoras do mundo, além de saber como identificá-las. Certamente, isso é inviável. Device drivers fornecem um nível de abstração para o desenvolvimento de programas que necessitam acesso a um dispositivo físico. Isso quer dizer que, ao invés de embutir em todos os programas o código para controlar a impressora X, simplesmente chamo uma função (por exemplo, print()) em meu programa e o sistema operacional se encarrega de procurar nos drivers carregados o código correspondente, e delega a essa porção de código a responsabilidade pelo controle da impressora. Se amanhã eu decidir que preciso de uma impressora Y e não mais da X, basta instalar os drivers da impressora Y e nada mais precisará de alteração. Assim funciona com basicamente tudo: discos, mouses, teclados, placas de vídeo, etc. Ge- ralmente você precisa identificá-los somente uma vez, e o sistema operacional se encarrega de encontrar os drivers corretos e esse sim é responsável pelo controle adequado do hardware. Na maioria dos sistemas operacionais, os device drivers mais importantes (também os mais genéricos) e utilizados em grande escala pelo computador geralmente estão compilados dentro do kernel (núcleo do sistema), e os utilizados com menos freqüência ou que não exigem demanda muito grande são carregados como módulos. Também são módulos os drivers que não estão disponíveis inicialmente pelo sistema operacional - drivers disponibilizados por terceiros ou os que você criar. Drivers devem ser programados e tratados cuidadosamente: um código destinado a ser driver de dispositivo funcionará com permissão ao hardware e ao sistema em si, podendo danificá-los seriamente. A maior parte do curso será abordada dentro do sistema operacional GNU/Linux, pois, pela característica de ser código aberto, possui a transparência necessária para o processo de criação de device drivers. 24
  26. 26. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 3.2 Tipos de Dispositivos Basicamente os dispositivos de hardware são separados da seguinte forma: dispositivos de caractere e dispositivos de bloco (Character device e Block device, respectivamente; há ainda os dispositivos de rede que possuem características diferentes e não serão abordados por en- quanto). A diferença entre eles é que o acesso aos dados de um dispositivo de caractere é seqüencial, enquanto nos dispositivos de bloco o acesso geralmente é aleatório. Isso é, um dispositivo de caractere é tão rápido quanto possível para escrever e ler dados do seu hardware e portanto não precisa de um buffer (o dispositivo em si não trabalha com um buffer). Uma outra característica de um dispositivo seqüencial é que não é possível ’retroceder’ a posição dos dados (na verdade, não faz o menor sentido). São dispositivos de streamming. Um bom exemplo de um dispositivo de caractere é o teclado: não faz sentido, via hardware, quot;ler a tecla que foi digitada 10 teclas atrásquot;, mas no entanto cada tecla pressionada é imediatamente enviada ao sistema operacional. Dispositivos de caracteres também têm esse nome pois geralmente o acesso é feito quot;um caractere (1 byte)quot;por vez. Já num dispositivo de bloco, por sua característica de acesso aleatório, é imprescindível o uso de um buffer. Na verdade, enquanto um programa utiliza um dispositivo de bloco, ele pode até ter a impressão que está lendo e escrevendo diretamente no dispositivo (como faria normalmente em um dispositivo de caractere), mas, na verdade, está realizando tais operações no buffer do dispositivo e esse, por sua vez, se encarrega de fazer a mudança fisicamente, na hora certa. Analisando o seu disco rígido é fácil chegar a conclusão de que ele é um dispositivo de bloco, pois você pode acessar dados que estão em partes diferentes do disco. Se o acesso ao disco fosse seqüencial, essa operação seria simplesmente impossível. Uma outra razão para que seja chamado dispositivo de blocos é que o acesso ao dispositivo é feito em blocos de dados (512 bytes, por exemplo). No entanto, para a maioria dos usuários do Linux/Unix, não faz diferença se o dispositivo é de bloco ou de caractere: é possível ler e escrever nesse dispositivo como se ele fosse um arquivo qualquer. A distinção de que tipo de dispositivo e como ler e escrever nele fica por conta do sistema operacional e do driver. 3.3 Interface do Driver com o Sistema Operacional mesma forma que o sistema operacional cria a possibilidade de um programa imprimir utili- zando a simples função print(), um device driver deve possibilitar o sistema operacional controlar essa mesma impressora utilizando uma função como control_printer(), independente da impres- sora. Isso quer dizer que o SO não se importa se você vai usar uma impressora da marca X ou Y, ele simplesmente vai chamar a função control_printer(), e o seu device driver deve responder a essa chamada de função da mesma forma que o sistema operacional responde à função print() do programa. Em outros termos, enquanto o device driver é a implementação virtual da impressora, a função control_printer() é a sua interface com o sistema operacional. Para dar mais um realce à idéia de interface e implementação: se hoje você utiliza discos SCSI e amanhã decidir utilizar discos IDE, a única mudança é o driver que será carregado. O Sistema operacional continuará chamando as mesmas funções de acesso ao disco. Sendo um pouco mais exato, cada device driver deve implementar uma struct cujos seus elementos são os ponteiros para as funções de controle, e o kernel, quando carrega esse driver, registra essa struct na memória. Assim que o driver é efetivamente carregado, o kernel chama a função de inicialização. O trabalho da função de inicialização consiste em registrar o dispositivo 25
  27. 27. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF na tabela de dispositivos e dar a ele a identificação necessária, além de inicializar outras structs que o driver vai utilizar. Na utilização do dispositivo, o kernel chama as funções de controle, leitura e escrita disponibilizadas. Quando o driver é descarregado, o kernel chama a função de finalização, responsável por desregistrar o dispositivo no sistema e limpar da memória. Vamos ver tudo isso com mais detalhes, pode ficar tranqüilo :) 26
  28. 28. Capítulo 4 Hello Kernel! Um Driver simples e que não faz nada! 4.1 Kello Hernell! Para exemplificar a interface do sistema operacional com o driver, vamos criar um quot;Hello Ker- nelquot;. O driver não faz nada de muito importante, só exibe uma mensagem quando é carregado e outra quando é descarregado. »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Ò ÐÙ Ð ÒÙÜ» Ò Øº Ò ÐÙ Ð ÒÙÜ»ÑÓ ÙÐ º ÅÇ ÍÄ ÄÁ ÆË ´ Ù Ð Ë » ÈÄ µ »¶ Ú Ø Ö Ð Ñ Ó × ÖÒ Ð ¶» ×Ø Ø ÒØ ÐÐÓ ´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ Ã ÐÐÓ¸ À ÖÒ Ð ℄ Ò µ »¶ Ó × × ÕÙ Þ Ñ Ó× Ö Ú Ö× ×ÔÓ× Ø ÚÓ× ¶» Ö ØÙÖÒ ¼ ×Ø Ø ÚÓ Ý ´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ Ý ¸ à ÖÒ Ð Ò µ ÑÓ ÙÐ Ò Ø´ ÐÐÓ µ ÑÓ ÙÐ Ü Ø´ Ý µ »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» 4.2 Como funciona? Dissecando o nosso módulo (que não tem muito o que ser dissecado, na verdade), encontra- mos algumas coisas parecidas com programas normais, outras, nem tanto. A primeira coisa a ser notada são os arquivos de include: nada de stdio.h nem string.h. Entretanto, temos <linux/init.h> e <linux/module.h>. Esses dois cabeçalhos devem aparecer em todos os módulos carregáveis. <linux/module.h> tem muitas definições importantes e símbolos utilizados em módulos e init.h 27
  29. 29. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF disponibiliza module_init e module_exit, além de outras coisas. Drivers geralmente utilizam muito mais includes, mas esses você vai encontrar em qualquer um deles. Você provavelmente deve ter percebido que não temos uma função main(). Ao invés dela existem as chamadas macros module_init e module_exit, que recebe como parâmetros, respec- tivamente, as funções de inicialização e de saída do módulo. Quando o driver for carregado, ele chama a função registrada por module_init e quando descarregar, a função registrada em module_exit. Para imprimir na tela, temos uma função que engana. Parece muito a velha conhecida printf. No entanto, printk é uma função controlada unicamente pelo kernel, pois esse não pode de- pender de funções disponibilizadas por bibliotecas que podem não estar presentes no futuro (se utilizássemos printf, nosso módulo dependeria da presença da libc, que muito provavelmente não estará disponível). Outras características que diferem printk de printf (além de trocar f por k): o argumento de urgência (KERN_ALERT, que é definida como <1>. Quanto maior o número entre <>, menor a prioridade. Dependendo do valor, a mensagem pode nem mesmo ser exibida) que vem antes da string que será exibida. Outra é que printk não suporta números de ponto flutuante (float). A diferença mais importante de um módulo para um programa comum é que módulos são orientados ao evento. Em outras palavras, enquanto o seu programa favorito abre, executa o que tem que executar e depois sai, um módulo é carregado no kernel informando o que sabe fazer e com quem. Depois disso não faz mais nada. Fica lá, parado, junto com um monte de módulos, esperando ordens que podem aparecer ou não. Para compilar esse módulo é necessário um pouco mais de trabalho. Primeiramente, para kernels da versão 2.6.x, você vai precisar dos fontes do kernel instalados e compilados. Em versões 2.4.x, apenas os headers do kernel eram necessários. Vai ser necessário criar um makefile um pouco diferente dos padrões para que a compilação funcione. O kernel tem seu próprio ’jeitinho’ de utilizar makefiles, chamado kbuild. Por hora, nosso Makefile vai se parecer com isso ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ Ó ¹Ñ ÐÐÓ ÖÒ ÐºÓ ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ Esse makefile deve estar no mesmo diretório do código do seu módulo. Compile-o da seguinte forma: make -C /caminho/do/fonte/linux M=‘pwd‘ modules (Digite esse comando dentro da pasta que está o seu makefile e o seu módulo) No final, você vai ter um arquivo do formato hellokernel.ko. Carregue o módulo utilizando o comando insmod hellokernel.ko, e o descarregue com rmmod hellokernel.ko. Se tudo correu bem, o driver vai exibir as respectivas mensagens que programa- mos. 28
  30. 30. Capítulo 5 Arquivos de Dispositivo Acesso aos dispositivos via os arquivos do /dev. Arquivos de dispositivos? Como assim? 5.1 Tudo é um arquivo! quot;No Linux, tudo é um arquivoquot;. Essa é a máxima da maioria dos usuários do Linux. Enquanto outros sistemas operacionais mais populares representam dispositivos de armazenamento por letras e quot;escondemquot;a localização dos outros dispositivos (e como eles são controlados), no sis- tema operacional do pingüim todos os dispositivos tem uma correspondência no diretório /dev (com exceção das interfaces de rede), onde são, de fato, arquivos. Sendo assim, você pode testar o comando _ echo quot;Oi dispositivo!» /dev/tty1 _ e dependendo de onde você utilizar esse comando, aparecerá na sua tela a mensagem quot;Oi dispositivo!quot;(/dev/tty* são dispositivos de termi- nais). Quem provê esse tipo de praticidade é em parte o sistema operacional e em parte o seu driver de dispositivo. Quando você chama o comando quot;echoquot;com redirecionamento de saída (>) para um arquivo de dispositivo, o sistema operacional logo descobre qual é o driver que o controla e envia a mensagem a ele. Talvez você se pergunte agora: quot;como o sistema operacional vai descobrir qual driver controla aquele dispositivo?quot;. Ou, pior, como o SO sabe que tipo de arquivo é esse? Por que é um dispositivo? Se você já utilizou alguma vez o comando mknod, deve lembrar-se que ele cria a representação (em forma de arquivo) para os dispositivos. Analisemos o comando com um exemplo: Ñ ÒÓ » Ú»Ñ Ù ×ÔÓ× Ø ÚÓ ¼ ¼ O primeiro parâmetro obviamente é o nome do arquivo que representará o dispositivo. O parâmetro c diz que está sendo criado um dispositivo de caractere. O que nos interessa agora são os dois números subseqüentes, 60 e 0. O 60 seria o quot;major numberquot;e 0 o quot;minor numberquot;. Major/minor numbers são utilizados como a identidade virtual do hardware. Junto com o tipo de dispositivo (no nosso caso, um dispositivo de caractere indicado com o parâmetro ’c’) e com esses números, o sistema operacional é capaz de identificar qual driver está controlando o dispositivo e faz a ligação entre eles dois. Vários dispositivos podem utilizar o mesmo major number (indi- cando assim que são controlados pelo mesmo driver), mas cada um deles tem um minor number único. Sendo um pouco mais claro, major numbers identificam para o sistema operacional, qual dispositivo controla aquele hardware e minor numbers identificam para o driver qual a variação que aquele hardware possui, para que esse possa adequar-se. Eu sei que vou acabar repetindo isso em algum ponto do curso. Se você não entendeu muito bem, continue lendo. Lembre-se que os números de dispositivo indicam apenas qual driver está controlando aquele hardware, e não o seu tipo. Isso significa que um mesmo driver pode controlar todos os tipos de dispositivos 29
  31. 31. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF do mundo: vai saber diferenciá-los pelo minor number. Obviamente que isso é uma tática sem sentido (para não dizer burra). O módulo seria um bloco gigantesco de código e muito lento, sem contar que, se eu preciso controlar as LEDs do meu gabinete, é praticamente uma piada carregar os controladores de um mouse. O driver por sua vez, quando é carregado na memória deve passar o major number do dis- positivo e quantos minor numbers ele pretende controlar, e o kernel registrará na sua tabela de dispositivos aquele driver. Dessa forma, o SO quot;casaquot;o arquivo de dispositivo com o seu driver. O tcl é muito útil para quem quer manipular string, ele oferece uma vasta quantidade de comandos para esse fim, como nosso curso é apenas uma introdução à linguagem não abordaremos todos os comandos. 5.2 Major e Minor Numbers A representação de major e minor numbers dentro do kernel fica por conta de um tipo de dado declarado em linux/types.h. É o tipo dev_t que, na verdade, é um espaço de 32 bits onde 12 bits são reservados para major numbers e os 20 bits restantes são reservados para minor numbers. As macros/funções que trabalham com o tipo dev_t estão no cabeçalho linux/kdev_t.h. As mais importantes para o esse momento no curso são MAJOR, MINOR e MKDEV. MAJOR e MINOR retornam major e minor numbers, respectivamente, de uma dada variável do tipo dev_t. MKDEV faz o contrário. Sabendo o major e o minor number, ele constrói a estrutura e a retorna no formato de dev_t. MAJOR(dev_t dev); MINOR(dev_t dev); MKDEV(int major, int minor); Ex: dev_t dev = MKDEV(60, 0); int major = MAJOR(dev); int minor = MINOR(dev); Como dito anteriormente, cada device driver deve declarar major e minor numbers que vai controlar. Existem duas formas de fazer isso, com funções prototipadas em linux/fs.h. A primeira é usar a função register_chrdev_region para drivers de caractere, que tem essa cara: int register_chrdev_region(dev_t first, unsigned int count, char *name); first é o nosso número de dispositivo (que pode ter sido criado com MKDEV, por exemplo). Geralmente, mas não necessariamente, o minor number em first é 0. count é a quantidade de devices que o driver controla; isso é, quantos minor numbers ele vai utilizar. name é o nome do dispositivo que vai aparecer em /proc/devices. Não confunda isso com o nome em /dev. Quem controla isso é o comando mknod. A função retorna 0 se tudo correr bem, e qualquer outro número se houver algum erro. A desvantagem dessa função é que o controle sobre os números é precário: você pode pedir números já alocados. Para contornar essa situação, existe uma função de alocação dinâmica de números de dispositivos. A função tem esse protótipo: int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); dev deve ser um ponteiro do tipo dev_t, onde será armazenado o resultado da alocação dos números de dispositivo. firstminor é o primeiro minor a ser utilizado. Os outros parâmetros são iguais aos de register_chrdev_region. A grande utilidade dessa função é que a probabilidade de colisão de números é pouca, pois retorna o primeiro número de dispositivo não utilizado. No entanto, isso torna mais difícil a utilização do comando mknod, pois você deve buscar em /proc/devices o número para utilizar. Uma dessas funções (register_chrdev_region ou alloc_chrdev_region) deve estar na sua fun- ção de inicialização. Quando o device driver for descarregado, a função unregister_chrdev_region deve estar presente na função de finalização. unregister_chrdev_region tem esse protótipo: void unregister_chrdev_region(dev_t first, unsigned int count); 30
  32. 32. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Os parâmetros first e count são os mesmos de register_chrdev_region. Vale lembrar que essas funções são para drivers de caractere. As funções de driver de bloco têm um jeito muito parecido. Já dá para deixar nosso módulo um pouquinho mais interessante. kernumbers.c »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Ò ÐÙ Ð ÒÙÜ» Ò Øº Ò ÐÙ Ð ÒÙÜ»ÑÓ ÙÐ º Ò ÐÙ Ð ÒÙÜ»ØÝÔ ×º Ò ÐÙ Ð ÒÙÜ» Ú Øº Ò ÐÙ Ð ÒÙÜ» ׺ ÅÇ ÍÄ ÄÁ ÆË ´ Ù Ð Ë » ÈÄ µ »¶ Ú Ø Ö Ð Ñ Ó × ÖÒ Ð ¶» »¶ Î Ö Ú × ÐÓ × ×× ÖÕÙ ÚÓº ÈÓ ÑÓ× ÔÖ × Ö Ð × Ñ × Ø Ö ¶» ×Ø Ø ÒØ Ñ ÓÖ ×Ø Ø Ú Ø Ú ×Ø Ø ÒØ ÐÐÓ ´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ Ã ÐÐÓ¸ À ÖÒ Ð ℄ Ò µ »¶ Ê ×ØÖ ÙÑ Ö Ú Ö ÓÑ ¿ Ñ ÒÓÖ ÒÙÑ Ö× ÓÑ Ó ÒÓÑ Ö Ú Ö ¶» ´ ÐÐÓ Ö Ú Ö ÓÒ´² Ú¸ ¼¸ ¿¸ Ö Ú Ö µµ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÀÓÙÚ ÙÑ ÔÖÓ Ð Ñ ÐÓ Ò Ó Ó× Ò Ñ ÖÓ× Ö Ú Ö Ò µ Ü Ø´½µ Ñ ÓÖ Å ÂÇÊ´ Úµ ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÆÓ××Ó Ñ ÓÖ ÒÙÑ Ö ± Ò ¸ Ñ ÓÖµ »¶ ÇÙØÖ × Ó × × ÕÙ Þ Ñ Ó× Ö Ú Ö× ×ÔÓ× Ø ÚÓ× ¶» Ö ØÙÖÒ ¼ ×Ø Ø ÚÓ Ý ´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ Ý ¸ à ÖÒ Ð Ò µ »¶ ×Ö ×ØÖ Ó ÒÓ××Ó Ö Ú Ö ¶» ÙÒÖ ×Ø Ö Ö Ú Ö ÓÒ´² Ú¸ ¿µ ÑÓ ÙÐ Ò Ø´ ÐÐÓ µ ÑÓ ÙÐ Ü Ø´ Ý µ »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» O código é auto-explicativo. O Makefile deve ser alterado de acordo com o novo nome do módulo. Para verificar se está tudo ok, você pode dar uma olhada no arquivo /proc/devices e /proc/modules: Ø »ÔÖÓ »ÑÓ ÙÐ × Ö Ô ÖÒÙÑ Ö× e Ø »ÔÖÓ » Ú × Ö Ô Ö Ú Ö O primeiro deve mostrar o seu módulo na lista de módulos carregados e o segundo mostra o nú- mero utilizado pelo seu quot;dispositivoquot;. 31
  33. 33. Capítulo 6 Estruturas As estruturas mais importantes para um driver de dispositivo: filp, fops e inode. 6.1 File Operations 6.1.1 Introdução Até agora foi a parte fácil da implementação de um driver de dispositivo. Se você queria saber apenas como funcionam os módulos, pode parar por aqui, pois a partir de agora a gente entra na parte em que o curso fica interessante (e complicado). Vamos levar o nosso driver um pouco mais a sério: implementaremos a estrutura de operações de arquivo. No entanto, o nosso driver vai fazer todas as operações num dispositivo de caractere quot;fictícioquot;. Como já dito, quando o driver é carregado na memória, além de registrar major e minor num- bers, ele deve registrar a estrutura de operações de arquivo referente ao driver (lembre-se que mesmo os dispositivos são representados como arquivos no linux e por isso precisam declarar quais operações estão disponíveis para esse arquivo). A definição dessas estruturas estão em <linux/fs.h>. Mesmo que o parágrafo acima não tenha ficado muito claro, tudo fica mais óbvio quando temos um pedaço de código para analisar, certo? Enfim chega de bate-papo. Vamos dar uma boa olhada na estrutura de operações de arquivo. É uma das mais importantes. 6.1.2 Fops Esta é a famosa quot;fops (file operations)quot;: ×ØÖÙ Ø Ð ÓÔ Ö Ø ÓÒ× ß ×ØÖÙ Ø ÑÓ ÙÐ ¶ÓÛÒ Ö ÐÓ Ø ´¶ÐÐ× µ ´×ØÖÙ Ø Ð ¶¸ ÐÓ Ø¸ Òص ×× Þ Ø ´¶Ö µ ´×ØÖÙ Ø Ð ¶¸ Ö Ù× Ö ¶¸ × Þ Ø¸ ÐÓ Ø ¶µ ×× Þ Ø ´¶ÛÖ Ø µ ´×ØÖÙ Ø Ð ¶¸ ÓÒ×Ø Ö Ù× Ö ¶¸ × Þ Ø¸ ÐÓ Ø ¶µ ×× Þ Ø ´¶ Ó Ö µ ´×ØÖÙ Ø Ó ¶¸ ÓÒ×Ø ×ØÖÙ Ø ÓÚ ¶¸ ÙÒ× Ò ÐÓÒ ¸ ÐÓ Øµ ×× Þ Ø ´¶ Ó ÛÖ Ø µ ´×ØÖÙ Ø Ó ¶¸ ÓÒ×Ø ×ØÖÙ Ø ÓÚ ¶¸ ÙÒ× Ò ÐÓÒ ¸ ÐÓ Øµ ÒØ ´¶Ö Öµ ´×ØÖÙ Ø Ð ¶¸ ÚÓ ¶¸ ÐÐ Ö Øµ ÙÒ× Ò ÒØ ´¶ÔÓÐе ´×ØÖÙ Ø Ð ¶¸ ×ØÖÙ Ø ÔÓÐÐ Ø Ð ×ØÖÙ Ø ¶µ ÒØ ´¶ Ó Øе ´×ØÖÙ Ø ÒÓ ¶¸ ×ØÖÙ Ø Ð ¶¸ ÙÒ× Ò Òظ ÙÒ× Ò ÐÓÒ µ ÐÓÒ ´¶ÙÒÐÓ Ó Øе ´×ØÖÙ Ø Ð ¶¸ ÙÒ× Ò Òظ ÙÒ× Ò ÐÓÒ µ 32
  34. 34. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÐÓÒ ´¶ ÓÑÔ Ø Ó Øе ´×ØÖÙ Ø Ð ¶¸ ÙÒ× Ò Òظ ÙÒ× Ò ÐÓÒ µ ÒØ ´¶ÑÑ Ôµ ´×ØÖÙ Ø Ð ¶¸ ×ØÖÙ Ø ÚÑ Ö ×ØÖÙ Ø ¶µ ÒØ ´¶ÓÔ Òµ ´×ØÖÙ Ø ÒÓ ¶¸ ×ØÖÙ Ø Ð ¶µ ÒØ ´¶ ÐÙ× µ ´×ØÖÙ Ø Ð ¶¸ Ð ÓÛÒ Ö Ø µ ÒØ ´¶Ö Ð × µ ´×ØÖÙ Ø ÒÓ ¶¸ ×ØÖÙ Ø Ð ¶µ ÒØ ´¶ ×ÝÒ µ ´×ØÖÙ Ø Ð ¶¸ ×ØÖÙ Ø ÒØÖÝ ¶¸ ÒØ Ø ×ÝÒ µ ÒØ ´¶ Ó ×ÝÒ µ ´×ØÖÙ Ø Ó ¶¸ ÒØ Ø ×ÝÒ µ ÒØ ´¶ ×ÝÒ µ ´ Òظ ×ØÖÙ Ø Ð ¶¸ Òص ÒØ ´¶ÐÓ µ ´×ØÖÙ Ø Ð ¶¸ Òظ ×ØÖÙ Ø Ð ÐÓ ¶µ ×× Þ Ø ´¶× Ò Ô µ ´×ØÖÙ Ø Ð ¶¸ ×ØÖÙ Ø Ô ¶¸ Òظ × Þ Ø¸ ÐÓ Ø ¶¸ Òص ÙÒ× Ò ÐÓÒ ´¶ Ø ÙÒÑ ÔÔ Ö µ´×ØÖÙ Ø Ð ¶¸ ÙÒ× Ò ÐÓÒ ¸ ÙÒ× Ò ÐÓÒ ¸ ÙÒ× Ò ÐÓÒ ¸ ÙÒ× Ò ÐÓÒ µ ÒØ ´¶ Ð ×µ´ Òص ÒØ ´¶ Ö ÒÓØ Ýµ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÙÒ× Ò ÐÓÒ Ö µ ÒØ ´¶ ÐÓ µ ´×ØÖÙ Ø Ð ¶¸ Òظ ×ØÖÙ Ø Ð ÐÓ ¶µ ×× Þ Ø ´¶×ÔÐ ÛÖ Ø µ´×ØÖÙ Ø Ô Ô ÒÓ Ò Ó ¶¸ ×ØÖÙ Ø Ð ¶¸ ÐÓ Ø ¶¸ × Þ Ø¸ ÙÒ ×× Þ Ø ´¶×ÔÐ Ö µ´×ØÖÙ Ø Ð ¶¸ ÐÓ Ø ¶¸ ×ØÖÙ Ø Ô Ô ÒÓ Ò Ó ¶¸ × Þ Ø¸ ÙÒ× ÒØ ´¶× ØÐ × µ´×ØÖÙ Ø Ð ¶¸ ÐÓÒ ¸ ×ØÖÙ Ø Ð ÐÓ ¶¶µ É uma estrutura um tanto quanto densa. A maioria do seu conteúdo são ponteiros para funções que você deve implementar. A estrutura em si é apenas a interface. Preencher essa struct é uma das operações que seu driver deve fazer na inicialização. Para que serve cada uma dessas funções? Você pergunta. Bom, algumas dão para deduzir pelo nome, outras, nem tanto. De qualquer forma, vamos analisar os elementos mais importantes para o nosso driver. struct module *owner: O primeiro ponteiro não é uma função. É um ponteiro para o mó- dulo que é o quot;donoquot;dessa struct. Geralmente, o seu valor é THIS_MODULE. (THIS_MODULE é definido em <linux/module.h>). loff_t (*llseek) (struct file *, loff_t, int): Função responsável pela manipulação da cabeça de leitura (offset) do arquivo. Esse offset é declarado na estrutura de arquivo, que veremos adiante. Ela retorna a nova posição no arquivo, se for bem sucedida ou algum número negativo caso falhe. ssize_t (*read) (struct file *, char __user *, size_t, loff_t *): O nome denuncia. É usado para ler informações do dispositivo. Retorna a quantidade que foi lida com sucesso ou um número negativo caso falhe. Se esse ponteiro for declarado como NULL, o arquivo não poderá ser lido. ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *): Escreve dados em um dispositivo. Retorna a quantidade que foi escrita com sucesso ou um número negativo caso falhe. Se esse ponteiro for declarado como NULL, a escrita no arquivo de dispositivo será impossível. ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t) e ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t): Fazem a mesma coisa que read e write, mas de forma assíncrona, isto é, a função pode retornar antes que a operação termine. Se forem NULL, todas as operaçõe de leitura e escrita serão feitas de forma síncrona. int (*readdir) (struct file *, void *, filldir_t): Função que permite a leitura de diretórios. Para driver de dispositivo ela não é implementada. unsigned int (*poll) (struct file *, struct poll_table_struct *): Função que retorna uma más- cara informando se é possível ou não utilizar as funções de leitura/escrita sem que elas quot;blo- queiemquot;o fluxo do programa (por exemplo, scanf é uma função que interrompe o programa). int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long): Função utilizada para mandar comandos especfíficos do hardware em questão, que não são nem de leitura nem 33
  35. 35. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF escrita. geralmente são comandos de controle de dispositivo. long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long) e long (*compat_ioctl) (struct file *, unsigned int, unsigned long): São alternativas mais recentes à ioctl(). ioctl() utiliza um recurso chamado Big Kernel Lock (BKL). BKLs são utilizadas em sistemas multiproces- sados (SMP) para garantir a consistência do kernel. Existem partes críticas do kernel que, para continuarem funcionando, devem esperar a resposta de algum dispositivo que foi controlado com ioctl() (como por exemplo, o resultado de um cálculo executado por outro processador na mesma máquina). Assim, antes de se utilizar alguma ioctl() crítica, o kernel deve ser colocado em modo de espera. unlocked_ioctl() é um recurso relativamente recente no kernel (apareceu por volta da versão 2.6.11 em forma de um patch) que deve implementar dentro de seu próprio código uma forma de bloquear a parte significativa para a chamada do kernel. compat_ioctl serve para fazer chamadas de 32 bits em sistemas de 64 bits. As duas funções não serão abordadas nesse curso, por serem de uso muito específico. (Por curiosidade, ioctl() não é a única função que utiliza BKL. open(), llseek() e outras também utilizam). int (*mmap) (struct file *, struct vm_area_struct *): mmap() é muito importante pois torna disponível alguma área de memória do dispositivo ao processo chamador, sendo possível controlá- la. int (*open) (struct inode *, struct file *): Função sempre chamada quando um arquivo de dispositivo (/dev/hda1, por exemplo) é aberto. O seu driver não precisa implementá-la e a abertura sempre irá funcionar. No entanto, sem essa chamada no seu driver, é impossível saber quando o arquivo de dispositivo está sendo aberto. int (*flush) (struct file *, fl_owner_t id): Dispositivos que trabalham com buffer geralmente aguardam o preenchimento de um certo tamanho de bloco na região da sua memória antes de efetuar a operação de escrita. flush() certifica-se que essa operação será executada. Essa função é chamanda somente antes da aplicação encerrar as operações com a sua cópia do descritor do arquivo (file descriptor), e portanto não deve ser confundida com fsync(). Observe que o programador geralmente não tem controle sobre flush(). int (*release) (struct inode *, struct file *): Chamada quando o arquivo é fechado. Assim como open(), se for NULL, o seu driver não será avisado dessa operação. Observe que release só é chamado pelo SO quando todos os aplicativos encerram sua utilização do o dispositivo. Assim, se dois processos complartilham o mesmo descritor de arquivo (utilizando fork(), por exemplo), somente flush() é utilizado quando um deles é encerrado. Se ninguém mais utiliza o arquivo, aí sim é chamado release(). int (*fsync) (struct file *, struct dentry *, int datasync): Essa operação se encarrega de tratar qualquer dado ainda pendente entre o processo e o dispositivo. É como flush(), mas o programador pode utilizá-la em qualquer momento. int (*aio_fsync) (struct kiocb *, int datasync): Como fsync, mas é assíncrona. Isso é, não deixa o processo chamador em modo de espera. int (*fasync) (int, struct file *, int): Utilizado para notificar ao dispositivo alguma mudança na flag FASYNC. Não será abordado nesse curso. int (*lock) (struct file *, int, struct file_lock *): Implementa a quot;travaquot;de arquivo, isto é, se um processo está quot;escrevendoquot;no arquivo, outro processo deve esperar a liberação antes de efetuar alguma outra operação que precise de lock. ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsig- ned long); int (*check_flags)(int); int (*dir_notify)(struct file *filp, unsigned long arg); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct 34
  36. 36. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **); As funções acima sem explicação tratam de tópicos mais avançados, fora do escopo desse curso, ou são funções de pouco uso em device drivers. Lembre-se que as funções nessa estrutura não são específicas de drivers de dispositivos, mas pertencem à struct file, que descreve qualquer arquivo carregado na memória e/ou controlado pelo kernel. Mesmo dentre as funções explicadas, existem algumas que jamais serão implementadas por nós, como aio_fsync ou unlocked_ioctl. 6.1.3 Inicializando a fops Há uma coisa que tem que estar clara em sua cabeça, e que talvez ainda não esteja clara no curso. Perceba que a estrutura file_operations pertence AO KERNEL (mais especificamente, ao nosso driver). Um programador jamais irá chamar diretamente write() ou read() do dispositivo, por exemplo. Um usuário do sistema muito menos. Lembra do quot;echo Oi! > /dev/tty1quot;? Nesse momento, o shell abre o arquivo /dev/tty1 com open() (da biblioteca fcntl.h) e o kernel percebe a chamada e utiliza open() do driver. Então o shell utiliza write() e assim também faz o kernel. Quando o shell encerra a utilização do arquivo, ele chama close() e o kernel usa flush() e release(). Portanto, os módulos devem implementar essas chamadas e inicializá-las na estrutura de file operations. Vamos desenvolver um pouco mais o nosso driver: mydev.c »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Ò ÐÙ Ð ÒÙÜ» Ò Øº Ò ÐÙ Ð ÒÙÜ»ÑÓ ÙÐ º Ò ÐÙ Ð ÒÙÜ»ØÝÔ ×º Ò ÐÙ Ð ÒÙÜ» Ú Øº Ò ÐÙ Ð ÒÙÜ» ׺ ÅÇ ÍÄ ÄÁ ÆË ´ Ù Ð Ë » ÈÄ µ ×Ø Ø ÒØ Ñ ÓÖ ×Ø Ø Ú Ø Ú »¶ ÈÖÓØÓØ ÔÓ× × ÙÒ Ó × ÔÖ Ò Ô × ¶» ÒØ ÑÝ Ú ÓÔ Ò´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ÒØ ÑÝ Ú Ö Ð × ´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ×× Þ Ø ÑÝ Ú Ö ´×ØÖÙ Ø Ð ¶ ÐÔ¸ Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ× ×× Þ Ø ÑÝ Ú ÛÖ Ø ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÓÒ×Ø Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ »¶ ÁÒ Ð Þ Ó ÓÔ× ¶» ×ØÖÙ Ø Ð ÓÔ Ö Ø ÓÒ× ÑÝ Ú ß ºÓÛÒ Ö ÌÀÁË ÅÇ ÍÄ ¸ ºÓÔ Ò ÑÝ Ú ÓÔ Ò¸ ºÖ Ð × ÑÝ Ú Ö Ð × ¸ ºÖ ÑÝ Ú Ö ¸ ºÛÖ Ø ÑÝ Ú ÛÖ Ø ¸ ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ß 35
  37. 37. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÖÖ Ò Ó ÑÝ Ú Ò µ »¶ Ö ×ØÖ Ó Ö Ú Ö ÓÑ ¿ Ñ ÒÓÖ ÒÙÑ Ö× ¶» ´ ÐÐÓ Ö Ú Ö ÓÒ´² Ú¸ ¼¸ ¼¸ Ö Ú Ö µµ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÀÓÙÚ ÙÑ ÔÖÓ Ð Ñ ÐÓ Ò Ó Ó Ö Ú Ö Ò µ Ö ØÙÖÒ ½ Ñ ÓÖ Å ÂÇÊ´ Úµ ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÆÓ××Ó Ñ ÓÖ ÒÙÑ Ö ± Ò ¸ Ñ ÓÖµ Ö ØÙÖÒ ¼ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ × ÖÖ Ò Ó ÑÓ ÙÐÓ Ò µ ÙÒÖ ×Ø Ö Ö Ú Ö ÓÒ´ Ú¸ ¼µ ÑÓ ÙÐ Ò Ø´ÑÝ Ú Ò Øµ ÑÓ ÙÐ Ü Ø´ÑÝ Ú Ü Øµ »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» A primeira diferença é que o módulo está com uma carinha mais séria. Uma outra é que prototipamos as nossas funções básicas. Depois, criamos uma struct file_operations, chamada mydev, e inicializamos com aquelas funções prototipadas. O resto do código certamente você já conhece. Agora você me pergunta: quot;É possível usar esse módulo só com o protótipo das funções?quot;. Provavelmente, se está me fazendo essa pergunta, você não compilou e carregou o módulo. A resposta é NÃO. A princípio, é possível compilar com sucesso esse módulo, mas a compilação vai dar avisos de símbolos indefinidos. Bom, ignorando isso, tentando um insmod mydev.ko, o módulo não carrega, alegando agora símbolos desconhecidos. 6.1.4 Algumas operações de mentirinha Já que o kernel está reclamando que não conhece alguns símbolos, vamos criá-los. Segue o código, dessa vez com uma implementação. »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Ò ÐÙ Ð ÒÙÜ» Ò Øº Ò ÐÙ Ð ÒÙÜ»ÑÓ ÙÐ º Ò ÐÙ Ð ÒÙÜ»ØÝÔ ×º Ò ÐÙ Ð ÒÙÜ» Ú Øº Ò ÐÙ Ð ÒÙÜ» ׺ ÅÇ ÍÄ ÄÁ ÆË ´ Ù Ð Ë » ÈÄ µ »¶ Ë ÔÖ Ð ¸ ÖÒ Ð ØÓ ¶» ×Ø Ø ÒØ Ñ ÓÖ ×Ø Ø Ú Ø Ú »¶ ÈÖÓØÓØ ÔÓ× × ÙÒ Ó × ÔÖ Ò Ô × ¶» ÒØ ÑÝ Ú ÓÔ Ò´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ÒØ ÑÝ Ú Ö Ð × ´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ 36
  38. 38. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ×× Þ Ø ÑÝ Ú Ö ´×ØÖÙ Ø Ð ¶ ÐÔ¸ Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ× ×× Þ Ø ÑÝ Ú ÛÖ Ø ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÓÒ×Ø Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ »¶ ÁÒ Ð Þ Ó ÓÔ× ¶» ×ØÖÙ Ø Ð ÓÔ Ö Ø ÓÒ× ÑÝ Ú ÓÔ× ß ºÓÛÒ Ö ÌÀÁË ÅÇ ÍÄ ¸ ºÓÔ Ò ÑÝ Ú ÓÔ Ò¸ ºÖ Ð × ÑÝ Ú Ö Ð × ¸ ºÖ ÑÝ Ú Ö ¸ ºÛÖ Ø ÑÝ Ú ÛÖ Ø ¸ ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÖÖ Ò Ó ÑÝ Ú Ò µ »¶ Ö ×ØÖ Ó Ö Ú Ö ÓÑ ¿ Ñ ÒÓÖ ÒÙÑ Ö× ¶» ´ ÐÐÓ Ö Ú Ö ÓÒ´² Ú¸ ¼¸ ¿¸ Ö Ú Ö µµ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÀÓÙÚ ÙÑ ÔÖÓ Ð Ñ ÐÓ Ò Ó Ó Ö Ú Ö Ò µ Ö ØÙÖÒ ½ Ñ ÓÖ Å ÂÇÊ´ Úµ ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÆÓ××Ó Ñ ÓÖ ÒÙÑ Ö ± Ò ¸ Ñ ÓÖµ Ö ØÙÖÒ ¼ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ × ÖÖ Ò Ó Ö Ú Ö Ò µ ÙÒÖ ×Ø Ö Ö Ú Ö ÓÒ´ Ú¸ ¿µ ÒØ ÑÝ Ú ÓÔ Ò´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÑÝ Ú ÓÔ Ò´µ Ò µ Ö ØÙÖÒ ¼ ÒØ ÑÝ Ú Ö Ð × ´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÑÝ Ú Ö Ð × ´µ Ò µ Ö ØÙÖÒ ¼ ×× Þ Ø ÑÝ Ú ÛÖ Ø ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÓÒ×Ø Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ×µ ß ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÑÝ Ú ÛÖ Ø ´µ Ò µ Ö ØÙÖÒ ÓÙÒØ ×× Þ Ø ÑÝ Ú Ö ´×ØÖÙ Ø Ð ¶ ÐÔ¸ Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ× 37
  39. 39. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÔÖ ÒØ ´Ã ÊÆ Ä ÊÌ ÑÝ Ú Ö ´µ Ò µ Ö ØÙÖÒ ÓÙÒØ ÑÓ ÙÐ Ò Ø´ÑÝ Ú Ò Øµ ÑÓ ÙÐ Ü Ø´ÑÝ Ú Ü Øµ »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Pronto, agora o compilador não reclama mais. Nem o insmod. O problema é que nosso driver ainda não faz absolutamente nada. Se você tentar ler ou escrever nele, provavelmente o programa que você utilizar vai retornar algum erro do tipo quot;endereço de dispositivo inválidoquot;. Ainda está faltando uma peça importante. Siga lendo e você vai descobrir o que é. 6.2 Filp Durante o curso, vamos chamar de filp um ponteiro para a struct file, só para facilitar a refe- rência (e o nome filp também é comumente utilizado pelos programadores de kernel). Vamos dar uma olhada no que é de mais pertinente para nós. unsigned int f_flags: Indica flags do arquivo: se ele está aberto para leitura/escrita ou se o arquivo está aberto de forma síncrona. Essas flags estão definidas em <linux/fcntl.h> mode_t f_mode: Permissões de leitura e escrita do arquivo em questão, identificada pelos bits FMODE_READ e FMODE_WRITE. Uma tentativa de leitura/escrita no arquivo que sem per- missões para tanto são bloqueadas diretamente pelo kernel, sem nem mesmo chegar a informar o seu módulo. loff_t f_pos: Informa a posição da cabeça de leitura no arquivo. Essa posição nunca deve ser alterada diretamente. As funções read() e write() implementadas em seu driver devem, na verdade, alterar o ponteiro de offset passado a elas (que, no caso, aponta para o f_pos dentro dessa struct). No caso de você ter passado batido pela file_operations acima, eu vou trazer a função write() pra você dar uma olhada: ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *). Observe que o último parâmetro é um ponteiro do tipo loff_t. A sua função deve alterar esse ponteiro, ao invés de buscar f_pos na estrutura de arquivo. A única função que altera essa informação diretamente é llseek, pois, afinal de contas, esse é o seu propósito. struct file_operations * f_op: A struct que observamos anteriormente. Cada arquivo aberto no kernel deve ter uma f_op associada com as funções disponíveis. Uma coisa interessante é que o endereço filp->f_op não fica guardado em nenhuma variável. Isso significa que sempre que o kernel precisa acessar alguma função daquele arquivo, ele vai buscar em filp->f_op, e isso possibilita algo muito importante: você pode mudar o endereço de f_op no filp para cada minor number em um arquivo. Em outras palavras, isso possibilita um mesmo driver controlar de forma diferente variações do mesmo dispositivo, registrando-o com minor number diferente e carregando uma f_op na memória moldada às necessidades. void * private_data: Ponteiro para um bloco de dados para uso particular do arquivo. É útil como uma região de memória que pode ser utilizada por diversas chamadas de sistema do seu módulo. É de sua escolha utilizá-lo ou não, mas lembre-se de que qualquer região de memó- ria alocada num módulo pertence à memória controlada pelo kernel e deve ser cuidadosamente tratada. Não esqueça de desalocá-la quando terminar de usar ou quando o módulo for descarre- gado. Esses são os pontos mais importantes sobre a struct file para nós. Os outros também são importantes, claro, porém são mais específicos ao arquivo em si e não para nosso driver. 38
  40. 40. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 6.3 Estrutura de Inode 6.3.1 Links e inodes A última struct que vamos dar uma olhada é a de inode. Como você deve(ria?) saber, inode é uma entrada que descreve o arquivo num sistema de arquivos (file system). Você já criou links no Linux, não é? Aulinha de links, com o professor Leonardo: Existem dois tipos de links entre arquivos no linux. São chamados de soft e hard links. Soft links apontam para um nome de um arquivo, e se você muda o nome do arquivo que ele aponta, o link é facilmente quebrado. Já o hard-link é um compromisso com a entrada no sistema de arquivos, e não com o nome do arquivo. Isso quer dizer que se você faz um hard-link com um arquivo, está efetivamente apontando para a posição no disco e não para o nome do arquivo. Qual a vantagem? Você me pergunta. Hard-links criam arquivos linkados independentes do nome. Significa que alterando o conteúdo de um arquivo você altera o do outro, independente do nome deles. Um inode comum pertence à tabela de arquivos do sistema de arquivos, e cada inode contém muitas infomações, além de dizer em que posição o arquivo está no disco. Um link apontando para o inode vai estar lá enquanto o inode existir. Arquivos apontando para inodes que não existem ou inodes sem ninguém apontando para eles são reflexos de inconsistências no sistema de arquivos (como acontece naquelas vezes em que acaba a energia ou quando você desliga o computador na pancada). - Guarde assim: inodes são únicos, nomes de arquivo, não. Da mesma forma que em um sistema de arquivos eu posso ter vários nomes apontando para o mesmo inode, no kernel do linux eu posso ter vários descritores de arquivo apontando para o mesmo inode virtual. Portanto, o inode é uma estrutura muito responsável, pois ela guarda a localização no sistema de arquivos, tamanho e muitas outras coisas sobre o arquivo. 6.3.2 inode A estrutura inode é muito grande e sua totalidade está fora das intenções desse curso, mas existem dois pontos nela que devem ser observados: dev_t i_rnode; para arquivos que são drivers de dispositivo, essa variável representa o seu número (major e minor nubers, lembra?). Vale lembrar que o melhor é não trabalhar com essa va- riável diretamente, pois sua história mostra que sua estrutura é bem diferente em muitas versões de kernel. O melhor é usar duas funções para recuperar o número diretamente do inode: ÙÒ× Ò ÒØ Ñ ÒÓÖ´×ØÖÙ Ø ÒÓ ¶ ÒÓ µ ÙÒ× Ò ÒØ Ñ ÓÖ´×ØÖÙ Ø ÒÓ ¶ ÒÓ µ Agora, vejamos essa union: ÙÒ ÓÒ ß ×ØÖÙ Ø Ô Ô ÒÓ Ò Ó ¶ Ô Ô ×ØÖÙ Ø ÐÓ Ú ¶ Ú ×ØÖÙ Ø Ú ¶ Ú 39
  41. 41. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Bom, cada membro dessa união representa, para a struct inode, o tipo de dispositivo. Se você utiliza o campo i_cdev, está quot;dizendoquot;que aquele inode representa um driver para um dispositivo de carctere. i_bdev para dispositivos de bloco e i_pipe para pipes (pipes são regiões de memória que se comportam como uma fila. São criados com o comando mkfifo, análogo ao mknod. Não abordaremos pipes por enquanto). Vamos continuar usando dispositivos de caractere, pois são mais simples de implementar. Logo veremos suas funções de registro. A estrutura de inode e de file não são de nossa responsabilidade: elas são entregues prontas para nós. Em outras palavras isso significa que não temos tenho que preencher a estrutura file e nem a inode. Isso seria um completo martírio, e escrever driver ia ser uma coisa para pessoas com MUITA paciência. Preencher a fops já é uma luta... imagina essas duas aí. Essas estruturas que são passadas para nós foram criadas pelo próprio kernel quando um programa executa a chamada open(). Precisamos dela para saber que tipo de arquivo está sendo aberto e os modos dele. Bem como a posição da cabeça, entre outras coisas. Vamos tentar tornar o nosso driver funcional agora. A primeira coisa que deve ser feita é pedir ao kernel um pouco de espaço referente a um dispositivo de caractere: struct cdev * dev_alloc(); Essa função aloca espaço e inicializa algumas coisas da estrutura cdev, e retorna um ponteiro para ela. Devemos inicializá-la completamente com void cdev_init(struct cdev *dev, struct file_operations *fops); Agora o kernel sabe quais operações o driver sabe executar em cima do dispositivo, colocando a fops em cdev. Depois de devidamente inicializado, vamos dizer ao kernel que estamos prontos para funcionar. int cdev_add(struct cdev *dev, dev_t num, unsigned int count); Os argumentos são o ponteiro para o dispositivo, o número do dispositivo e a quantidade de dispositivos consecutivos que são controlados por esse driver. Fique muito atento a essa função, pois, uma vez que o kernel foi informado dessa struct e de sua respectiva fops, ele pode começar a utilizá-la imediatamente, estando o seu módulo pronto para isso ou não. Esse comportamento pode levar a falhas catastróficas (como um certo SO popular gosta muito de fazer) do sistema. Portanto, registrar essa cdev deve ser a última coisa que a sua função de inicialização deve fazer. 40
  42. 42. Capítulo 7 Mydev Sabendo todas as estruturas importantes, já é hora de fazer algo mais funcional: Vamos agora criar um dispositivo - mydev.c - que faz algo mais útil. Dê uma olhada: »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Ò ÐÙ Ð ÒÙÜ» Ò Øº Ò ÐÙ Ð ÒÙÜ»ÑÓ ÙÐ º Ò ÐÙ Ð ÒÙÜ»ØÝÔ ×º Ò ÐÙ Ð ÒÙÜ» Ú Øº Ò ÐÙ Ð ÒÙÜ» ׺ Ò ÐÙ Ð ÒÙÜ» Úº ÅÇ ÍÄ ÄÁ ÆË ´ Ù Ð Ë » ÈÄ µ ×Ø Ø ÒØ Ñ ÓÖ ×Ø Ø Ú Ø Ú ÒØ ÓÔ Ò Ú ×ØÖÙ Ø Ú ÑÝ Ú Ú »¶ ÈÖÓØÓØ ÔÓ× × ÙÒ Ó × ÔÖ Ò Ô × ¶» ÒØ ÑÝ Ú ÓÔ Ò´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ÒØ ÑÝ Ú Ö Ð × ´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ×× Þ Ø ÑÝ Ú Ö ´×ØÖÙ Ø Ð ¶ ÐÔ¸ Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ× ×× Þ Ø ÑÝ Ú ÛÖ Ø ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÓÒ×Ø Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ »¶ ÁÒ Ð Þ Ó ÓÔ× ¶» ×ØÖÙ Ø Ð ÓÔ Ö Ø ÓÒ× ÑÝ Ú ÓÔ× ß ºÓÛÒ Ö ÌÀÁË ÅÇ ÍÄ ¸ ºÓÔ Ò ÑÝ Ú ÓÔ Ò¸ ºÖ Ð × ÑÝ Ú Ö Ð × ¸ ºÖ ÑÝ Ú Ö ¸ ºÛÖ Ø ÑÝ Ú ÛÖ Ø ¸ 41
  43. 43. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ×Ø Ø ÒØ ÑÝ Ú Ò Ø´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç ÖÖ Ò Ó ÑÝ Ú Ò µ »¶ Ö ×ØÖ Ó Ö Ú Ö ÓÑ ¿ Ñ ÒÓÖ ÒÙÑ Ö× ¶» ´ ÐÐÓ Ö Ú Ö ÓÒ´² Ú¸ ¼¸ ¿¸ Ö Ú Ö µµ ß ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç ÀÓÙÚ ÙÑ ÔÖÓ Ð Ñ ÐÓ Ò Ó Ó Ö Ú Ö Ò µ Ö ØÙÖÒ ½ »¶ ÐÓ Ö ×ØÖ ×ØÖÙØÙÖ Ú ÒÓ ÖÒ Ð ¶» Ú Ò Ø´²ÑÝ Ú Ú¸ ²ÑÝ Ú ÓÔ×µ ÑÝ Ú ÚºÓÛÒ Ö ÌÀÁË ÅÇ ÍÄ Ú ´²ÑÝ Ú Ú¸ Ú¸ ¿µ Ñ ÓÖ Å ÂÇÊ´ Úµ ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç ÆÓ××Ó Ñ ÓÖ ÒÙÑ Ö ± Ò ¸ Ñ ÓÖµ ÓÔ Ò Ú ¼ Ö ØÙÖÒ ¼ ×Ø Ø ÚÓ ÑÝ Ú Ü Ø´ÚÓ µ ß ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç × ÖÖ Ò Ó Ö Ú Ö Ò µ Ú Ð´²ÑÝ Ú Úµ ÙÒÖ ×Ø Ö Ö Ú Ö ÓÒ´ Ú¸ ¿µ ÓÔ Ò Ú¹¹ ÒØ ÑÝ Ú ÓÔ Ò´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ß ´ÓÔ Ò Úµ ß Ö ØÙÖÒ ¹ ÍË ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç ×ÔÓ× Ø ÚÓ × Ò Ó Ù× Ó Ò µ Ö ØÙÖÒ ¼ ÒØ ÑÝ Ú Ö Ð × ´×ØÖÙ Ø ÒÓ ¶ ÒÓ ¸ ×ØÖÙ Ø Ð ¶ ÐÔµ ß ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç ×ÔÓ× Ø ÚÓ Ð Ö Ó Ò µ Ö ØÙÖÒ ¼ ×× Þ Ø ÑÝ Ú ÛÖ Ø ´×ØÖÙ Ø Ð ¶ ÐÔ¸ ÓÒ×Ø Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç Å Ò× Ñ Ö º Ë Ù Ø Ñ Ò Ó ± Ò ¸ ÓÙÒص Ö ØÙÖÒ ÓÙÒØ ×× Þ Ø ÑÝ Ú Ö ´×ØÖÙ Ø Ð ¶ ÐÔ¸ Ö Ù× Ö ¶ Ù ¸ × Þ Ø ÓÙÒظ ÐÓ Ø ¶ ÔÓ× ÔÖ ÒØ ´Ã ÊÆ ÁÆ Ç Ì ÒØ Ø Ú Ð ØÙÖ ÙÑ Ñ Ò× Ñ Ø Ñ Ò Ó ± Ò ¸ ÓÙÒص Ö ØÙÖÒ ÓÙÒØ 42
  44. 44. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÑÓ ÙÐ Ò Ø´ÑÝ Ú Ò Øµ ÑÓ ÙÐ Ü Ø´ÑÝ Ú Ü Øµ »¶¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ÙØ Ö ¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹ ¶» Puxa vida! Tá aí, um driver legal de se ver. É excelente para estudar como são feitas as chamadas de sistema de cada aplicativo. Nosso driver não faz nada de verdade, só mostra o que está sendo passado a ele. Impressionante, não é? Dava para imaginar, no início do curso, que a gente ia ver algo bacana como isso? Observe as diferenças. O que tem de novo? Bom, registramos a cdev, colocamos a fops e agora exibimos mensagens sobre o que está sendo passado a nós. Compile e carregue na memória. Não esqueça de fazer o arquivo de dispositivo correspondente (com mknod, lembra-se?). Teste-o com o comando echo, dd, cat, etc. Observe como cada um faz um pedido diferente em relação ao tamanho de dados. Excelente. Agora, você pode se perguntar: por que diabos quando eu digito ’cat nome_do_dispositivo’, ele tenta ficar lendo indefinidamente? Não sei se você lembra, mas a função read() retorna um número. Número positivo indica quantos bytes ele leu, e número negativo, um erro qualquer. O 0 (zero) significa fim do arquivo. cat lê até o fim do arquivo, mas nós nunca retornamos 0 em read(). O que acontece com a região de memória que o read() passa para preenchermos? Nada. Fica lá, do jeito que veio, volta. 43

×