Académique Documents
Professionnel Documents
Culture Documents
2 de Setembro de 2008
Contedo
I Sobre essa apostila
II Informaes Bsicas
18
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
CDTC
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
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
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".
CDTC
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
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
10
CDTC
Braslia/DF
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
Braslia/DF
12
CDTC
Braslia/DF
13
CDTC
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
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
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.
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
Braslia/DF
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.
17
CDTC
tal como a GNU General Public License, para permitir o seu uso em software livre.
18
Braslia/DF
Parte IV
19
Captulo 1
20
Captulo 2
Plano de ensino
2.1
Objetivo
2.2
Pblico Alvo
2.3
Pr-requisitos
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
Braslia/DF
2.6
Programa
2.7
Avaliao
CDTC
2.8
Bibliografia
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
Braslia/DF
Tipos de Dispositivos
3.3
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
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.
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
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
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
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
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
Braslia/DF
}
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
Braslia/DF
CDTC
Braslia/DF
CDTC
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.
CDTC
Braslia/DF
}
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.
CDTC
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
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
Braslia/DF
Estrutura de Inode
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:
union {
stru
t pipe\_inode\_info *i\_pipe;
stru
t blo
k\_devi
e *i\_bdev;
stru
t
dev *i\_
dev;
};
39
CDTC
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:
<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;
CDTC
Braslia/DF
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
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
CDTC
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
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.
int major;
dev\_t dev;
int open\_dev;
stru
t
dev mydev\_
dev;
har * internal\_buffer;
CDTC
47
Braslia/DF
CDTC
Braslia/DF
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
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