Você está na página 1de 50

Drivers de Dispositivos Linux

2 de Setembro de 2008

Contedo
I Sobre essa apostila

II Informaes Bsicas

III GNU Free Documentation License

IV Driver de Dsipositivo Linux

18

1 Driver de Dispositivo Linux

19

2 Plano de ensino
2.1 Objetivo . . .
2.2 Pblico Alvo .
2.3 Pr-requisitos
2.4 Descrio . .
2.5 Cronograma
2.6 Programa . .
2.7 Avaliao . .
2.8 Bibliografia .

.
.
.
.
.
.
.
.

20
20
20
20
20
20
21
21
22

3 Introduo
3.1 Driver de Dispositivo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Tipos de Dispositivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Interface do Driver com o Sistema Operacional . . . . . . . . . . . . . . . . . . . . .

23
23
24
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 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
6.1.2 Fops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1

CDTC

Centro de Difuso de Tecnologia e Conhecimento

6.1.3 Inicializando a fops . . . . . . . . .


6.1.4 Algumas operaes de mentirinha
6.2 Filp . . . . . . . . . . . . . . . . . . . . . .
6.3 Estrutura de Inode . . . . . . . . . . . . .
6.3.1 Links e inodes . . . . . . . . . . .
6.3.2 inode . . . . . . . . . . . . . . . .
7 Mydev

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

Braslia/DF

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

34
35
37
38
38
38
40

8 A memria e o Kernel
43
8.1 Como funciona a memria? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
9 Mydev completo
45
9.1 mydev.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
9.2 Utilizao do mydev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Parte I

Sobre essa apostila

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Contedo
O contedo dessa apostila fruto da compilao de diversos materiais livres publicados na internet, disponveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br.
O formato original deste material bem como sua atualizao est disponvel dentro da licena
GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seo de
mesmo nome, tendo inclusive uma verso traduzida (no oficial).
A reviso e alterao vem sendo realizada pelo CDTC (suporte@cdtc.org.br), desde outubro
de 2006. Criticas e sugestes construtivas so bem-vindas a qualquer tempo.

Autores
A autoria deste contedo, atividades e avaliaes de responsabilidade de Leonardo Guilherme de Freitas (lgfreitas@cdtc.org.br) .
O texto original faz parte do projeto Centro de Difuso 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 pas.
Informaes adicionais podem ser obtidas atrves do email ouvidoria@cdtc.org.br, ou da
home page da entidade, atravs da URL http://www.cdtc.org.br.

Garantias
O material contido nesta apostila isento de garantias e o seu uso de inteira responsabilidade do usurio/leitor. Os autores, bem como o ITI e seus parceiros, no se responsabilizam
direta ou indiretamente por qualquer prejuzo oriundo da utilizao do material aqui contido.

Licena
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 APOSTILA. A copy of the license is included in the section entitled GNU Free Documentation
License.

Parte II

Informaes Bsicas

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Sobre o CDTC
Objetivo Geral
O Projeto CDTC visa a promoo e o desenvolvimento de aes que incentivem a disseminao de solues que utilizem padres abertos e no proprietrios de tecnologia, em proveito do
desenvolvimento social, cultural, poltico, tecnolgico e econmico da sociedade brasileira.
Objetivo Especfico
Auxiliar o Governo Federal na implantao do plano nacional de software no-proprietrio e
de cdigo fonte aberto, identificando e mobilizando grupos de formadores de opinio dentre os
servidores pblicos e agentes polticos da Unio Federal, estimulando e incentivando o mercado
nacional a adotar novos modelos de negcio da tecnologia da informao e de novos negcios
de comunicao com base em software no-proprietrio e de cdigo fonte aberto, oferecendo
treinamento especfico para tcnicos, profissionais de suporte e funcionrios pblicos usurios,
criando grupos de funcionrios pblicos que iro treinar outros funcionrios pblicos e atuar como
incentivadores e defensores de produtos de software no proprietrios e cdigo fonte aberto, oferecendo contedo tcnico on-line para servios de suporte, ferramentas para desenvolvimento de
produtos de software no proprietrios e de seu cdigo fonte livre, articulando redes de terceiros
(dentro e fora do governo) fornecedoras de educao, pesquisa, desenvolvimento e teste de produtos de software livre.

Guia do aluno
Neste guia, voc ter reunidas uma srie de informaes importantes para que voc comece
seu curso. So elas:
Licenas para cpia de material disponvel
Os 10 mandamentos do aluno de Educao a Distncia
Como participar dos fruns e da wikipdia
Primeiros passos
muito importante que voc entre em contato com TODAS estas informaes, seguindo o
roteiro acima.

Licena
Copyright 2006, Leonardo Guilherme de Freitas (lgfreitas@cdtc.org.br) .
6

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

dada permisso para copiar, distribuir e/ou modificar este documento sob os termos
da Licena de Documentao Livre GNU, Verso 1.1 ou qualquer verso posterior
publicada pela Free Software Foundation; com o Captulo Invariante SOBRE ESSA
APOSTILA. Uma cpia da licena est inclusa na seo entitulada "Licena de Documentao Livre GNU".

Os 10 mandamentos do aluno de educao online

1. Acesso a Internet: ter endereo eletrnico, um provedor e um equipamento adequado


pr-requisito para a participao nos cursos a distncia.
2. Habilidade e disposio para operar programas: ter conhecimentos bsicos de Informtica necessrio para poder executar as tarefas.
3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distncia conta muitos pontos, pois ir colaborar para o processo ensino-aprendizagem pessoal,
dos colegas e dos professores.
4. Comportamentos compatveis com a etiqueta: mostrar-se interessado em conhecer seus
colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo.
5. Organizao pessoal: planejar e organizar tudo fundamental para facilitar a sua reviso
e a sua recuperao de materiais.
6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigaes e
realiz-las em tempo real.
7. Curiosidade e abertura para inovaes: aceitar novas idias e inovar sempre.
8. Flexibilidade e adaptao: requisitos necessrio a mudana tecnolgica, aprendizagens
e descobertas.
9. Objetividade em sua comunicao: comunicar-se de forma clara, breve e transparente
ponto-chave na comunicao pela Internet.
10. Responsabilidade: ser responsvel por seu prprio aprendizado. O ambiente virtual no
controla a sua dedicao, mas reflete os resultados do seu esforo e da sua colaborao.

Como participar dos fruns e Wikipdia


Voc tem um problema e precisa de ajuda?
Podemos te ajudar de 2 formas:
A primeira o uso dos fruns de notcias e de dvidas gerais que se distinguem pelo uso:
O frum de notcias tem por objetivo disponibilizar um meio de acesso rpido a informaes
que sejam pertinentes ao curso (avisos, notcias). As mensagens postadas nele so enviadas a
7

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

todos participantes. Assim, se o monitor ou algum outro participante tiver uma informao que
interesse ao grupo, favor post-la aqui.
Porm, se o que voc deseja resolver alguma dvida ou discutir algum tpico especfico do
curso, recomendado que voc faa uso do Frum de dvidas gerais que lhe d recursos mais
efetivos para esta prtica.
. O frum de dvidas gerais tem por objetivo disponibilizar um meio fcil, rpido e interativo
para solucionar suas dvidas e trocar experincias. As mensagens postadas nele so enviadas
a todos participantes do curso. Assim, fica muito mais fcil obter respostas, j que todos podem
ajudar.
Se voc receber uma mensagem com algum tpico que saiba responder, no se preocupe com a
formalizao ou a gramtica. Responda! E no se esquea de que antes de abrir um novo tpico
recomendvel ver se a sua pergunta j foi feita por outro participante.
A segunda forma se d pelas Wikis:
Uma wiki uma pgina web que pode ser editada colaborativamente, ou seja, qualquer participante pode inserir, editar, apagar textos. As verses antigas vo 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 "Wikipdia", uma experincia grandiosa de construo de uma enciclopdia de forma colaborativa, por
pessoas de todas as partes do mundo. Acesse-a em portugus pelos links:
Pgina principal da Wiki - http://pt.wikipedia.org/wiki/
Agradecemos antecipadamente a sua colaborao com a aprendizagem do grupo!

Primeiros Passos
Para uma melhor aprendizagem recomendvel que voc siga os seguintes passos:
Ler o Plano de Ensino e entender a que seu curso se dispe a ensinar;
Ler a Ambientao do Moodle para aprender a navegar neste ambiente e se utilizar das
ferramentas bsicas do mesmo;
Entrar nas lies seguindo a seqncia descrita no Plano de Ensino;
Qualquer dvida, reporte ao Frum de Dvidas Gerais.

Perfil do Tutor
Segue-se uma descrio do tutor ideal, baseada no feedback de alunos e de tutores.
O tutor ideal um modelo de excelncia: consistente, justo e profissional nos respectivos
valores e atitudes, incentiva mas honesto, imparcial, amvel, positivo, respeitador, aceita as
idias dos estudantes, paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar.
8

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

A classificao por um tutor desta natureza proporciona o melhor feedback possvel, crucial, e,
para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem. Este tutor
ou instrutor:
fornece explicaes claras acerca do que ele espera, e do estilo de classificao que ir
utilizar;
gosta que lhe faam perguntas adicionais;
identifica as nossas falhas, mas corrige-as amavelmente, diz um estudante, e explica porque motivo a classificao foi ou no foi atribuda;
tece comentrios completos e construtivos, mas de forma agradvel (em contraste com um
reparo de um estudante: os comentrios deixam-nos com uma sensao de crtica, de
ameaa e de nervosismo)
d uma ajuda complementar para encorajar um estudante em dificuldade;
esclarece pontos que no foram entendidos, ou corretamente aprendidos anteriormente;
ajuda o estudante a alcanar os seus objetivos;
flexvel quando necessrio;
mostra um interesse genuno em motivar os alunos (mesmo os principiantes e, por isso,
talvez numa fase menos interessante para o tutor);
escreve todas as correes de forma legvel e com um nvel de pormenorizao adequado;
acima de tudo, devolve os trabalhos rapidamente;

Parte III

GNU Free Documentation License

10

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

(Traduzido pelo Joo S. O. Bueno atravs do CIPSGA em 2001)


Esta uma traduo no oficial da Licenaa de Documentao Livre GNU em Portugus
Brasileiro. Ela no publicada pela Free Software Foundation, e no se aplica legalmente a distribuio de textos que usem a GFDL - apenas o texto original em Ingls da GNU FDL faz isso.
Entretanto, ns esperamos que esta traduo ajude falantes de portugus a entenderem melhor
a GFDL.
This is an unofficial translation of the GNU General Documentation License into Brazilian Portuguese. It was not published by the Free Software Foundation, and does not legally state the
distribution terms for software that uses the GFDLonly the original English text of the GFDL does
that. However, we hope that this translation will help Portuguese speakers understand the GFDL
better.
Licena de Documentao Livre GNU Verso 1.1, Maro 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 cpias exatas deste documento de licena, mas
no permitido alter-lo.

INTRODUO
O propsito desta Licena deixar um manual, livro-texto ou outro documento escrito "livre"no
sentido de liberdade: assegurar a qualquer um a efetiva liberdade de copi-lo ou redistribui-lo,
com ou sem modificaes, comercialmente ou no. Secundariamente, esta Licena mantm
para o autor e editor uma forma de ter crdito por seu trabalho, sem ser considerado responsvel
pelas modificaes feitas por terceiros.
Esta Licena um tipo de "copyleft"("direitos revertidos"), o que significa que derivaes do
documento precisam ser livres no mesmo sentido. Ela complementa a GNU Licena Pblica Geral (GNU GPL), que um copyleft para software livre.
Ns fizemos esta Licena para que seja usada em manuais de software livre, por que software
livre precisa de documentao livre: um programa livre deve ser acompanhado de manuais que
provenham as mesmas liberdades que o software possui. Mas esta Licena no 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. Ns recomendamos esta Licena principalmente para trabalhos cujo propsito seja de introduo ou referncia.

APLICABILIDADE E DEFINIES
Esta Licena se aplica a qualquer manual ou outro texto que contenha uma nota colocada pelo
detentor dos direitos autorais dizendo que ele pode ser distribudo sob os termos desta Licena.

11

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

O "Documento"abaixo se refere a qualquer manual ou texto. Qualquer pessoa do pblico um


licenciado e referida como "voc".
Uma "Verso Modificada"do Documento se refere a qualquer trabalho contendo o documento
ou uma parte dele, quer copiada exatamente, quer com modificaes e/ou traduzida em outra
lngua.
Uma "Seo Secundria" um apndice ou uma seo inicial do Documento que trata exclusivamente da relao dos editores ou dos autores do Documento com o assunto geral do
Documento (ou assuntos relacionados) e no contm nada que poderia ser includo diretamente
nesse assunto geral (Por exemplo, se o Documento em parte um livro texto de matemtica, a
Seo Secundria pode no explicar nada de matemtica).
Essa relao poderia ser uma questo de ligao histrica com o assunto, ou matrias relacionadas, ou de posies legais, comerciais, filosficas, ticas ou polticas relacionadas ao mesmo.
As "Sees Invariantes"so certas Sees Secundrias cujos ttulos so designados, como
sendo de Sees Invariantes, na nota que diz que o Documento publicado sob esta Licena.
Os "Textos de Capa"so certos trechos curtos de texto que so listados, como Textos de Capa
Frontal ou Textos da Quarta Capa, na nota que diz que o texto publicado sob esta Licena.
Uma cpia "Transparente"do Documento significa uma cpia que pode ser lida automaticamente, representada num formato cuja especificao esteja disponvel ao pblico geral, cujos
contedos possam ser vistos e editados diretamente e sem mecanismos especiais com editores
de texto genricos ou (para imagens compostas de pixels) programas de pintura genricos ou
(para desenhos) por algum editor de desenhos grandemente difundido, e que seja passvel de
servir como entrada a formatadores de texto ou para traduo automtica para uma variedade
de formatos que sirvam de entrada para formatadores de texto. Uma cpia feita em um formato
de arquivo outrossim Transparente cuja constituio tenha sido projetada para atrapalhar ou desencorajar modificaes subsequentes pelos leitores no Transparente. Uma cpia que no
"Transparente" chamada de "Opaca".
Exemplos de formatos que podem ser usados para cpias Transparentes incluem ASCII simples sem marcaes, formato de entrada do Texinfo, formato de entrada do LaTex, SGML ou XML
usando uma DTD disponibilizada publicamente, e HTML simples, compatvel com os padres, e
projetado para ser modificado por pessoas. Formatos opacos incluem PostScript, PDF, formatos
proprietrios que podem ser lidos e editados apenas com processadores de texto proprietrios,
SGML ou XML para os quais a DTD e/ou ferramentas de processamento e edio no estejam
disponveis para o pblico, e HTML gerado automaticamente por alguns editores de texto com
finalidade apenas de sada.
A "Pgina do Ttulo"significa, para um livro impresso, a pgina do ttulo propriamente dita,
mais quaisquer pginas subsequentes quantas forem necessrias para conter, de forma legvel,
o material que esta Licena requer que aparea na pgina do ttulo. Para trabalhos que no
tenham uma pgina do ttulo, "Pgina do Ttulo"significa o texto prximo da apario mais proeminente do ttulo do trabalho, precedendo o incio do corpo do texto.

12

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

FAZENDO CPIAS EXATAS


Voc pode copiar e distribuir o Documento em qualquer meio, de forma comercial ou no
comercial, desde que esta Licena, as notas de copyright, e a nota de licena dizendo que esta
Licena se aplica ao documento estejam reproduzidas em todas as cpias, e que voc no acrescente nenhuma outra condio, quaisquer que sejam, s desta Licena.
Voc no pode usar medidas tcnicas para obstruir ou controlar a leitura ou confeco de
cpias subsequentes das cpias que voc fizer ou distribuir. Entretanto, voc pode aceitar compensao em troca de cpias. Se voc distribuir uma quantidade grande o suficiente de cpias,
voc tambm precisa respeitar as condies da seo 3.
Voc tambm pode emprestar cpias, sob as mesmas condies colocadas acima, e tambm
pode exibir cpias publicamente.

FAZENDO CPIAS EM QUANTIDADE


Se voc publicar cpias do Documento em nmero maior que 100, e a nota de licena do
Documento obrigar Textos de Capa, voc precisar incluir as cpias 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 trs. Ambas as capas tambm precisam identificar clara e
legivelmente voc como o editor dessas cpias. A capa da frente precisa apresentar o titulo completo com todas as palavras do ttulo igualmente proeminentes e visveis. Voc pode adicionar
outros materiais s capas. Fazer cpias com modificaes limitadas s capas, tanto quanto estas
preservem o ttulo do documento e satisfaam a essas condies, pode ser tratado como cpia
exata em outros aspectos.
Se os textos requeridos em qualquer das capas for muito volumoso para caber de forma
legvel, voc deve colocar os primeiros (tantos quantos couberem de forma razovel) na capa
verdadeira, e continuar os outros nas pginas adjacentes.
Se voc publicar ou distribuir cpias Opacas do Documento em nmero maior que 100, voc
precisa ou incluir uma cpia Transparente que possa ser lida automaticamente com cada cpia
Opaca, ou informar, em ou com, cada cpia Opaca a localizao de uma cpia Transparente
completa do Documento acessvel publicamente em uma rede de computadores, a qual o pblico
usurio de redes tenha acesso a download gratuito e annimo utilizando padres pblicos de
protocolos de rede. Se voc utilizar o segundo mtodo, voc precisar tomar cuidados razoavelmente prudentes, quando iniciar a distribuio de cpias Opacas em quantidade, para assegurar
que esta cpia Transparente vai permanecer acessvel desta forma na localizao especificada
por pelo menos um ano depois da ltima vez em que voc distribuir uma cpia Opaca (diretamente ou atravs de seus agentes ou distribuidores) daquela edio para o pblico.
pedido, mas no obrigatrio, que voc contate os autores do Documento bem antes de
redistribuir qualquer grande nmero de cpias, para lhes dar uma oportunidade de prover voc
com uma verso atualizada do Documento.

13

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

MODIFICAES
Voc pode copiar e distribuir uma Verso Modificada do Documento sob as condies das sees 2 e 3 acima, desde que voc publique a Verso Modificada estritamente sob esta Licena,
com a Verso Modificada tomando o papel do Documento, de forma a licenciar a distribuio
e modificao da Verso Modificada para quem quer que possua uma cpia da mesma. Alm
disso, voc precisa fazer o seguinte na verso modificada:
A. Usar na Pgina de Ttulo (e nas capas, se houver alguma) um ttulo distinto daquele do Documento, e daqueles de verses anteriores (que deveriam, se houvesse algum, estarem listados
na seo "Histrico do Documento"). Voc pode usar o mesmo ttulo de uma verso anterior se
o editor original daquela verso lhe der permisso;
B. Listar na Pgina de Ttulo, como autores, uma ou mais das pessoas ou entidades responsveis pela autoria das modificaes na Verso 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 Pgina de Ttulo o nome do editor da Verso Modificada, como o editor;
D. Preservar todas as notas de copyright do Documento;
E. Adicionar uma nota de copyright apropriada para suas prprias modificaes adjacente s
outras notas de copyright;
F. Incluir, imediatamente depois das notas de copyright, uma nota de licena dando ao pblico
o direito de usar a Verso Modificada sob os termos desta Licena, na forma mostrada no tpico
abaixo;
G. Preservar nessa nota de licena as listas completas das Sees Invariantes e os Textos de
Capa requeridos dados na nota de licena do Documento;
H. Incluir uma cpia inalterada desta Licena;
I. Preservar a seo entitulada "Histrico", e seu ttulo, e adicionar mesma um item dizendo
pelo menos o ttulo, ano, novos autores e editor da Verso Modificada como dados na Pgina de
Ttulo. Se no houver uma sesso denominada "Histrico"no Documento, criar uma dizendo o
ttulo, ano, autores, e editor do Documento como dados em sua Pgina de Ttulo, ento adicionar
um item descrevendo a Verso Modificada, tal como descrito na sentena anterior;
J. Preservar o endereo de rede, se algum, dado no Documento para acesso pblico a uma
cpia Transparente do Documento, e da mesma forma, as localizaes de rede dadas no Documento para as verses anteriores em que ele foi baseado. Elas podem ser colocadas na seo
"Histrico". Voc pode omitir uma localizao na rede para um trabalho que tenha sido publicado
pelo menos quatro anos antes do Documento, ou se o editor original da verso a que ela se refira
der sua permisso;
K. Em qualquer seo entitulada "Agradecimentos"ou "Dedicatrias", preservar o ttulo da
14

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

seo e preservar a seo em toda substncia e fim de cada um dos agradecimentos de contribuidores e/ou dedicatrias dados;
L. Preservar todas as Sees Invariantes do Documento, inalteradas em seus textos ou em
seus ttulos. Nmeros de seo ou equivalentes no so considerados parte dos ttulos da seo;
M. Apagar qualquer seo entitulada "Endossos". Tal sesso no pode ser includa na Verso
Modificada;
N. No reentitular qualquer seo existente com o ttulo "Endossos"ou com qualquer outro
ttulo dado a uma Seo Invariante.
Se a Verso Modificada incluir novas sees iniciais ou apndices que se qualifiquem como
Sees Secundrias e no contenham nenhum material copiado do Documento, voc pode optar
por designar alguma ou todas aquelas sees como invariantes. Para fazer isso, adicione seus
ttulos lista de Sees Invariantes na nota de licena da Verso Modificada. Esses ttulos precisam ser diferentes de qualquer outro ttulo de seo.
Voc pode adicionar uma seo entitulada "Endossos", desde que ela no contenha qualquer coisa alm de endossos da sua Verso Modificada por vrias pessoas ou entidades - por
exemplo, declaraes de revisores ou de que o texto foi aprovado por uma organizao como a
definio oficial de um padro.
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 Verso 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 no pode
adicionar um outro; mas voc pode trocar o antigo, com permisso explcita do editor anterior que
adicionou a passagem antiga.
O(s) autor(es) e editor(es) do Documento no do permisso por esta Licena para que seus
nomes sejam usados para publicidade ou para assegurar ou implicar endossamento de qualquer
Verso Modificada.

COMBINANDO DOCUMENTOS
Voc pode combinar o Documento com outros documentos publicados sob esta Licena, sob
os termos definidos na seo 4 acima para verses modificadas, desde que voc inclua na combinao todas as Sees Invariantes de todos os documentos originais, sem modificaes, e liste
todas elas como Sees Invariantes de seu trabalho combinado em sua nota de licena.
O trabalho combinado precisa conter apenas uma cpia desta Licena, e Sees Invariantes
Idnticas com multiplas ocorrncias podem ser substitudas por apenas uma cpia. Se houver
mltiplas Sees Invariantes com o mesmo nome mas com contedos distintos, faa o ttulo de
15

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

cada seo nico adicionando ao final do mesmo, em parnteses, o nome do autor ou editor
origianl daquela seo, se for conhecido, ou um nmero que seja nico. Faa o mesmo ajuste
nos ttulos de seo na lista de Sees Invariantes nota de licena do trabalho combinado.
Na combinao, voc precisa combinar quaisquer sees entituladas "Histrico"dos diversos documentos originais, formando uma seo entitulada "Histrico"; da mesma forma combine
quaisquer sees entituladas "Agradecimentos", ou "Dedicatrias". Voc precisa apagar todas as
sees entituladas como "Endosso".

COLETNEAS DE DOCUMENTOS
Voc pode fazer uma coletnea consitindo do Documento e outros documentos publicados
sob esta Licena, e substituir as cpias individuais desta Licena nos vrios documentos com
uma nica cpia incluida na coletnea, desde que voc siga as regras desta Licena para cpia
exata de cada um dos Documentos em todos os outros aspectos.
Voc pode extrair um nico documento de tal coletnea, e distribu-lo individualmente sob
esta Licena, desde que voc insira uma cpia desta Licena no documento extrado, e siga esta
Licena em todos os outros aspectos relacionados cpia exata daquele documento.

AGREGAO COM TRABALHOS INDEPENDENTES


Uma compilao do Documento ou derivados dele com outros trabalhos ou documentos separados e independentes, em um volume ou mdia de distribuio, no conta como uma Verso Modificada do Documento, desde que nenhum copyright de compilao seja reclamado pela
compilao. Tal compilao chamada um "agregado", e esta Licena no se aplica aos outros
trabalhos auto-contidos compilados junto com o Documento, s por conta de terem sido assim
compilados, e eles no so trabalhos derivados do Documento.
Se o requerido para o Texto de Capa na seo 3 for aplicvel a essas cpias do Documento,
ento, 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.
Seno eles precisaro aparecer nas capas de todo o agregado.

TRADUO
Traduo considerada como um tipo de modificao, ento voc pode distribuir tradues
do Documento sob os termos da seo 4. A substituio de Sees Invariantes por tradues
requer uma permisso especial dos detentores do copyright das mesmas, mas voc pode incluir
tradues de algumas ou de todas as Sees Invariantes em adio s verses orignais dessas
Sees Invariantes. Voc pode incluir uma traduo desta Licena desde que voc tambm inclua a verso original em Ingls desta Licena. No caso de discordncia entre a traduo e a

16

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

verso original em Ingls desta Licena, a verso original em Ingls prevalecer.

TRMINO
Voc no pode copiar, modificar, sublicenciar, ou distribuir o Documento exceto como expressamente especificado sob esta Licena. Qualquer outra tentativa de copiar, modificar, sublicenciar, ou distribuir o Documento nula, e resultar automaticamente no trmino de seus direitos
sob esta Licena. Entretanto, terceiros que tenham recebido cpias, ou direitos de voc sob esta
Licena no tero suas licenas terminadas, tanto quanto esses terceiros permaneam em total
acordo com esta Licena.

REVISES FUTURAS DESTA LICENA


A Free Software Foundation pode publicar novas verses revisadas da Licena de Documentao Livre GNU de tempos em tempos. Tais novas verses sero similares em espirito verso
presente, mas podem diferir em detalhes ao abordarem novos porblemas e preocupaes. Veja
http://www.gnu.org/copyleft/.
A cada verso da Licena dado um nmero de verso distinto. Se o Documento especificar
que uma verso particular desta Licena "ou qualquer verso posterior"se aplica ao mesmo, voc
tem a opo de seguir os termos e condies daquela verso especfica, ou de qualquer verso
posterior que tenha sido publicada (no como rascunho) pela Free Software Foundation. Se o
Documento no especificar um nmero de Verso desta Licena, voc pode escolher qualquer
verso j publicada (no como rascunho) pela Free Software Foundation.
ADENDO: Como usar esta Licena para seus documentos
Para usar esta Licena num documento que voc escreveu, inclua uma cpia desta Licena
no documento e ponha as seguintes notas de copyright e licenas logo aps a pgina de ttulo:
Copyright (c) ANO SEU NOME.
dada permisso para copiar, distribuir e/ou modificar este documento sob os termos da Licena
de Documentao Livre GNU, Verso 1.1 ou qualquer verso posterior publicada pela Free Software Foundation; com as Sees Invariantes sendo LISTE SEUS TTULOS, com os Textos da
Capa da Frente sendo LISTE, e com os Textos da Quarta-Capa sendo LISTE. Uma cpia da licena est inclusa na seo entitulada "Licena de Documentao Livre GNU".
Se voc no tiver nenhuma Seo Invariante, escreva "sem Sees Invariantes"ao invs de
dizer quais so invariantes. Se voc no tiver Textos de Capa da Frente, escreva "sem Textos de
Capa da Frente"ao invs de "com os Textos de Capa da Frente sendo LISTE"; o mesmo para os
Textos da Quarta Capa.
Se o seu documento contiver exemplos no triviais de cdigo de programas, ns recomendamos a publicao desses exemplos em paralelo sob a sua escolha de licena de software livre,

17

CDTC

Centro de Difuso de Tecnologia e Conhecimento

tal como a GNU General Public License, para permitir o seu uso em software livre.

18

Braslia/DF

Parte IV

Driver de Dsipositivo Linux

19

Captulo 1

Driver de Dispositivo Linux

Drivers de dispositivo so a interface necessria entre o sistema operacional e o hardware do seu


computador. Drivers so responsveis por controlar de forma correta os dispositivos e esconder
do prprio sistema operacional os detalhes de baixo nvel.

20

Captulo 2

Plano de ensino
2.1

Objetivo

Capacitar o usurio para o desenvolviemento de drivers de dispositivo para o Kernel 2.6.x do


SO GNU/Linux.

2.2

Pblico Alvo

Tcnicos e Programadores com experincia em programao usando C que desejam um


caminho para criar os prprios drivers de dispositivo.

2.3

Pr-requisitos

necessrio slido conhecimento em lgica de programao e familiaridade com a linguagem


C, alm de domnio do SO GNU/Linux.

2.4

Descrio

O curso de Driver de Dispositivo Linux ser realizado na modalidade EAD e utilizar a plataforma Moodle como ferramenta de aprendizagem. O material didtico estar disponvel on-line
de acordo com as datas pr-estabelecidas no calendrio. A verso utilizada para o Kernel do
Linux ser a 2.6.18; O curso est dividido da seguinte maneira:

2.5

Cronograma

Introduo;
Interface SO<->driver.
Cdigo de exemplo.
Estruturas do dispositivo.
Aprimorao do driver exemplo
21

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Alocao e manipulao de memria


Finalizao do driver exemplo
As lies contm o contudo principal. Elas podero ser acessadas quantas vezes forem necessrias, desde que esteja dentro da semana programada. Ao final de uma lio, voc receber
uma nota de acordo com o seu desempenho. Responda com ateno s perguntas de cada lio,
pois elas sero consideradas na sua nota final. Caso sua nota numa determinada lio for menor
do que 6.0, sugerimos que voc faa novamente esta lio.
Ao final do curso ser disponibilizada a avaliao referente ao curso. Tanto as notas das lies
quanto a da avaliao sero consideradas para a nota final. Todos os mdulos ficaro visveis
para que possam ser consultados durante a avaliao final.
Aconselhamos a leitura da "Ambientao do Moodle"para que voc conhea a plataforma de
Ensino a Distncia, evitando dificuldades advindas do "desconhecimento"sobre a mesma.
Os instrutores estaro a sua disposio ao longo de todo curso. Qualquer dvida dever ser
enviada no frum. Diariamente os monitores daro respostas e esclarecimentos.

2.6

Programa

O curso de Driver de Dispositivo Linux oferecer o seguinte contedo:


Estudo das estruturas do kernel
Estudo das reas de memria
Estudo da criao de arquivos de dispositivo
Programao em C dos drivers de exemplo

2.7

Avaliao

Toda a avaliao ser feita on-line.


Aspectos a serem considerados na avaliao:
Iniciativa e autonomia no processo de aprendizagem e de produo de conhecimento;
Capacidade de pesquisa e abordagem criativa na soluo dos problemas apresentados.
Instrumentos de avaliao:
Participao ativa nas atividades programadas.
Avaliao ao final do curso.
O participante far vrias avaliaes referente ao contedo do curso. Para a aprovao e
obteno do certificado o participante dever obter nota final maior ou igual a 6.0 de acordo
com a frmula abaixo:
Nota Final = ((ML x 7) + (AF x 3)) / 10 = Mdia aritmtica das lies
AF = Avaliaes
22

CDTC

2.8

Centro de Difuso de Tecnologia e Conhecimento

Bibliografia

The Linux Kernel: http://www.kernel.org


LinuxDevCenter: http://www.linuxdevcenter.com

23

Braslia/DF

Captulo 3

Introduo
O que so drivers de dispositivo e como eles funcionam? Quais os tipos de driver de dispositivo? Como funciona a interao 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 impressora e, pior ainda, teria que saber exatamente como o controlador fsico dessa impressora
funciona. Isso provavelmente ficaria ainda pior: todo programa que fosse imprimir funcionaria somente para uma impressora ou teria que saber como funcionam todas as impressoras do mundo,
alm de saber como identific-las. Certamente, isso invivel.
Device drivers fornecem um nvel de abstrao para o desenvolvimento de programas que
necessitam acesso a um dispositivo fsico. Isso quer dizer que, ao invs de embutir em todos
os programas o cdigo para controlar a impressora X, simplesmente chamo uma funo (por
exemplo, print()) em meu programa e o sistema operacional se encarrega de procurar nos drivers
carregados o cdigo correspondente, e delega a essa poro de cdigo a responsabilidade pelo
controle da impressora. Se amanh eu decidir que preciso de uma impressora Y e no mais da
X, basta instalar os drivers da impressora Y e nada mais precisar de alterao.
Assim funciona com basicamente tudo: discos, mouses, teclados, placas de vdeo, etc. Geralmente voc precisa identific-los somente uma vez, e o sistema operacional se encarrega de
encontrar os drivers corretos e esse sim responsvel pelo controle adequado do hardware.
Na maioria dos sistemas operacionais, os device drivers mais importantes (tambm os mais
genricos) e utilizados em grande escala pelo computador geralmente esto compilados dentro
do kernel (ncleo do sistema), e os utilizados com menos freqncia ou que no exigem demanda
muito grande so carregados como mdulos. Tambm so mdulos os drivers que no esto
disponveis inicialmente pelo sistema operacional - drivers disponibilizados por terceiros ou os
que voc criar.
Drivers devem ser programados e tratados cuidadosamente: um cdigo destinado a ser driver
de dispositivo funcionar com permisso 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
caracterstica de ser cdigo aberto, possui a transparncia necessria para o processo de criao
de device drivers.

24

CDTC

3.2

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Tipos de Dispositivos

Basicamente os dispositivos de hardware so 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 caractersticas diferentes e no sero abordados por enquanto). A diferena entre eles que o acesso aos dados de um dispositivo de caractere
seqencial, enquanto nos dispositivos de bloco o acesso geralmente aleatrio.
Isso , um dispositivo de caractere to rpido quanto possvel para escrever e ler dados
do seu hardware e portanto no precisa de um buffer (o dispositivo em si no trabalha com um
buffer). Uma outra caracterstica de um dispositivo seqencial que no possvel retroceder a
posio dos dados (na verdade, no faz o menor sentido). So dispositivos de streamming. Um
bom exemplo de um dispositivo de caractere o teclado: no faz sentido, via hardware, "ler a tecla
que foi digitada 10 teclas atrs", mas no entanto cada tecla pressionada imediatamente enviada
ao sistema operacional. Dispositivos de caracteres tambm tm esse nome pois geralmente o
acesso feito "um caractere (1 byte)"por vez.
J num dispositivo de bloco, por sua caracterstica de acesso aleatrio, imprescindvel o uso
de um buffer. Na verdade, enquanto um programa utiliza um dispositivo de bloco, ele pode at
ter a impresso que est lendo e escrevendo diretamente no dispositivo (como faria normalmente
em um dispositivo de caractere), mas, na verdade, est realizando tais operaes no buffer do
dispositivo e esse, por sua vez, se encarrega de fazer a mudana fisicamente, na hora certa.
Analisando o seu disco rgido fcil chegar a concluso de que ele um dispositivo de bloco,
pois voc pode acessar dados que esto em partes diferentes do disco. Se o acesso ao disco
fosse seqencial, essa operao seria simplesmente impossvel. Uma outra razo 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 usurios do Linux/Unix, no faz diferena se o dispositivo de
bloco ou de caractere: possvel ler e escrever nesse dispositivo como se ele fosse um arquivo
qualquer. A distino 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 utilizando a simples funo print(), um device driver deve possibilitar o sistema operacional controlar
essa mesma impressora utilizando uma funo como control_printer(), independente da impressora. Isso quer dizer que o SO no se importa se voc vai usar uma impressora da marca X ou
Y, ele simplesmente vai chamar a funo control_printer(), e o seu device driver deve responder a
essa chamada de funo da mesma forma que o sistema operacional responde funo print() do
programa. Em outros termos, enquanto o device driver a implementao virtual da impressora,
a funo control_printer() a sua interface com o sistema operacional. Para dar mais um realce
idia de interface e implementao: se hoje voc utiliza discos SCSI e amanh decidir utilizar
discos IDE, a nica mudana o driver que ser carregado. O Sistema operacional continuar
chamando as mesmas funes de acesso ao disco.
Sendo um pouco mais exato, cada device driver deve implementar uma struct cujos seus
elementos so os ponteiros para as funes de controle, e o kernel, quando carrega esse driver,
registra essa struct na memria. Assim que o driver efetivamente carregado, o kernel chama a
funo de inicializao. O trabalho da funo de inicializao consiste em registrar o dispositivo

25

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

na tabela de dispositivos e dar a ele a identificao necessria, alm de inicializar outras structs
que o driver vai utilizar. Na utilizao do dispositivo, o kernel chama as funes de controle,
leitura e escrita disponibilizadas. Quando o driver descarregado, o kernel chama a funo de
finalizao, responsvel por desregistrar o dispositivo no sistema e limpar da memria. Vamos
ver tudo isso com mais detalhes, pode ficar tranqilo :)

26

Captulo 4

Hello Kernel!
Um Driver simples e que no faz nada!

4.1

Kello Hernell!

Para exemplificar a interface do sistema operacional com o driver, vamos criar um "Hello Kernel". O driver no faz nada de muito importante, s exibe uma mensagem quando carregado e
outra quando descarregado.

/*----------------------- ut here ---------------------------- */


#in lude <linux/init.h>
#in lude <linux/module.h>
MODULE\_LICENSE("Dual BSD/GPL") /* Evita re lama oes de kernel */
stati int hellok(void) {
printk(KERN\_ALERT "Kello, Hernel! :\n");
/* Coisas que fazem os drivers de dispositivos */
return 0;
}
stati void byek(void) {
printk(KERN\_ALERT "Bye, Kernel! :[\n");
}
module\_init(hellok);
module\_exit(byek);
/*----------------------- ut here ---------------------------- */

4.2

Como funciona?

Dissecando o nosso mdulo (que no tem muito o que ser dissecado, na verdade), encontramos algumas coisas parecidas com programas normais, outras, nem tanto. A primeira coisa a ser
notada so os arquivos de include: nada de stdio.h nem string.h. Entretanto, temos <linux/init.h>
e <linux/module.h>. Esses dois cabealhos devem aparecer em todos os mdulos carregveis.
<linux/module.h> tem muitas definies importantes e smbolos utilizados em mdulos e init.h
27

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

disponibiliza module_init e module_exit, alm de outras coisas. Drivers geralmente utilizam muito
mais includes, mas esses voc vai encontrar em qualquer um deles.
Voc provavelmente deve ter percebido que no temos uma funo main(). Ao invs dela
existem as chamadas macros module_init e module_exit, que recebe como parmetros, respectivamente, as funes de inicializao e de sada do mdulo. Quando o driver for carregado,
ele chama a funo registrada por module_init e quando descarregar, a funo registrada em
module_exit.
Para imprimir na tela, temos uma funo que engana. Parece muito a velha conhecida printf.
No entanto, printk uma funo controlada unicamente pelo kernel, pois esse no pode depender de funes disponibilizadas por bibliotecas que podem no estar presentes no futuro (se
utilizssemos printf, nosso mdulo dependeria da presena da libc, que muito provavelmente no
estar disponvel). Outras caractersticas que diferem printk de printf (alm de trocar f por k): o
argumento de urgncia (KERN_ALERT, que definida como <1>. Quanto maior o nmero 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 no suporta nmeros de ponto flutuante
(float).
A diferena mais importante de um mdulo para um programa comum que mdulos so
orientados ao evento. Em outras palavras, enquanto o seu programa favorito abre, executa o que
tem que executar e depois sai, um mdulo carregado no kernel informando o que sabe fazer e
com quem. Depois disso no faz mais nada. Fica l, parado, junto com um monte de mdulos,
esperando ordens que podem aparecer ou no.
Para compilar esse mdulo necessrio um pouco mais de trabalho. Primeiramente, para
kernels da verso 2.6.x, voc vai precisar dos fontes do kernel instalados e compilados. Em
verses 2.4.x, apenas os headers do kernel eram necessrios.
Vai ser necessrio criar um makefile um pouco diferente dos padres para que a compilao
funcione. O kernel tem seu prprio jeitinho de utilizar makefiles, chamado kbuild.
Por hora, nosso Makefile vai se parecer com isso

# ----------------------- ut here ---------------------------obj-m := hellokernel.o


# ----------------------- ut here ---------------------------Esse makefile deve estar no mesmo diretrio do cdigo do seu mdulo. 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 mdulo) No final, voc
vai ter um arquivo do formato hellokernel.ko.
Carregue o mdulo 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 programamos.

28

Captulo 5

Arquivos de Dispositivo
Acesso aos dispositivos via os arquivos do /dev. Arquivos de dispositivos? Como assim?

5.1

Tudo um arquivo!

"No Linux, tudo um arquivo". Essa a mxima da maioria dos usurios do Linux. Enquanto
outros sistemas operacionais mais populares representam dispositivos de armazenamento por
letras e "escondem"a localizao dos outros dispositivos (e como eles so controlados), no sistema operacional do pingim todos os dispositivos tem uma correspondncia no diretrio /dev
(com exceo das interfaces de rede), onde so, de fato, arquivos. Sendo assim, voc pode
testar o comando _ echo "Oi dispositivo! /dev/tty1 _ e dependendo de onde voc utilizar esse
comando, aparecer na sua tela a mensagem "Oi dispositivo!"(/dev/tty* so dispositivos de terminais). Quem prov esse tipo de praticidade em parte o sistema operacional e em parte o seu
driver de dispositivo. Quando voc chama o comando "echo"com redirecionamento de sada (>)
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: "como o sistema operacional vai descobrir qual driver controla
aquele dispositivo?". 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
representao (em forma de arquivo) para os dispositivos.
Analisemos o comando com um exemplo: # mknod /dev/meudispositivo 60 0
O primeiro parmetro obviamente o nome do arquivo que representar o dispositivo. O
parmetro c diz que est sendo criado um dispositivo de caractere. O que nos interessa agora
so os dois nmeros subseqentes, 60 e 0. O 60 seria o "major number"e 0 o "minor number".
Major/minor numbers so utilizados como a identidade virtual do hardware. Junto com o tipo de
dispositivo (no nosso caso, um dispositivo de caractere indicado com o parmetro c) e com esses
nmeros, o sistema operacional capaz de identificar qual driver est controlando o dispositivo
e faz a ligao entre eles dois. Vrios dispositivos podem utilizar o mesmo major number (indicando assim que so 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 variao
que aquele hardware possui, para que esse possa adequar-se. Eu sei que vou acabar repetindo
isso em algum ponto do curso. Se voc no entendeu muito bem, continue lendo. Lembre-se
que os nmeros de dispositivo indicam apenas qual driver est controlando aquele hardware, e
no o seu tipo. Isso significa que um mesmo driver pode controlar todos os tipos de dispositivos
29

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

do mundo: vai saber diferenci-los pelo minor number. Obviamente que isso uma ttica sem
sentido (para no dizer burra). O mdulo seria um bloco gigantesco de cdigo 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 memria deve passar o major number do dispositivo e quantos minor numbers ele pretende controlar, e o kernel registrar na sua tabela de
dispositivos aquele driver. Dessa forma, o SO "casa"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 introduo linguagem no abordaremos todos
os comandos.

5.2

Major e Minor Numbers

A representao 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 espao de 32 bits onde 12 bits
so reservados para major numbers e os 20 bits restantes so reservados para minor numbers.
As macros/funes que trabalham com o tipo dev_t esto no cabealho linux/kdev_t.h. As mais
importantes para o esse momento no curso so MAJOR, MINOR e MKDEV.
MAJOR e MINOR retornam major e minor numbers, respectivamente, de uma dada varivel
do tipo dev_t. MKDEV faz o contrrio. Sabendo o major e o minor number, ele constri 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 funes prototipadas em linux/fs.h. A primeira
usar a funo 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 nmero de dispositivo (que pode ter sido criado com MKDEV, por exemplo).
Geralmente, mas no 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. No confunda isso com o nome em /dev. Quem
controla isso o comando mknod. A funo retorna 0 se tudo correr bem, e qualquer outro
nmero se houver algum erro. A desvantagem dessa funo que o controle sobre os nmeros
precrio: voc pode pedir nmeros j alocados. Para contornar essa situao, existe uma
funo de alocao dinmica de nmeros de dispositivos. A funo tem esse prottipo:
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 alocao dos
nmeros de dispositivo. firstminor o primeiro minor a ser utilizado. Os outros parmetros so
iguais aos de register_chrdev_region. A grande utilidade dessa funo que a probabilidade
de coliso de nmeros pouca, pois retorna o primeiro nmero de dispositivo no utilizado.
No entanto, isso torna mais difcil a utilizao do comando mknod, pois voc deve buscar em
/proc/devices o nmero para utilizar.
Uma dessas funes (register_chrdev_region ou alloc_chrdev_region) deve estar na sua funo de inicializao. Quando o device driver for descarregado, a funo unregister_chrdev_region
deve estar presente na funo de finalizao.
unregister_chrdev_region tem esse prottipo:
void unregister_chrdev_region(dev_t first, unsigned int count);
30

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Os parmetros first e count so os mesmos de register_chrdev_region. Vale lembrar que


essas funes so para drivers de caractere. As funes de driver de bloco tm um jeito muito
parecido.
J d para deixar nosso mdulo um pouquinho mais interessante.
kernumbers.c

/*----------------------- ut here ---------------------------- */


#in lude <linux/init.h>
#in lude <linux/module.h>
#in lude <linux/types.h>
#in lude <linux/kdev\_t.h>
#in lude <linux/fs.h>
MODULE\_LICENSE("Dual BSD/GPL") /* Evita re lama oes de kernel */
/* Variveis globais a esse arquivo. Podemos pre isar delas mais tarde */
stati int major;
stati dev\_t dev;
stati int hellok(void) {
printk(KERN\_ALERT "Kello, Hernel! :\n");
/* Reigstra um driver om 3 minor numbers om o nome "driver" */
if (!allo \_ hrdev\_region(&dev, 0, 3, "driver")) {
printk(KERN\_ALERT "Houve um problema alo ando os nmeros de driver\n");
exit(1);
}
major = MAJOR(dev);
printk(KERN\_ALERT "Nosso major number %d\n", major);
/* Outras oisas que fazem os drivers de dispositivos */
return 0;

}
stati void byek(void) {
printk(KERN\_ALERT "Bye, Kernel! :[\n");
/* Desregistra o nosso driver */
unregister\_ hrdev\_region(&dev, 3);
}
module\_init(hellok);
module\_exit(byek);
/*----------------------- ut here ---------------------------- */
O cdigo auto-explicativo. O Makefile deve ser alterado de acordo com o novo nome do
mdulo. Para verificar se est tudo ok, voc pode dar uma olhada no arquivo /proc/devices e
/proc/modules: # at /pro /modules | grep kernumbers e # at /pro /devi es | grep driver
O primeiro deve mostrar o seu mdulo na lista de mdulos carregados e o segundo mostra o nmero utilizado pelo seu "dispositivo".

31

Captulo 6

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

6.1

File Operations

6.1.1 Introduo
At agora foi a parte fcil da implementao de um driver de dispositivo. Se voc queria saber
apenas como funcionam os mdulos, 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 srio: implementaremos a estrutura de operaes de arquivo. No entanto, o nosso driver
vai fazer todas as operaes num dispositivo de caractere "fictcio".
Como j dito, quando o driver carregado na memria, alm de registrar major e minor numbers, ele deve registrar a estrutura de operaes de arquivo referente ao driver (lembre-se que
mesmo os dispositivos so representados como arquivos no linux e por isso precisam declarar
quais operaes esto disponveis para esse arquivo). A definio dessas estruturas esto em
<linux/fs.h>.
Mesmo que o pargrafo acima no tenha ficado muito claro, tudo fica mais bvio quando
temos um pedao de cdigo para analisar, certo? Enfim chega de bate-papo. Vamos dar uma
boa olhada na estrutura de operaes de arquivo. uma das mais importantes.

6.1.2 Fops
Esta a famosa "fops (file operations)":

stru t file\_operations {
stru t module *owner;
loff\_t (*llseek) (stru t file *, loff\_t, int);
ssize\_t (*read) (stru t file *, har \_\_user *, size\_t, loff\_t *);
ssize\_t (*write) (stru t file *, onst har \_\_user *, size\_t, loff\_t *);
ssize\_t (*aio\_read) (stru t kio b *, onst stru t iove *, unsigned long, loff\_t);
ssize\_t (*aio\_write) (stru t kio b *, onst stru t iove *, unsigned long, loff\_t);
int (*readdir) (stru t file *, void *, filldir\_t);
unsigned int (*poll) (stru t file *, stru t poll\_table\_stru t *);
int (*io tl) (stru t inode *, stru t file *, unsigned int, unsigned long);
long (*unlo ked\_io tl) (stru t file *, unsigned int, unsigned long);
32

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

long (* ompat\_io tl) (stru t file *, unsigned int, unsigned long);


int (*mmap) (stru t file *, stru t vm\_area\_stru t *);
int (*open) (stru t inode *, stru t file *);
int (*flush) (stru t file *, fl\_owner\_t id);
int (*release) (stru t inode *, stru t file *);
int (*fsyn ) (stru t file *, stru t dentry *, int datasyn );
int (*aio\_fsyn ) (stru t kio b *, int datasyn );
int (*fasyn ) (int, stru t file *, int);
int (*lo k) (stru t file *, int, stru t file\_lo k *);
ssize\_t (*sendpage) (stru t file *, stru t page *, int, size\_t, loff\_t *, int);
unsigned long (*get\_unmapped\_area)(stru t file *, unsigned long, unsigned long, \
unsigned long, unsigned long);
int (* he k\_flags)(int);
int (*dir\_notify)(stru t file *filp, unsigned long arg);
int (*flo k) (stru t file *, int, stru t file\_lo k *);
ssize\_t (*spli e\_write)(stru t pipe\_inode\_info *, stru t file *, loff\_t *, size\_t, un
ssize\_t (*spli e\_read)(stru t file *, loff\_t *, stru t pipe\_inode\_info *, size\_t, uns
int (*setlease)(stru t file *, long, stru t file\_lo k **);
};
uma estrutura um tanto quanto densa. A maioria do seu contedo so ponteiros para funes
que voc deve implementar. A estrutura em si apenas a interface. Preencher essa struct
uma das operaes que seu driver deve fazer na inicializao. Para que serve cada uma dessas
funes? Voc pergunta. Bom, algumas do 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 no uma funo. um ponteiro para o mdulo que o "dono"dessa struct. Geralmente, o seu valor THIS_MODULE. (THIS_MODULE
definido em <linux/module.h>).
loff_t (*llseek) (struct file *, loff_t, int): Funo responsvel pela manipulao da cabea de
leitura (offset) do arquivo. Esse offset declarado na estrutura de arquivo, que veremos adiante.
Ela retorna a nova posio no arquivo, se for bem sucedida ou algum nmero negativo caso falhe.
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *): O nome denuncia. usado para
ler informaes do dispositivo. Retorna a quantidade que foi lida com sucesso ou um nmero
negativo caso falhe. Se esse ponteiro for declarado como NULL, o arquivo no 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 nmero negativo caso falhe.
Se esse ponteiro for declarado como NULL, a escrita no arquivo de dispositivo ser impossvel.
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 assncrona, isto , a funo pode retornar antes que a operao
termine. Se forem NULL, todas as operae de leitura e escrita sero feitas de forma sncrona.
int (*readdir) (struct file *, void *, filldir_t): Funo que permite a leitura de diretrios. Para
driver de dispositivo ela no implementada.
unsigned int (*poll) (struct file *, struct poll_table_struct *): Funo que retorna uma mscara informando se possvel ou no utilizar as funes de leitura/escrita sem que elas "bloqueiem"o fluxo do programa (por exemplo, scanf uma funo que interrompe o programa).
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long): Funo utilizada
para mandar comandos especfficos do hardware em questo, que no so nem de leitura nem
33

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

escrita. geralmente so comandos de controle de dispositivo.


long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long) e long (*compat_ioctl)
(struct file *, unsigned int, unsigned long): So alternativas mais recentes ioctl(). ioctl()
utiliza um recurso chamado Big Kernel Lock (BKL). BKLs so utilizadas em sistemas multiprocessados (SMP) para garantir a consistncia do kernel. Existem partes crticas 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 clculo executado por outro processador na mesma
mquina). Assim, antes de se utilizar alguma ioctl() crtica, o kernel deve ser colocado em modo
de espera. unlocked_ioctl() um recurso relativamente recente no kernel (apareceu por volta da
verso 2.6.11 em forma de um patch) que deve implementar dentro de seu prprio cdigo 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 funes no sero abordadas nesse curso,
por serem de uso muito especfico. (Por curiosidade, ioctl() no a nica funo que utiliza BKL.
open(), llseek() e outras tambm utilizam).
int (*mmap) (struct file *, struct vm_area_struct *): mmap() muito importante pois torna
disponvel alguma rea de memria do dispositivo ao processo chamador, sendo possvel controlla.
int (*open) (struct inode *, struct file *): Funo sempre chamada quando um arquivo de
dispositivo (/dev/hda1, por exemplo) aberto. O seu driver no precisa implement-la e a abertura
sempre ir funcionar. No entanto, sem essa chamada no seu driver, impossvel 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 regio da sua memria antes
de efetuar a operao de escrita. flush() certifica-se que essa operao ser executada. Essa
funo chamanda somente antes da aplicao encerrar as operaes com a sua cpia do
descritor do arquivo (file descriptor), e portanto no deve ser confundida com fsync(). Observe
que o programador geralmente no tem controle sobre flush().
int (*release) (struct inode *, struct file *): Chamada quando o arquivo fechado. Assim
como open(), se for NULL, o seu driver no ser avisado dessa operao. Observe que release s
chamado pelo SO quando todos os aplicativos encerram sua utilizao 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 ningum mais utiliza o arquivo, a
sim chamado release().
int (*fsync) (struct file *, struct dentry *, int datasync): Essa operao 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 assncrona. Isso , no
deixa o processo chamador em modo de espera.
int (*fasync) (int, struct file *, int): Utilizado para notificar ao dispositivo alguma mudana na
flag FASYNC. No ser abordado nesse curso.
int (*lock) (struct file *, int, struct file_lock *): Implementa a "trava"de arquivo, isto , se um
processo est "escrevendo"no arquivo, outro processo deve esperar a liberao antes de efetuar
alguma outra operao 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, unsigned 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

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **);
As funes acima sem explicao tratam de tpicos mais avanados, fora do escopo desse
curso, ou so funes de pouco uso em device drivers. Lembre-se que as funes nessa estrutura
no so especficas de drivers de dispositivos, mas pertencem struct file, que descreve qualquer
arquivo carregado na memria e/ou controlado pelo kernel. Mesmo dentre as funes explicadas,
existem algumas que jamais sero implementadas por ns, como aio_fsync ou unlocked_ioctl.

6.1.3 Inicializando a fops


H uma coisa que tem que estar clara em sua cabea, e que talvez ainda no 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 usurio do sistema muito menos. Lembra do "echo Oi! > /dev/tty1"? 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. Ento o shell utiliza write() e assim tambm faz o kernel.
Quando o shell encerra a utilizao do arquivo, ele chama close() e o kernel usa flush() e release().
Portanto, os mdulos devem implementar essas chamadas e inicializ-las na estrutura de file
operations. Vamos desenvolver um pouco mais o nosso driver:
mydev.c

/*----------------------- ut here ---------------------------- */


#in lude <linux/init.h>
#in lude <linux/module.h>
#in lude <linux/types.h>
#in lude <linux/kdev\_t.h>
#in lude <linux/fs.h>
MODULE\_LICENSE("Dual BSD/GPL");
stati int major;
stati dev\_t dev;

/* Prototipos das fun oes prin ipais */


int mydev\_open(stru t inode * inode, stru t file * filp);
int mydev\_release(stru t inode * inode, stru t file * filp);
ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, loff\_t *
stati int mydev\_init(void);
stati void mydev\_exit(void);
/* Ini ializa ao da fops */
stru t file\_operations mydev = {
.owner = THIS\_MODULE,
.open = mydev\_open,
.release = mydev\_release,
.read = mydev\_read,
.write = mydev\_write,
};
stati int mydev\_init(void) {
35

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

printk(KERN\_ALERT "Carregando mydev\n");


/* registra o driver om 3 minor numbers */
if (allo \_ hrdev\_region(&dev, 0, 0, "driver")) {
printk(KERN\_ALERT "Houve um problema alo ando o driver\n");
return 1;
}
major = MAJOR(dev);
printk(KERN\_ALERT "Nosso major number e %d\n", major);
return 0;

}
stati void mydev\_exit(void) {
printk(KERN\_ALERT "Des arregando modulo\n");
unregister\_ hrdev\_region(dev, 0);
}

module\_init(mydev\_init);
module\_exit(mydev\_exit);
/*----------------------- ut here ---------------------------- */
A primeira diferena que o mdulo est com uma carinha mais sria. Uma outra que
prototipamos as nossas funes bsicas. Depois, criamos uma struct file_operations, chamada
mydev, e inicializamos com aquelas funes prototipadas. O resto do cdigo certamente voc j
conhece.
Agora voc me pergunta: " possvel usar esse mdulo s com o prottipo das funes?".
Provavelmente, se est me fazendo essa pergunta, voc no compilou e carregou o mdulo. A
resposta NO. A princpio, possvel compilar com sucesso esse mdulo, mas a compilao
vai dar avisos de smbolos indefinidos. Bom, ignorando isso, tentando um insmod mydev.ko, o
mdulo no carrega, alegando agora smbolos desconhecidos.

6.1.4 Algumas operaes de mentirinha


J que o kernel est reclamando que no conhece alguns smbolos, vamos cri-los. Segue o
cdigo, dessa vez com uma implementao.

/*----------------------- ut here ---------------------------- */


#in lude <linux/init.h>
#in lude <linux/module.h>
#in lude <linux/types.h>
#in lude <linux/kdev\_t.h>
#in lude <linux/fs.h>
MODULE\_LICENSE("Dual BSD/GPL"); /* Sai pra l, kernel hato! */
stati int major;
stati dev\_t dev;
/* Prototipos das fun oes prin ipais */
int mydev\_open(stru t inode * inode, stru t file * filp);
int mydev\_release(stru t inode * inode, stru t file * filp);
36

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, loff\_t *
stati int mydev\_init(void);
stati void mydev\_exit(void);
/* Ini ializa ao da fops */
stru t file\_operations mydev\_fops = {
.owner = THIS\_MODULE,
.open = mydev\_open,
.release = mydev\_release,
.read = mydev\_read,
.write = mydev\_write,
};
stati int mydev\_init(void) {
printk(KERN\_ALERT "Carregando mydev\n");
/* registra o driver om 3 minor numbers */
if (allo \_ hrdev\_region(&dev, 0, 3, "driver")) {
printk(KERN\_ALERT "Houve um problema alo ando o driver\n");
return 1;
}
major = MAJOR(dev);
printk(KERN\_ALERT "Nosso major number e %d\n", major);
return 0;
}
stati void mydev\_exit(void) {
printk(KERN\_ALERT "Des arregando driver\n");
unregister\_ hrdev\_region(dev, 3);
}
int mydev\_open(stru t inode * inode, stru t file * filp) {
printk(KERN\_ALERT "mydev\_open()\n");
return 0;
}
int mydev\_release(stru t inode * inode, stru t file * filp) {
printk(KERN\_ALERT "mydev\_release()\n");
return 0;
}
ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf,
size\_t ount, loff\_t * f\_pos) {
printk(KERN\_ALERT "mydev\_write()\n");
return ount;
}

ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
37

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

printk(KERN\_ALERT "mydev\_read()\n");
return ount;

module\_init(mydev\_init);
module\_exit(mydev\_exit);
/*----------------------- ut here ---------------------------- */
Pronto, agora o compilador no reclama mais. Nem o insmod. O problema que nosso
driver ainda no faz absolutamente nada. Se voc tentar ler ou escrever nele, provavelmente
o programa que voc utilizar vai retornar algum erro do tipo "endereo de dispositivo invlido".
Ainda est faltando uma pea 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 referncia (e o nome filp tambm comumente utilizado pelos programadores de kernel).
Vamos dar uma olhada no que de mais pertinente para ns.
unsigned int f_flags: Indica flags do arquivo: se ele est aberto para leitura/escrita ou se o
arquivo est aberto de forma sncrona. Essas flags esto definidas em <linux/fcntl.h>
mode_t f_mode: Permisses de leitura e escrita do arquivo em questo, identificada pelos
bits FMODE_READ e FMODE_WRITE. Uma tentativa de leitura/escrita no arquivo que sem permisses para tanto so bloqueadas diretamente pelo kernel, sem nem mesmo chegar a informar
o seu mdulo.
loff_t f_pos: Informa a posio da cabea de leitura no arquivo. Essa posio nunca deve
ser alterada diretamente. As funes 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
funo write() pra voc dar uma olhada: ssize_t (*write) (struct file *, const char __user *, size_t,
loff_t *). Observe que o ltimo parmetro um ponteiro do tipo loff_t. A sua funo deve alterar
esse ponteiro, ao invs de buscar f_pos na estrutura de arquivo. A nica funo que altera essa
informao diretamente llseek, pois, afinal de contas, esse o seu propsito.
struct file_operations * f_op: A struct que observamos anteriormente. Cada arquivo aberto
no kernel deve ter uma f_op associada com as funes disponveis. Uma coisa interessante
que o endereo filp->f_op no fica guardado em nenhuma varivel. Isso significa que sempre
que o kernel precisa acessar alguma funo daquele arquivo, ele vai buscar em filp->f_op, e
isso possibilita algo muito importante: voc pode mudar o endereo de f_op no filp para cada
minor number em um arquivo. Em outras palavras, isso possibilita um mesmo driver controlar
de forma diferente variaes do mesmo dispositivo, registrando-o com minor number diferente e
carregando uma f_op na memria moldada s necessidades.
void * private_data: Ponteiro para um bloco de dados para uso particular do arquivo. til
como uma regio de memria que pode ser utilizada por diversas chamadas de sistema do seu
mdulo. de sua escolha utiliz-lo ou no, mas lembre-se de que qualquer regio de memria alocada num mdulo pertence memria controlada pelo kernel e deve ser cuidadosamente
tratada. No esquea de desaloc-la quando terminar de usar ou quando o mdulo for descarregado.
Esses so os pontos mais importantes sobre a struct file para ns. Os outros tambm so
importantes, claro, porm so mais especficos ao arquivo em si e no para nosso driver.
38

CDTC

6.3

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

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, no ?
Aulinha de links, com o professor Leonardo:
Existem dois tipos de links entre arquivos no linux. So 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 no com o nome do arquivo. Isso quer dizer que se voc faz um hard-link com um
arquivo, est efetivamente apontando para a posio no disco e no para o nome do arquivo.
Qual a vantagem? Voc me pergunta. Hard-links criam arquivos linkados independentes do
nome. Significa que alterando o contedo 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 contm
muitas infomaes, alm de dizer em que posio o arquivo est no disco. Um link apontando
para o inode vai estar l enquanto o inode existir. Arquivos apontando para inodes que no
existem ou inodes sem ningum apontando para eles so reflexos de inconsistncias no sistema
de arquivos (como acontece naquelas vezes em que acaba a energia ou quando voc desliga o
computador na pancada).
- Guarde assim: inodes so nicos, nomes de arquivo, no. Da mesma forma que em um
sistema de arquivos eu posso ter vrios nomes apontando para o mesmo inode, no kernel do
linux eu posso ter vrios descritores de arquivo apontando para o mesmo inode virtual. Portanto,
o inode uma estrutura muito responsvel, pois ela guarda a localizao 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 intenes desse curso, mas
existem dois pontos nela que devem ser observados:
dev_t i_rnode; para arquivos que so drivers de dispositivo, essa varivel representa o seu
nmero (major e minor nubers, lembra?). Vale lembrar que o melhor no trabalhar com essa varivel diretamente, pois sua histria mostra que sua estrutura bem diferente em muitas verses
de kernel. O melhor usar duas funes para recuperar o nmero diretamente do inode:

unsigned int iminor(stru t inode *inode);


unsigned int imajor(stru t inode *inode);
Agora, vejamos essa union:

union {
stru t pipe\_inode\_info *i\_pipe;
stru t blo k\_devi e *i\_bdev;
stru t dev *i\_ dev;
};

39

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

Bom, cada membro dessa unio representa, para a struct inode, o tipo de dispositivo. Se voc
utiliza o campo i_cdev, est "dizendo"que aquele inode representa um driver para um dispositivo
de carctere. i_bdev para dispositivos de bloco e i_pipe para pipes (pipes so regies de memria
que se comportam como uma fila. So criados com o comando mkfifo, anlogo ao mknod. No
abordaremos pipes por enquanto). Vamos continuar usando dispositivos de caractere, pois so
mais simples de implementar. Logo veremos suas funes de registro.
A estrutura de inode e de file no so de nossa responsabilidade: elas so entregues prontas
para ns. Em outras palavras isso significa que no temos tenho que preencher a estrutura file
e nem a inode. Isso seria um completo martrio, e escrever driver ia ser uma coisa para pessoas
com MUITA pacincia. Preencher a fops j uma luta... imagina essas duas a. Essas estruturas
que so passadas para ns foram criadas pelo prprio 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 posio da cabea, entre outras coisas.
Vamos tentar tornar o nosso driver funcional agora. A primeira coisa que deve ser feita pedir
ao kernel um pouco de espao referente a um dispositivo de caractere:
struct cdev * dev_alloc();
Essa funo aloca espao 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 operaes 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 so o ponteiro para o dispositivo, o nmero do dispositivo e a quantidade de
dispositivos consecutivos que so controlados por esse driver. Fique muito atento a essa funo,
pois, uma vez que o kernel foi informado dessa struct e de sua respectiva fops, ele pode comear
a utiliz-la imediatamente, estando o seu mdulo pronto para isso ou no. Esse comportamento
pode levar a falhas catastrficas (como um certo SO popular gosta muito de fazer) do sistema.
Portanto, registrar essa cdev deve ser a ltima coisa que a sua funo de inicializao deve fazer.

40

Captulo 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:

/*----------------------- ut here ---------------------------- */


#in lude
#in lude
#in lude
#in lude
#in lude
#in lude

<linux/init.h>
<linux/module.h>
<linux/types.h>
<linux/kdev\_t.h>
<linux/fs.h>
<linux/ dev.h>

MODULE\_LICENSE("Dual BSD/GPL");
stati int major;
stati dev\_t dev;
int open\_dev;
stru t dev mydev\_ dev;

/* Prototipos das fun oes prin ipais */


int mydev\_open(stru t inode * inode, stru t file * filp);
int mydev\_release(stru t inode * inode, stru t file * filp);
ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, loff\_t *
stati int mydev\_init(void);
stati void mydev\_exit(void);
/* Ini ializa ao da fops */
stru t file\_operations mydev\_fops = {
.owner = THIS\_MODULE,
.open = mydev\_open,
.release = mydev\_release,
.read = mydev\_read,
.write = mydev\_write,
};
41

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

stati int mydev\_init(void) {


printk(KERN\_INFO "Carregando mydev\n");
/* registra o driver om 3 minor numbers */
if (allo \_ hrdev\_region(&dev, 0, 3, "driver")) {
printk(KERN\_INFO "Houve um problema alo ando o driver\n");
return 1;
}
/* alo a registra a estrutura dev no kernel */
dev\_init(&mydev\_ dev, &mydev\_fops);
mydev\_ dev.owner = THIS\_MODULE;
dev\_add(&mydev\_ dev, dev, 3);
major = MAJOR(dev);
printk(KERN\_INFO "Nosso major number e %d\n", major);
open\_dev = 0;
return 0;
}
stati void mydev\_exit(void) {
printk(KERN\_INFO "Des arregando driver\n");
dev\_del(&mydev\_ dev);
unregister\_ hrdev\_region(dev, 3);
open\_dev--;
}
int mydev\_open(stru t inode * inode, stru t file * filp) {
if (open\_dev) {
return -EBUSY;
}
printk(KERN\_INFO "Dispositivo sendo usado\n");
return 0;
}
int mydev\_release(stru t inode * inode, stru t file * filp) {
printk(KERN\_INFO "Dispositivo liberado\n");
return 0;
}

ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, loff\_t *
printk(KERN\_INFO "Mensagem re ebida. Seu tamanho e %d\n", ount);
return ount;
}

ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
printk(KERN\_INFO "Tentativa de leitura de uma mensagem de tamanho %d\n", ount);
return ount;
}
42

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

module\_init(mydev\_init);
module\_exit(mydev\_exit);
/*----------------------- ut here ---------------------------- */
Puxa vida! T a, um driver legal de se ver. excelente para estudar como so feitas as chamadas
de sistema de cada aplicativo. Nosso driver no faz nada de verdade, s mostra o que est sendo
passado a ele. Impressionante, no ? Dava para imaginar, no incio do curso, que a gente ia ver
algo bacana como isso? Observe as diferenas.
O que tem de novo? Bom, registramos a cdev, colocamos a fops e agora exibimos mensagens
sobre o que est sendo passado a ns. Compile e carregue na memria. No esquea 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 relao 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? No sei se voc lembra, mas a funo read() retorna um
nmero. Nmero positivo indica quantos bytes ele leu, e nmero negativo, um erro qualquer. O 0
(zero) significa fim do arquivo. cat l at o fim do arquivo, mas ns nunca retornamos 0 em read().
O que acontece com a regio de memria que o read() passa para preenchermos? Nada. Fica
l, do jeito que veio, volta.

43

Captulo 8

A memria e o Kernel
Vamos entender como funciona a alocao de memria dentro do kernel - zonas de memria,
alocao dinmica, etc

8.1

Como funciona a memria?

Deixe-me explicar um pouco sobre a memria no Linux.


Basicamente, na hora do boot, o kernel divide a memria do seu computador em trs zonas:
a primeira vista de dentro do kernel, e pode ser acessada diretamente por ele, essa zona
chamada de zona normal ou zona baixa de memria. Atualmente seu tamanho mximo chega
a 1 GB (o que muito mais do que necessrio para um kernel de Linux). A segunda zona
chamada de zona alta de memria, e pode ir muito mais alm de 1GB. acessada fora do
kernel, no userspace. A terceira zona de memria chamada de DMA - Direct Memmory Access
(Acesso direto a memria) e geralmente parte de algum dispositivo e muito dependente da
arquitetura. Cada uma das zonas de memria mapeada numa regio diferente, e, assim sendo,
"ponteiros"que vm do userspace podem ser invlidos dentro do kernel space e vice-versa. Por
isso que o buffer enviado a read() e write() no exemplo anterior ficou intocado: antes de mexer com
eles, necessrio entender esses conceitos. Sem contar que, se tentamos acessar o ponteiro
passado em buf, a regio de memria referenciada por ele pode estar inacessvel no momento na
RAM, gerando um page fault. Em um programa normal, tudo bem, s esperar um pouco que o
dado vai ser acessvel. No kernel isso simplesmente inadmissvel! No d para ficar esperando
a boa vontade da memria. E como vamos fazer pra utilizar os dados? Bom, tem duas funes
que servem s para isso, definidas em asm/uaccess.h: copy_from_user() e copy_to_user().
unsigned long copy_to_user(void __user *to, const void *from, unsigned long count);
unsigned long copy_from_user(void *to, const void __user *from, unsigned long count);
Na primeira, *to um ponteiro do userspace que receber os dados, *from um ponteiro do
kernel space de onde os dados sero copiados e count o tamanho em bytes a ser copiado de
*from para *to. Na segunda, copy_from_user(), *to um ponteiro do kernel space, *from um
ponteiro do user space e count a quantidade de dados que vai ser copiada de *from para *to.
To simples que eu nem precisava ter explicado, no ?
Essas duas funes, meus caros alunos, so duas das engrenagens principais de um driver de dispositivo. Sem essas funes, a comunicao userspace<->kernelspace teria de ser
reinventada cada vez que um novo driver fosse criado.
Agora, pense nas possibilidades! Ou melhor, pense no /dev/zero. Na verdade, pense nos
dispositivos virtuais controlados pelo driver mem. Voc pode at olhar em drivers/char/mem.c pra
44

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

ter uma idia. Bom, o que o /dev/zero faz? Quando voc l dele, enche a sada de zeros. Mas
zero no sentido de NADA. No o zero decimal, nem o de caractere. NADA mesmo. NULL.
Quando voc escreve nele, faz a mesma coisa que escrever em /dev/null.
Mas, fazer um driver desses fcil, a gente j d conta com copy_to_user(). Mas ainda est
faltando uma coisa... a funo copy_to_user precisa de um ponteiro para o buffer que queremos
copiar, e esse buffer deve variar seu tamanho de acordo com count (que nos passado atravs
da chamada da funo mydev_read(..., size_t count)). No d para simplesmente enviar um "
0"no lugar do ponteiro para o buffer e retornar o count que nos foi passado; os resultados seriam
imprevisveis.
Ento vou apresentar as funes de tratamento de memria do kernel, para resolver esse
problema. Elas esto definidas em linux/slab.h e so to parecidas com as funes de userspace
que, se eu no falasse, voc nem ia notar a diferena.
A primeira delas a de alocao de memria:
void *kmallo (size\_t size, gfp\_t flags);
E a segunda a de liberao:
void kfree(void *ptr);
kmalloc() funciona como malloc(); retorna um ponteiro para a regio alocada de memria,
size_t size o tamanho que voc quer alocar e gfp_t flags define como vai se comportar essa
funo. Calma, vou explicar. Algumas situaes, voc no precisa de acesso instantneo
memria do kernel e pode esperar at que alguma regio de memria seja liberada para voc;
para isso, voc usa a flag GFP_KERNEL. Em outras situaes, voc precisa instantaneamente de
memria, pois o dispositivo e o driver no podem parar. Essa a flag GFP_ATOMIC. Existe ainda
situaes em que voc quer que a memria alocada esteja disponvel no userspace. Para tanto,
utilize a flag GFP_USER, que aloca e mapeia a memria para o userspace ou GFP_USERHIGH,
que mapeia para o userspace, mas aloca somente na zona alta de memria. Existem ainda flags
mais especficas, como o caso de __GFP_DMA, que diz funo kmalloc() que a memria a ser
alocada capaz de operaes em DMA. H outras flags, mas essas so as mais interessantes.
kmalloc, bem como malloc, retorna NULL caso seja impossvel alocar a memria requisitada.
kfree() age exatamente igual a free(). Libera uma regio de memria. Trabalhando com o
kernel, extremo cuidado com a memria. Lembre-se que a memria no kernelspace no grande
e deve ser poupada.
Existem algumas outras funes associadas kmalloc, que so muito teis tambm. Elas so

void *k allo (size\_t n, size\_t size, gfp\_t flags);


void *kzallo (size\_t size, gfp\_t flags);
void *memset(void *,int,\_\_kernel\_size\_t);
kcalloc cria um array de n elementos, cada um com o tamanho size, e devolve um ponteiro para
essa array; kzalloc devolve um ponteiro para a memria alocada, "zerada"por omisso; memset
equivalente memset da libc, ou seja, seta toda a regio de memria de acordo com seus
parmetros.

45

Captulo 9

Mydev completo
Vamos agora finalizar o nosso driver

9.1

mydev.c

Vamos para a ltima parte do nosso curso. O driver, com algumas das funes que aprendemos durante todas as aulas, ser apresentado de forma completa e funcional. Ele agora capaz
de armazenar um valor na memria do kernel, que tambm poder ser acessado. No final dessa
parte vamos executar alguns programas em nosso dispositivo virtual, s para ver o que acontece.

/* ---------------------------------- ut here ------------------------ */


#in lude <linux/init.h>
#in lude <linux/module.h>
#in lude <linux/types.h>
#in lude <linux/kdev\_t.h>
#in lude <linux/fs.h>
#in lude <linux/ dev.h>
#in lude <linux/slab.h>
#in lude <linux/string.h>
#in lude <asm/ua ess.h>
MODULE\_LICENSE("Dual BSD/GPL");
stati
stati
stati
stati
stati

int major;
dev\_t dev;
int open\_dev;
stru t dev mydev\_ dev;
har * internal\_buffer;

/* Prototipos das fun oes prin ipais */


stati int mydev\_open(stru t inode * inode, stru t file * filp);
stati int mydev\_release(stru t inode * inode, stru t file * filp);
stati ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t *
stati ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, lo
stati int mydev\_init(void);
46

CDTC

Centro de Difuso de Tecnologia e Conhecimento

stati void mydev\_exit(void);


/* Ini ializa ao da fops */
stru t file\_operations mydev\_fops = {
.owner = THIS\_MODULE,
.open = mydev\_open,
.release = mydev\_release,
.read = mydev\_read,
.write = mydev\_write,
};
stati int mydev\_init(void) {
printk(KERN\_ALERT "Carregando mydev\n");
/* registra o driver om 3 minor numbers */
if (allo \_ hrdev\_region(&dev, 0, 3, "mydev")) {
printk(KERN\_ALERT "Houve um problema alo ando o driver\n");
return 1;
}

/* alo a registra a estrutura dev no kernel */


dev\_init(&mydev\_ dev, &mydev\_fops);
mydev\_ dev.owner = THIS\_MODULE;
dev\_add(&mydev\_ dev, dev, 3);
major = MAJOR(dev);
printk(KERN\_ALERT "Nosso major number e %d\n", major);
open\_dev = 0;
internal\_buffer = NULL;
return 0;

stati void mydev\_exit(void) {


printk(KERN\_ALERT "Des arregando driver\n");
dev\_del(&mydev\_ dev);
unregister\_ hrdev\_region(dev, 3);
open\_dev--;
}
int mydev\_open(stru t inode * inode, stru t file * filp) {
if (open\_dev) {
return -EBUSY;
}
printk(KERN\_ALERT "Dispositivo sendo usado\n");
return 0;
}

47

Braslia/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

int mydev\_release(stru t inode * inode, stru t file * filp) {


printk(KERN\_ALERT "Dispositivo liberado\n");
return 0;
}

ssize\_t mydev\_write(stru t file * filp, onst har \_\_user * buf, size\_t ount, loff\_t *
printk(KERN\_ALERT "Mensagem re ebida. Seu tamanho e %d\n", ount);
if (internal\_buffer != NULL)
kfree(internal\_buffer);
internal\_buffer = kmallo ( ount, GFP\_KERNEL);
memset(internal\_buffer,'\0', ount); // Memoria limpa, por favor!
if ( opy\_from\_user(internal\_buffer, buf, ount))
printk(KERN\_ALERT "Erro ao opiar dados do userspa e\n");
return ount;
}

ssize\_t mydev\_read(stru t file * filp, har \_\_user * buf, size\_t ount, loff\_t * f\_pos
int size;
printk(KERN\_ALERT "Tentativa de leitura de uma mensagem de tamanho %d\n", ount);
if (internal\_buffer != NULL)
size = strlen(internal\_buffer) +1; // Nao podemos esque er do \0
else
return 0;
if (*f\_pos >= size)
return 0;
if ( ount > size) // Nao vamos ler mais do que tem pra ler
ount = size;
if ( opy\_to\_user(buf, internal\_buffer, ount)) {
printk(KERN\_ALERT "Erro ao opiar dados para userspa e\n"); // Passando do buffer pr
return 0;
}
*f\_pos += ount;
return ount;
}
module\_init(mydev\_init);
module\_exit(mydev\_exit);
/* ---------------------------------- ut here ------------------------ */

9.2

Utilizao do mydev

Enfim, a est. Primeiro, declaramos globalmente um ponteiro que vamos utilizar como buffer
interno. Tudo que for escrito no dispositivo, vai estar dentro desse ponteiro. Tudo que for lido, vai
48

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Braslia/DF

ser lido desse ponteiro. Em um dispositivo de verdade estaramos apontando para uma regio
de memria prpria dele. No entanto, nosso driver ainda seria responsvel pela manipulao do
offset, da escrita e da leitura, alm de outras coisas. A inicializao e finalizao do driver vocs
j conhecem. O que mudou foram as funes de leitura e escrita. Acrescentamos um monte
de checagens de memria. Vamos para a funo de escrita. A primeira coisa ver se o buffer
existe. Se no, a gente cria um. Depois escrevemos os dados que o programa est mandando
no buffer. Se houver algum erro (copy_to_user e copy_from_user retornam o nmero de bytes
que no puderam ser enviados), a gente exibe a mensagem de erro. Nada demais. A funo de
leitura do dispositivo um pouquinho mais trabalhosa. Temos que checar, primeiro, se existe o
que ser lido. Checamos se o tamanho de dados que est sendo pedido cabe dentro do tamanho
dos dados que temos, para que no haja nenhuma violao de memria. Por ltimo, verificamos
se estamos no final do buffer, retornando 0 caso sim (simbolizando o final do arquivo). Mandamos
os dados para o usurio e ajustamos a cabea de leitura (o offset, f_pos). complicado? No,
n? Moleza Antes de testar, tenha certeza que criou o arquivo de dispositivo correspondente
com mknod e que descarregou (caso esteja carregado) e carregou novamente o driver. Caso as
mensagens no estejam sendo exibidas no terminal, fique de olho no arquivo /var/log/syslog. Vou
chamar o arquivo de dispositivo de mydev, s pra ajudar nos exemplos.
Primeiro teste bsico: echo "oi driver de dispositivo mydev
Verifique o arquivo de log, e vai perceber que chegou a mensagem.
cat mydev
Deve exibir o que foi gravado.
Voc pode fazer tambm
cat <algum arquivo> > mydev
E todo o contedo do arquivo ser copiado.
Voc pode testar o que mais quiser.
Apesar do driver ser bem simples, ele possui alguma utilidade. Pode ser uma regio de
memria que pode ser usada pelo seu programa. Pode ser tanta coisa interessante, e d para
fazer muito mais!

49