sábado, 30 de novembro de 2013

Aula 7 - Criando um Device Driver

Aula 7 - Criando um Device Driver

Este tutorial descreve a criação de um device drive básico



Comando Úteis

  • modprobe argumento - Carrega o módulo do kernel do Linux, verificando suas dependências.
  • modinfo argumento - Fornece informações sobre o módulo.
  • insmod argumento - Carrega o módulo no kernel do Linux.
  • rmmod argumento - Remove o módulo no Kernel do Linux.

Informações

No diretório /dev está contido arquivos de dispositivos, arquivos especiais e simples nós para a arvore do sistema de arquivo.

Identificação:
  • Major number: identifica o driver associado com o dispositivo, especificando o tipo de dispositvo.
  • Minor number: identifica o dispositivo a ele referenciado.
Data Structures Importantes

  • File Operations: o file_operations structure é o meio em que o dispositivo "char" estabelece um conexão. Cada campo do file_operations structure implementa específicas funções para manipulação do dispositivo. Cabendo desenvolvedor estabelecer links esntre as funções do file_operation structure e o código. Ex:


struct file_operations scull_fops = {

.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
#retirada nas versão mais novas do kernel
.ioctl = scull_ioctl, 
.open = scull_open,
.release = scull_release,

};
  • File Structure: representa abrir um arquivo(open file), ele é criado pelo kernel na abertura sendo passado para qualquer função que opera no arquivo até o último fechamento.
  • Inode Structure: é usada internamente pelo kernel para representar arquivos.

Código Exemplo


Quando for programar código para o kernel (módulos, drivers, etc), a Standily Liby C não é usada, por padrão, a implementação tem que usar as funções do próprio kernel.


/*
 * "Hello, world!"
 */

/*
 * Alguns headers necessário para o Device Driver
 */
#include <linux/init.h>
#include <linux/module.h>

/*
 * A função init() é a primeira função executada quando o módulo
 * é carregado. Ele executará somente uma vez quando o módulo
 * é carregado
*/

static int __init
hello_init(void)
{
printk("Hello, world!\n");
return 0;
}

/*
 * A função macro do Kernel
 */

module_init(hello_init);

/*
 * Similar a init(), essa função é chamada quando queremos
 * descarregar o módulo no kernel
 */

static void __exit
hello_exit(void)
{
printk("Goodbye, world!\n");
}

module_exit(hello_exit);

/*
 * Algumas informações para o módulo
*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jack Beagle <http://embarcadosunifor.blogspot.com.br>");
MODULE_DESCRIPTION("\"Hello, world!\" modulo mínimo");
MODULE_VERSION("printk");


Makefile

Abaixo o exemplo de um makefile, para geração de um modulo para o Hello Word.


# obj-m é uma lista para os modulodos do kernel para build.
# O .o e outros objetos serão automaticamente gerados

obj-m := hello.o

# KDIR é a localização dos arquivos do kernel que
# serão utlizados para da build

KDIR  := /lib/modules/$(shell uname -r)/build

# PWD é o diretório atual e da localização do nosso
# módulo.
PWD   := $(shell pwd)

# Faz a linkagem de nosso modulo e o arquivos do kernel para
# compilar e gerar os arquivos necessários..
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules


Carregando o módulo


Entre no diretório do projeto:

  • make
Para carrega o módulo:
  • sudo insmod ./hello.ko
Verificar:

  •  dmesg | tail
Remover módulo:
  • sudo rmmod hello

Verificar:

  •  dmesg | tail
Debugando

  • Printk: Fornece mensagens de acordo com o logleves das mensagens


printk (KERN_DEBUG "Erro:% s:% i \ n", __ FILE__, __ line_ & _);
printk (KERN_CRIT "Erro Grave % p \ n", ptr);

Há oito possíveis seqüências de LogLevel definidos no <linux/kernel.h> :

KERN_EMERG
Usado para mensagens de emergência, geralmente aqueles que precedem um acidente.

KERN_ALERT
Uma situação que requer ação imediata.

KERN_CRIT
Condições críticas, muitas vezes relacionados com graves falhas de hardware ou software.

KERN_ERR
Usado para relatar condições de erro; drivers de dispositivos, muitas vezes, usar KERN_ERR relatar dificuldades de hardware.

KERN_WARNING
Avisos sobre situações problemáticas que não, em si mesmos, criar sérios problemas com o sistema.

KERN_NOTICE
Situações que são normais, mas ainda digno de nota. Uma série de condições relacionadas à segurança são relatados a este nível.

KERN_INFO
Mensagens informativas. Muitos motoristas imprimir informações sobre o hardware que encontram no momento da inicialização, a este nível.



Aula 5 - Configurando servidor e cliente usando NFS/TFTP



Aula 5 - Configurando servidor e cliente usando NFS/TFTP


Instalando NFS Cliente e NFS Servidor (Ubuntu/Debian)

Parte1:

Parte 2:




Servidor:
  • sudo apt-get update 
  • sudo apt-get install nfs-kernel-server nfs-common 

Cliente:
  • sudo apt-get update 
  • sudo apt-get install nfs-common 


Opções do NFS


Algumas opções que podemos utilizar em "/etc/exports" para compartilhamento de arquivos: 
ro : Fornecer acesso somente leitura para os arquivos compartilhados para o cliente. 
rw : Fornece a escrita e leitura para os arquivos compartilhados para o cliente. 
sincronização : Sincronização confirma pedidos para o diretório compartilhado apenas uma vez as mudanças foram cometidos. 
no_subtree_check : Esta opção evita que o sub verificação. Quando um diretório compartilhado é o subdiretório de um sistema de arquivos maior, nfs realiza varreduras de todos os diretórios acima dele, a fim de verificar suas permissões e detalhes. Desativando o sub verificação pode aumentar a confiabilidade do NFS , mas reduzir a segurança . 
no_root_squash : permite o root se conectar ao diretório referente. 


Comando importantes do NFS

  • showmount -e : Informa os compartilhamentos disponíveis de sua máquina local 
  • showmount -e <ip_servidor>: Lista de disponíveis compartilhamentos para o servidor remoto 
  • showmount -d :Informa as lista de todos os subdiretórios. 
  • exportfs -v : Informa uma lista de todos os arquivos compartilhados e opções do servidor. 
  • exportfs -a : Exporta todas as lista de modificações do servidor /etc/exports 
  • exportfs -u : Não exporta as lista compartilhadas em /etc/exports 
  • exportfs -r : Atualiza a lista de modificações do servidor /etc/exports 


Configurando o NFS Servidor


Crie um diretório para ser usado pelo servidor:

mkdir /diretório


Acesse o arquivo presente nesse diretório "/etc/exports", aparecerá :


# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
//começo da configurações

//Exemplo de configuração:
//pasta_a_ser_compartilhada ip_do_cliente(opções_de_configuração)

//Neste caso o servidor fina na própria máquina
/home/david/Nfs 127.0.0.1(rw,sync,no_root_squash)

No terminal:

Execute o comando para resetar o servidor:
  • sudo /etc/init.d/nfs-kernel-server restart 
Execute o comando atualiza e exporta a lista de "etc/exports"
  • sudo exportfs -ra 
Configurando NFS Cliente:

Execute o comando abaixo e verifique se a pasta do servido está dusoinível:
  • showmount -e ip_do_servidor 
Crie uma pasta onde será montado a pasta do servidor:

  • mkdir /mnt/local_montagem 

Para montar a pasta do servidor, execute:
  • mount -t nfs ip_do_servidor:/pasta_compartilhada /mnt/local_motagem 
Para verificar informações da montagem, execute:
  • sudo mount | grep nfs 
Para uma montagem automática, entre no arquivo "etc/fstab":
  • sudo nano /etc/fstab 
Adicione a lina e reinicie a máquina:

  • ip_do_servidor:/pasta_servidor /local_montagem nfs defaults 0 0 


Instalando TFTP Cliente e TFTP Servidor (Ubuntu/Debian)

Servidor:
  • sudo apt-get update 
  • sudo apt-get install tftpd-hpa xinetd 

Client:
  • sudo apt-get update 
  • sudo apt-get install tftp 


Configuração

Verifique a instalação:
  • /usr/sbin/in.tftpd -V
Crie um arquivo  /etc/xinetd.d/tftp

  • sudo gedit /etc/xinetd.d/tftp
Edit o arquivo criado:

No campo user forneça o usuário que irá acessar a pasta.

No campo  server_args  forneça o diretório da pasta o qual será acessado.

Crie a pasta sendo o mesmo diretório em server_args

  • sudo mkdir /tftpbood
Mude a permissão da pasta, neste caso foi setado todas as permissões:
  • sudo chmod -R 777 /tftpboot
Mude o dono da pasta para, sendo o mesmo em user ou pode usar o parâmetro nobody para deixar a pasta sem dono:
  • sudo chown -R nobody /tftpbood
Restart o serviço do xinetd
  • sudo /etc/init.d/xinetd restart

Verificando a troca de arquivos


Verifique se o acesso local do tftp:
  • netstat -l -u | grep ftp

 Crie um arquivo na pasta setada para o servidor:

  • touch /tftpboot/test

Se estiver testando na máquina local :
  • tftp localhost (127.0.0.1)
Se o servidor está em outra máquina:

Teste a conexão:
  • ping ip_servidor
Estabelecendo conexão:
  • tftp ip_servidor
Use ? para lista os comandos:
  • ?
Escreva algo no arquivo do diretório do servidor, neste caso em test e  use o comando abaixo para receber o arquivo::
  • get test   /diretorio_alvo
Feche a conexão:
  • quit