# Introdução aos Sistemas Operacionais/Exemplo de Comunicação com Hardware em Drivers Linux: Título 2
#### Dados gerais
## Autoria

Everton Cerqueira - 050133
Wanderson Paim de Jesus - 060219

## Licenciamento

Licença (GLP)

## Objetivo e descrição

    O objetivo do projeto é estudar o processo de desenvolvimento de dispositivos do Linux por meio da documentação e modificação de códigos-exemplo disponibilizado no livro "Linux Device Drivers - de Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman" e em sites direcionados ao assunto. O enfoque será no aprendizado da API de programação. Os resultados do estudo serão documentados como projetos de grupo na disciplina de Sistemas Operacionais da Wikiversity.
    O projeto Blink visa o desenvolvimento de um driver para comunicação com o hardware, mais especificamente com os leds do teclado. E para isso organizamos o conteúdo de forma a facilitar o aprendizado de possíveis leitores. Inicialmente é feita uma introdução ao tema Linux Device Drivers, buscando mostrar os principais conceitos envolvidos no decorrer da publicação. Então iniciamos uma descrição da configuração de um ambiente favorável e da exemplificação de um módulo básico e suas principais funções. Em seguida apresentaremos o projeto Blink, um antecessor do driver Blink, que será pautado no último capítulo.

## Apresentação do projeto Blink

    Para exemplificar o processo de criação de um módulo para o linux, primeiramente pensamos em criar um projeto funcional de comunicação com um hardware, o qual poderia futuramente ser adaptado para utilização como módulo.
    O hardware escolhido foi o teclado, pois nele existem alguns leds de indicação que podem ser utilizados como teste. Os leds do teclado podem ser controlados diretamente por portas de E/S. As portas de E/S são utilizadas pela CPU para comunicar com quase todos os controladores e periféricos. Cada porta tem um endereço no qual podemos realizar operações de escrita e leitura.
    Cada dispositivo dentro do computador tem uma faixa de portas de E/S alocadas que poderam ser utilizadas para comunicação. Para checar qual a faixa de portas que um certo dispositivo pode usar para comunicação, basta dar uma olhada no /proc/ioports. Analisando este arquivo, percebemos que o teclado usa a faixa de portas 0x60 – 0x6f. Para resolver nosso problema de controle dos leds do teclado, utilizaremos apenas a porta 0x60.

#### Comunicação

Para controlar os leds do teclado, devemos seguir o seguinte processo:
      * Escrever o comando 0xED na porta 0x60. Esse comando deve indicar ao teclado que em seguida ele receberá um padrão de configuração dos leds.
      * A controladora do teclado irá enviar pela porta 0x60 um comando de resposta 0xFA indicando que ele está pronto para receber a configuração.
      * O teclado espera um valor do tipo byte na porta 0x60 com a configuração desejada para os leds, que segue o seguinte padrão:
      * 000: todos desligados
      * 001: somente SCROLL-LOCK ativo
      * 010: somente NUM-LOCK ativo
      * 100: somente CAPS-LOCK ativo
      * 111: todos ligados
Para ter permissão de interação com o hardware, ou seja, permissão para executar operações de E/S em modo usuário, devemos utilisar a função ioperm ou a função iopl da API <sys/io.h>, o que as difere é que enquanto iopl adquire permissão para um conjunto de portas a ioperm adquire somente para uma. O programa deve ser compilado usando a opção -o para forçar a expansão das funções internas.

#### Código comentado
## O módulo Blink

No intuito de tornar o projeto blink em um módulo, o primeiro passo é descobrir quais são as APIs fornecidas pelo kernel do linux que poderão substituir as utilizadas pelo nosso blink.c. Tais como stdio.h, sys/io.h, unistd.h e stdlib.h. Para substituir a função ioperm, temos no kernel do linux a função request_region e para que seja possível sua utilização, temos que importar a API <linux/ioport.h> do kernel. Sua utilização é demonstrada e explicada no código comentado do módulo blink.

#### Código fonte
## Procedimento para testes

Para iniciar os testes é preciso que os arquivos blink.c e o Makefile estejam na mesma pasta. Então é executado o comando make, que compilará o blink.c gerando, dentre outros, o blink.ko, modulo o qual será instalado utilizando o comando insmod.
Uma vez instalado, podemos checar sua disponibilidade e tambem o Major number atribuido, utilizando o comando cat /proc/devices, agora que já sabemos desses dados, podemos criar o driver no /dev da seguinte maneira: mknod /dev/blink c MN 0 - isso irá criar o nosso driver comunicador com o Major Number MN atribuido. A partir dai basta fazer um pedido de execução para ativar a função device_open do módulo e ver o resultado. Um exemplo seria cat /dev/blink. Para remover o módulo basta fazer um rmmod blink.ko.