Algumas vezes acontece que quando fazemos a instalação de um sistema operacional GNU/Linux em uma máquina algumas interfaces não funcionam “de primeira”. Típico exemplo disto é o não funcionamento da interface wifi, que pode necessitar da instalação de um determinado driver proprietário. Especialmente na distribuição Debian que preza por todos os softwares terem qualidade e serem 100% livres, os drivers proprietários não estão incluídos entre aqueles softwares da sua imagem ISO dos CDs ou DVDs de instalação.
Este texto visa dar uma compreensão melhor do que fazer nestes momentos.
1) O papel do dispositivo driver (“device driver”)
O papel de um módulo (driver) é estender a funcionalidade do kernel. Ainda mais, o papel do dispositivo driver é prover mecanismos, e não a política. Por exemplo, o driver de floppy é livre de políticas: seu papel é apenas mostrar o disquete como um contínuo array de blocos de dados. Níveis mais altos provêem as políticas, tais como quem pode acessar o driver de floppy, se o driver é acessado diretamente ou via um filesystem e se os usuários podem montar o filesystem no driver. Um driver é flexível, oferecendo acesso ao hardware sem adicionar restrições.
Um módulo (driver) é executado no espaço do kernel. Uma aplicação é executada no espaço do usuário. No mundo Unix, o kernel é executado no mais alto nível (chamado modo supervisor), onde tudo é permitido, enquanto as aplicações são executadas no nível mais baixo (também chamado modo usuário), onde o processador regulamenta o acesso direto ao hardware e o acesso não autorizado à memória.
Uma das boas características do Linux é a habilidade de estender o conjunto de facilidades oferecido pelo kernel. Cada pedaço de código que pode ser adicionado ao kernel em tempo de execução é chamado um módulo. O Linux diferencia três tipos de dispositivos fundamentais: char module, block module e network module. Mas isto não é rígido. O console de texto (/dev/console) e as postas seriais (/dev/ttyS0 e correlatas) são exemplos de char devices, acessados via device files. Block devices são acessados também através de device files presentes no diretório /dev. Um block device é um dispositivo (por exemplo, um disco) que pode hospedar um filesystem. Já o módulo (ou interface) de rede não é facilmente mapeado através de um device file , como é o /dev/tty1. A maneira Unix de provê acesso à interfaces é ainda atribuindo um único nome para elas (tal como eth0), porém este nome não tem uma entrada correspondente no filesystem.
Existem ainda outros tipos de módulos drivers. Cada dispositivo USB é controlado por um módulo USB que trabalha com o subsistema USB, porém o próprio dispositivo mostra-se no sistema como um char device (se for uma porta serial USB), um block device (se for um leitor de cartão de memória USB) ou um network device (se for uma interface USB Ethernet).
2) Níveis de suporte do Kernel
O kernel Linux não suporta completamente todos os dispositivos de I/O. Em termos gerais, existem três possíveis tipos de suporte aos dispositivos de hardware:
Absolutamente sem suporte
O programa aplicativo interage diretamente com as portas de I/O do device mediante a emissão correspondente de instruções em linguagem assembly. O exemplo mais comum deste tipo, que não depende de qualquer driver de dispositivo do kernel, é como o “X Window System” tradicionalmente lida com a tela gráfica. Isto tem uma explicação histórica, que vem dos tempos em que o Unix fora introduzido. Naqueles tempos, terminais gráficos eram raros e muito caros, fazendo com que apenas terminais alfanuméricos fossem manipulados diretamente por Kernels Unix. Quando os terminais gráficos se tornaram difundidos, aplicações ad hoc foram introduzidas, tal como o “X Windows System” (que foi um projeto independente em sua origem *). O “X Windows System” já tinha seus processos padronizados e acessava de forma direta as portas de I/O da interface gráfica e a memória RAM de vídeo.
Outro exemplo deste tipo de suporte são as interfaces de rede. A placa de rede já empacota seu controlador, que segue padronizações de rede bem definidos (que existem vários, entre eles a Ethernet que atualmente é a mais comum).
(*) O X Windows foi um projeto criado pelo MIT em 1984. Com o passar do tempo, surgiram variantes deste projeto, como o XFree86 e o X.Org. O X.Org, por exemplo, surgiu em 1999 como uma reação à mudança da licença do X Windows.
Suporte Mínimo
O kernel não reconhece o “device hardware“, mas reconhece sua interface de I/O. Programas dos usuários são capazes de tratar a interface como um dispositivo sequencial capaz de ler e/ou escrever sequencias de caracteres. É usada para manipular os dispositivos de hardware externos conectados a uma interface de I/O de propósito geral. O kernel cuida da interface I/O, oferecendo um “arquivo de dispositivo” (e, portanto, um “driver de dispositivo”), e o programa aplicativo lida com o dispositivo de hardware externo, lendo e escrevendo o arquivo de dispositivo.
Suporte Mínimo é preferível em relação ao Suporte Estendido, pois contribui para um kernel enxuto. Exemplos são as portas seriais e paralelas, que são utilizadas por mouses seriais e modem seriais, por exemplo. Nestes casos, os mouses seriais são controlados diretamente pelo programa aplicativo (tal como o servidor X) e os modems necessitam de um programa de comunicação ou um daemon de protocolo ponto-a-ponto (PPP).
Suporte Estendido
O kernel reconhece o dispositivo hardware e manipula a interface de I/O por si mesmo. De fato, pode até não existir um “arquivo de dispositivo” para o dispositivo. Esse tipo de suporte é o mais genérico e são necessários para aqueles dispositivos com forte acoplamento com o SO. Neste tipo de suporte, o kernel provê um device driver para cada device. Dispositivos externos conectados à USB, à porta PCMCIA ou à interface SCSI requerem o suporte extendido.
3) Sistemas de Arquivos no Debian
O sistema Debian fornece o sistema de arquivos sob o qual os dados físicos em discos rígidos e outros dispositivos de armazenamento, e a interação com os dispositivos de hardware como telas de console e consoles seriais remotos são representados em uma forma unificada. Cada arquivo, diretório, pipe nomeada, ou dispositivo físico em um sistema Debian tem uma estrutura de dados chamada “inode” que descreve seus atributos associados como o usuário que é seu dono, o grupo ao qual pertence, a hora do último acesso, etc..
Essa representação unificada de entidades físicas é muito poderosa já que nos permite usar o mesmo comando para o mesmo tipo de operação em muitos dispositivos totalmente diferentes.
4) Arquivos de dispositivos (“device files“) no GNU/Linux
Arquivos de dispositivos se referem a dispositivos físicos ou virtuais em seu sistema, tais como seu disco rígido, sua placa de vídeo, monitor, ou teclado. Um exemplo de dispositivo virtual é o teclado, representado pelo /dev/console.
No sistema operacional Linux tudo é baseado na noção de arquivos, seja um conjunto de dados ou um periférico do computador (como um HD, impressora,etc). Neste sentido, dispositivos de entrada/saída (I/O) são tratados como arquivos especiais chamados arquivos de dispositivos (“device files“). O diretório /dev contém estes arquivos de dispositivos que servem de comunicação com os dispositivos de hardware (“devices“) e periféricos do computador (discos rígidos, mouses, etc.). Estes arquivos têm influência direta quando do “boot” do sistema. Na prática, representam os dispositivos hardware do computador.
Um arquivo de dispositivo está associado com um dispositivo hardware (tal como um HD, por exemplo, /dev/sda) ou com alguma porção física ou lógica do dispositivo hardware (tal como uma partição do disco, por exemplo, /dev/sda2). Por exemplo, quando executamos o comando “less -f /dev/sda“, de fato fazemos a leitura diretamente do primeiro HD físico da máquina. Os nomes destes arquivos em /dev é arbitrária e é escolhida por conveniencia e consistência.
É importante distinguir estes “arquivos de dispostivos” dos “arquivos de drivers”. Os arquivos de dispositivos são simplesmente pontos de encontro usados para comunicação do sistema operacional com os drivers. Eles não são os drivers em si. Um driver de dispositivo, também chamado de módulo de dispositivo, cuida dos detalhes específicos de gerenciamento direto do dispositivo hardware.
Exemplos de arquivos de dispositivos:
Nome Tipo Major Minor Descrição
/dev/fd0 bloco 2 0 Floppy disk
/dev/hda bloco 3 0 Primeiro disco IDE
/dev/hda2 bloco 3 2 Segunda partição primária, primeiro disco IDE
/dev/hdb bloco 3 64 Segundo disco IDE
/dev/hdb3 bloco 3 67 Terceira partição primária, segundo disco IDE
/dev/sdb bloco 8 0 Segundo disco SCSI
/dev/ttyp0 char 3 0 Terminal
/dev/console char 5 1 Console (terminais não-gráficos)
/dev/lp1 char 6 1 Impressora paralela
/dev/ttyS0 char 4 64 Primeira porta serial
/dev/rtc char 10 135 Clock de tempo-real
/dev/null char 1 3 Null device
OBS:
(a) atualmente as placas-mãe possuem duas interfaces IDE (ou duas SCSI), uma primária e outra secundária. Cada interface tem capacidade de controlar até dois dispositivos hardware (geralmente HD ou CD-ROM);
(b) os arquivos dos dispositivos de rede não estão representados em /dev, sendo considerado uma exceção.
Número dos dispositivos:
Os arquivos de dispositivo vêm com duas identificações básicas:
(a) o tipo do arquivo de dispositivo, se de bloco (para HW do tipo HD ou CD-ROM), de caracter (para HW do tipo cartões de som ou teclado) ou interface de rede (eth0);
(b) um par de números: o principal e o secundário (“major number” e “minor number“). O primeiro identifica o tipo do dispositivo, e o segundo número identifica o dispositivo específico dentre um grupo de dispositivos que compartilham o mesmo número principal. Por exemplo, um grupo de discos gerenciados pelo mesmo controlador de disco têm o mesmo número principal e diferentes números secundários. Note que os dispositivos tipo bloco e tipo char têm numerações independentes, tal que o dispositivo de bloco (3,0) é diferente do dispositivo char (3,0).
Os arquivos de dispositivos em /dev possuem essas identificações. Estes números de dispositivo principal e secundário identificam o dispositivo para o kernel, onde este utiliza esses números para associar referências do arquivo de dispositivo ao driver correspondente. O número de dispositivo principal identifica o driver com o qual o arquivo está associado (ou seja, o tipo de dispositivo). O número de dispositivo secundário identifica qual a instância em particular de um dado tipo de dispositivo deve ser tratada.
%ls -l /dev/sda*
$ ls -l sd*
brw-rw---- 1 root disk 8, 0 Dez 29 17:37 sda
brw-rw---- 1 root disk 8, 1 Dez 29 17:37 sda1
brw-rw---- 1 root disk 8, 2 Dez 29 17:37 sda2
brw-rw---- 1 root disk 8, 3 Dez 29 17:38 sda3
brw-rw---- 1 root disk 8, 5 Dez 29 17:37 sda5
Observe pela resposta do sistema:
- na primeira coluna, a letra “b” representa um block driver. Quando for o caso de um char driver, a letra presente será “c”.
- 8 identifica o número de dispositivo principal. Ou seja, todos os discos SCSI possuem “major number” 8.
- 0, 1, 2, 3 e 5 identificam os números de dispositivos secundários (as unidades). O driver é livre para interpretar o número de dispositivo secundário da maneira que lhe aprouver.
O registro oficial dos números dos dispositivos e o diretório dos devices file /dev está disponível no sítio do desenvolvimento do kernel do Linux em ftp://ftp.kernel.org/pub/linux/docs/device-list/devices.txt; as macros correspondentes aos “major numbers” dos dispositivos podem ser encontradas no arquivo include/linux/major.h (no Debian em /usr/src/linux-headers–common/include/linux/major.h).
Criando Arquivos de Dispositivos com o comando mknod
Apesar que todos os arquivos de dispositivos estarem listados no diretório /dev, em tese pode-se criar um arquivo de dispositivo em qualquer localização do sistema de arquivo através do comando mknod:
mknod [-m ] [b|c]
onde:
(a) as letras ‘b’ e ‘c’ são para criação de “device” de bloco ou character, respectivamente;
(b) ‘mode‘ é a permissão.
Exemplo:
mknod -m 0600 ~/my-floppy b 2 0
ls -al /dev/fd0 ~/my-floppy
onde neste caso my-floppy pode ser usado da mesma forma que usamos tradicionalmente a /dev/fd0
5) Montar um dispositivo
Para acessar os dados que estão em um dispositivo, no Linux usamos o conceito de montar; assim, quando se coloca um cd no computador, por exemplo, tem-se de ‘montar’ o cd para acessá-lo, isto é, deixar os dados que estão no cd disponíveis para uso. O que o comando mount faz é anexar um sistema de arquivos à árvore atual de arquivos (que forma o atual leiaute geral do sistema de arquivos). O comando mount associa um diretório dentro da árvore de arquivos existente, chamado de ponto de montagem, à raiz do sistema de arquivos recém-chegado. O conteúdo anterior do ponto de montagem se torna inacessível enquanto um outro sistema de arquivos esteja montado nele.
O comando utilizado para montar dispositivos é o mount, e sua sintaxe básica é:
mount dispositivo ponto_de_montagem
Como os dispositivos são tratados como arquivos, será sempre /dev/alguma_coisa!
Exemplos:
# mount /dev/fd0 /diretorio_onde_o_disco_vai_ser_montado
# umount /dev/fd0
O primeiro comando para montar o disco flexível. O diretório_onde_o_disco_vai_ser_montado tem que existir, e tem que estar totalmente vazio. O segundo comando para desmontar o disco flexível.
# mount /dev/hda2 /diretorio_onde_o_disco_vai_ser_montado
# umount /dev/hda2
O primeiro comando para montar a partição /dev/hda2 (HD número 1, partição número 2). O segundo comando para desmontar a partição.
# mount /dev/cdrom /mnt/cdrom
# umount /dev/cdrom
O primeiro comando monta a unidade de CD-ROM. O segundo realiza a operação inversa. Observe que o arquivo /dev/cdrom é sim um link simbólico para o dispositivo correspondente ao CD-ROM (/dev/srx). Isso quer dizer que se pode substituir o /dev/cdrom pelo /dev/srx tranqüilamente, assim como pode também modificar o link simbólico para apontar para outro dispositivo.
# mount -t ext3 /dev/sda1 /mnt/diretorio
Comando para montar a partição raiz de um sistema de arquivos, a partir de um live-CD.
O arquivo /etc/fstab armazena as configurações de quais dispositivos devem ser montados e qual o ponto de montagem de cada um na inicialização do sistema operacional. Por exemplo, quando o sistema operacional inicia, ele procura no arquivo /etc/fstab para saber onde está a raiz do seu sistema, e vai montar no /.
Vejamos aqui um exemplo de arquivo /etc/fstab:
$ cat /etc/fstab
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/sda1 / ext3 errors=remount-ro 0 1
/dev/sda3 /home ext3 defaults 0 2
/dev/sda5 none swap sw 0 0
/dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0
OBS: = checagem de disco. Determina se o dispositivo deve ou não ser checado na inicialização do sistema pelo fsck. É um campo numérico, onde 0 é para não ser checado, 1 é para ser checado primeiro(raiz) e 2 para checar depois do raiz.
Dentro de cada linha, o primeiro parâmetro (/dev/sda1 por exemplo) indica a partição, o segundo parâmetro indica a pasta onde ela será montada (/, por exemplo), o terceiro indica o sistema de arquivos em que a partição foi formatada (ext3, por exemplo), enquanto o “defaults 0 0” permite definir configurações adicionais. O “default” por exemplo faz com que a partição seja acessada usando as opções padrão, enquanto se fosse utilizado o “noatime” seria uma opção de otimização que faria com que o sistema não atualizasse a data de acesso quando os arquivos fossem lidos, o que resultaria em um pequeno ganho de desempenho.
A segunda linha é a raiz do sistema, que está na partição /dev/sda1, será montada automaticamente (‘defaults’) no diretório “/” durante a inicialização. E esta partição tem o sistema de arquivos ext3. Na quarta temos a montagem da memória SWAP. E vejamos a linha que começa com /dev/scd0. Aqui facilita as coisas porque os parâmetros ‘user,noauto’ significam que qualquer usuário pode montar o CD-ROM (user) e não é montado automaticamente na inicialização (noauto). Qual a diferença? O comando mount só pode ser usado pelo root, mas com essa opção no /etc/fstab, um usuário comum pode montar o cd-rom apenas com o comando “mount /mnt/cdrom”, ou “mount /dev/cdrom”. Você pode criar suas próprias configurações para dar mais praticidade no seu uso com os dispositivos no Linux! Mexa à vontade, mas nunca nas linhas que já vêm, pois se não o Linux pode não achar sua partição e poderá não conseguir iniciar o sistema.
Ao instalar outros HDs posteriormente, pode-se fazer com que o sistema passe a usá-las inserindo as linhas apropriadas no arquivo “/etc/fstab”. Em sistemas como Debian e Ubuntu a referência as partições em /etc/fstab não é realizada através do dispositivo. Mas sim pelo UUID, que é um identificador único. Para seguir este padrão adicionar o novo HD em /etc/fstab, faça o seguinte:
(a) após montar o novo disco (identificando as particições, no caso aqui sdc1), verificar qual é o UUID:
#blkid /dev/sdc1
/dev/sdc1: LABEL=”novoHD” UUID=”aae8c256-24a8-4533-b163-5a08ff4a49f0″ TYPE=”ext3″
(b) especificar o UUID na linha do /etc/fstab no lugar do device:
UUID=aae8c256-24a8-4533-b163-5a08ff4a49f0 /mnt/scd1 ext3 defaults 0 0
OBS: deixe sempre uma linha em branco no final do arquivo /etc/fstab.
6) Módulos (drivers) de Kernel carregáveis
O kernel contém drivers de dispositivos que gerenciam interação com as peças de hardware específicas. O restante do kernel é, em grande parte, independente do dispositivo. A existência da camada de driver ajuda a manter o Linux relativamente independente de dispositivos. Drivers de dispositivos fazem parte do kernel, não sendo processos de usuários. Porém um driver pode ser acessado tanto de dentro do kernel quanto do espaço do usuário. O acesso em nível de usuário para dispositivos é normalmente fornecido através de arquivos de dispositivos especiais que residem no diretório /dev. O kernel transforma operações nesses arquivos em chamadas para o código do driver.
Somente drivers de dispositivos para uso com linux (e normalmente, para uma versão específica do kernel Linux) pode ser instalada com sucesso num sistema Linux. Drivers para outros sistemas operacionais (como Windows, por exemplo) não funcionarão.
Um driver de dispositivo pode ser linkado e removido do kernel a qualquer instante. Essa possibilidade facilita a instalação de drivers, já que o binário do kernel não necessita ser modificado. Também possibilita o kernel ser menor, pois os drivers não são carregados a menos que necessário. Os módulos de kernel carregáveis são armazenados em /lib/modules/version-kernel, onde ‘version-kernel’ é a versão do kernel linux em uso (reportada através do comando ‘uname -r’).
7) Verificar a interface de rede wifi (Network controller) e seu driver
O não funcionamento do hardware da interface de rede se encaixa em um dos três casos:
(a) a placa de rede é incompatível com o sistema linux;
(b) a placa de rede é incompatível com a versão do kernel Linux; e
(c) o driver da placa não está disponível no sistema.
As soluções para cada um dos problemas são:
(a) adquira uma placa compatível com o sistema Linux;
(b) atualize o kernel do linux; e
(c) adquira o módulo (driver) correto do fabricante.
Passo-1: verificar se algum dispositivo “Network” fora reconhecido pelo linux:
# lspci | grep "Network"
02:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8191SEvB Wireless LAN Controller (rev 10)
Vemos neste exemplo que a placa de rede fora reconhecido pelo linux. A placa não teria sido reconhecido pelo sistema Linux caso não houvesse nada como resposta. Neste caso, reinicia-se o dispositivo ou retira-se e coloca-se novamente a placa de rede, caso esta placa seja do tipo “espetada”.
Passo-2: verificar os detalhes deste dispositivo:
# lspci -v -s 02:00.0
02:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8191SEvB Wireless LAN Controller (rev 10)
Subsystem: Device 1a32:0308
Flags: bus master, fast devsel, latency 0, IRQ 16
I/O ports at 3000 [size=256]
Memory at d8100000 (32-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
Capabilities: [70] Express Legacy Endpoint, MSI 00
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Virtual Channel
Capabilities: [160] Device Serial Number 88-55-22-fe-ff-4c-e0-00
Kernel driver in use: rtl819xSE
Vemos que o módulo (driver) em uso referente a placa é o rtl819xSE.
Caso não tivesse sido carregado nenhum drive, uma possível resposta ao mesmo comando seria:
02:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8191SEvB Wireless LAN Controller (rev 10)
Subsystem: Quanta Microsystems, Inc Device 0308
Flags: fast devsel, IRQ 16
I/O ports at 3000 [size=256]
Memory at d8100000 (32-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
Capabilities: [70] Express Legacy Endpoint, MSI 00
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Virtual Channel
Capabilities: [160] Device Serial Number 88-55-22-fe-ff-4c-e0-00
em cuja resposta pode se observar que não há a indicação do driver em uso, como no caso do primeiro comando.
Passo-3: verificar os módulos em uso (carregados) no sistema:
# lsmod
Module Size Used by
r8192se_pci 481792 0
onde pode-se verificar que o módulo (driver) realmente está carregado.
Passo-4: verificar onde se encontra o módulo armazenado no HD:
Os módulos (drivers) no sistema Linux possuem o sufixo “.ko”:
# modprobe --list | grep "r8192"
kernel/drivers/net/wireless/r8192se_pci.ko
Ou seja, o endereço completo da localização do driver é: /lib/modules/2.6.32-5-amd64/kernel/drivers/net/wireless/r8192se_pci.ko
OBS: caso o módulo não tivesse carregado, seria possível carregá-lo usando o comando modprobe ou usando o comando insmod:
# modprobe r8192se_pci
# insmod /lib/modules/2.6.32-5-amd64/kernel/drivers/net/wireless/r8192se_pci.ko
Outros comandos úteis:
(a) lsmod: lista os módulos atualmente carregados. Trabalha lendo o arquivo /proc/modules. Informações dos módulos carregados também podem ser encontradas em /sys/module
(b) insmod: carregar (inserir) manualmente um módulo no kernel.
(c) rmmod: remover manualmente um módulo carregado no kernel.
(d) modprobe: carregar/remover de forma semi-automática um módulo kernel. Trata-se de um envoltório para os comandos ‘insmod’ e ‘rmmod’ que compreende as dependências, opções e procedimentos de instalação/remoção. Um arquivo muito importante aqui é o ‘/etc/modules.conf’ev, o qual permite controlar as opções de todos os módulos do sistema.
(e) depmod: verifica as dependências de um determinado módulo.
Mais informações:
1- Unix Devices
2- Linux Device List
3- Como habilitar os dispositivos WiFi baseados nos chipsets Intel 3945 and 4965 em sistemas Debian
4- Intel Wireless Wifi Link Drivers for Linux
5- Debian Wireless Fidelity
6- How to use a WiFi interface
Identificação de dispositivos PCI:
7- Como identificar os dispositivos PCI de uma máquina
8- Identificação dos PCI devices
9- PCIdatabase
10- Listagem de dispositivos wireless devices com informação sobre o seu chipset, e se são suportados em Linux
outras publicações neste blog referentes a este assunto:
11- Instalando driver de dispositivo Wifi no laptop HP Pavilion dv2040 usando o Debian
12- Configurando as interfaces do laptop LG modelo LGR58, configuração R590, para Debian squeeze
13- Instalando o adaptador de rede wireless D-Link DWL-G510 no Debian
14- Entendendo os drivers Linux para arquitetura de barramento PCI
livros:
15- Livro: Linux Device Drivers