O Kernel

Hoje em dia, quando falamos em “Linux”, estamos normalmente nos referindo à plataforma como um todo, incluindo as diferentes distribuições e softwares. Mas, no início, o Linux era apenas o kernel desenvolvido pelo Linus Torvalds.

Mesmo hoje em dia, alguns puristas ainda insistem na ideia de que o “Linux” é apenas o kernel e todos os outros componentes são softwares que rodam sobre ele. O principal argumento a favor dessa ideia é que outros sistemas Unix, como o FreeBSD e o OpenSolaris, são baseados em outros kernels (e são por isso considerados sistemas diferentes) mas, apesar disso, rodam o X, KDE, Firefox e outros softwares, assim como no caso das distribuições Linux. De qualquer forma, a ideia de usar o termo Linux para a plataforma como um todo é bem mais simples e natural, por isso adoto esta terminologia no livro.

O kernel é a peça fundamental do sistema, responsável por prover a infra-estrutura básica necessária para que os programas funcionem, além de ser o responsável por dar suporte aos mais diferentes periféricos: placas de rede, som e o que mais você tiver espetado no micro.

Essa é justamente uma das principais diferenças entre o Windows e as distribuições Linux. No Windows, o sistema inclui um conjunto relativamente pequeno de drivers e você depende dos CDs de instalação e dos drivers disponibilizados pelos fabricantes. No Linux, quase todos os drivers disponíveis são incorporados diretamente no kernel e já vêm pré-instalados nas distribuições. Isso faz com que os periféricos suportados sejam detectados automaticamente.

Isso faz com que a importância de usar uma distribuição atual seja muito maior, já que uma distribuição antiga ou desatualizada incluirá não apenas softwares antigos, mas também um conjunto desatualizado de drivers, que farão com que muitos componentes do PC não sejam reconhecidos.

Começando do início, se você der uma olhada dentro da pasta “/boot” de qualquer distribuição Linux, vai encontrar o executável do kernel no meio de um pequeno conjunto de arquivos. Ele é o primeiro componente carregado pelo gerenciador de boot durante a inicialização do sistema:

Você deve estar se perguntando por que o arquivo se chama “vmlinuz” e não “vmlinux”, como seria mais lógico. Na verdade, esta é uma longa história, mas, em resumo, o “z” no nome é usado porque o arquivo do kernel é guardado no HD na forma de um arquivo compactado.

Nas primeiras distribuições Linux, todos os drivers e outros componentes eram compilados diretamente nesse arquivo principal, e você podia escolher os componentes a ativar na hora de compilar o kernel. Se você habilitasse tudo, não teria problemas com nenhum dispositivo suportado, tudo iria funcionar facilmente, mas, por outro lado, você teria um kernel gigantesco, que rodaria muito devagar no seu 486 com 8 MB de RAM.

Se, por outro lado, você compilasse um kernel enxuto e esquecesse de habilitar o suporte a algum recurso necessário, teria que recompilar tudo de novo para ativá-lo. Como resultado disso, as distribuições passaram a incluir diversas opções de kernel, compiladas com configurações diferentes. Você tinha então que escolher qual usar, de acordo com os componentes do micro.

Este problema foi resolvido durante o desenvolvimento do kernel 2.0, através do suporte a módulos. Os módulos são peças independentes que podem ser ativadas ou desativadas com o sistema em uso. Do kernel 2.2 (lançado em 1999) em diante, quase tudo pode ser compilado como módulo, o que tornou as coisas muito mais práticas e abriu as portas para os sistemas de detecção automática de hardware que são usados nas distribuições atuais.

Os módulos nada mais são do que arquivos, que são armazenados dentro da pasta “/lib/modules/versão_do_kernel”. Veja que os módulos ficam organizados em pastas: a pasta “kernel/drivers/net/” contém drivers para placas de rede, a pasta “kernel/drivers/usb/” agrupa os que dão suporte dispositivos USB, e assim por diante:

Na maioria dos casos, os módulos possuem nomes que dão uma ideia do dispositivo a que oferecem suporte. O “8139too.ko” dá suporte às placas de rede com o chipset Realtek 8139, o “sis900.ko” dá suporte às placas SiS 900, enquanto o “e100.ko” ativa as placas Intel E100, por exemplo. Se você fizer uma pesquisa pelo nome de um módulo específico no Google, vai quase sempre chegar à página do projeto ou a alguma página ou manual explicando o que ele faz.

Para ativar o suporte a um certo dispositivo, você (ou o utilitário de detecção incluído no sistema) precisa apenas carregar o módulo referente a ele. O resto é feito pelo próprio kernel, que se encarrega de ativar o dispositivo e criar um caminho de acesso para ele.

Cada vez mais, o trabalho de detecção e carregamento dos módulos passa a ser feito de maneira automática pelas distribuições, através dos códigos de identificação incluídos nos próprios dispositivos. Uma placa de rede com chipset Realtek, por exemplo, retorna algo como “Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+”. Com base nesses códigos, o sistema pode descobrir quais periféricos estão instalados e carregar os módulos apropriados, de forma automática.

Você pode checar os códigos de identificação dos dispositivos instalados usando os comandos “lspci” e “lsusb”. Nos casos em que você precisa carregar um módulo manualmente, é usado o comando “modprobe”, seguido do módulo desejado, como em:

# modprobe ndiswrapper

Para descarregar um módulo, é usado o “modprobe -r”, como em:

# modprobe -r ndiswrapper

Você pode ver uma lista com todos os módulos disponíveis usando o comando “modprobe -l”. A lista é muito longa para caber na tela ou mesmo no buffer do terminal, por isso é interessante adicionar um “| more”, que adiciona quebras de página na exibição. Basta ir pressionando a barra de espaço para avançar:

# modprobe -l | more

Essa longa lista é mais uma curiosidade, mas os mais curiosos podem usá-la para tentar entender mais sobre o suporte a hardware e os componentes do sistema. A lista mostra a estrutura de pastas completa até os módulos, o que ajuda a descobrir para que cada um serve. Ao ver o “/lib/modules/2.6.29-1-686/kernel/drivers/net/wireless/ipw2200.ko” na lista, por exemplo, você pode presumir que se trata do módulo que dá suporte a placas de rede wireless com chipsets Intel IPW2200.

Algumas distribuições oferecem uma opção de carregar módulos adicionais durante a instalação, atendendo justamente aos raros casos onde você precisa de um determinado módulo para ativar a placa SCSI onde está instalado o HD, por exemplo.

Os módulos são gerados durante a compilação do kernel. Você não precisa se preocupar com isso se não quiser, pois as distribuições quase sempre incluem versões bem completas do kernel por padrão, mas, de qualquer forma, existe sempre a possibilidade de recompilar o kernel, mexendo nas opções e ativando ou desativando os módulos que quiser.

Na prática, a situação mais comum onde você precisa lidar com módulos é quando precisa instalar manualmente algum driver modificado ou proprietário, necessário para ativar algum dispositivo em particular. Infelizmente, isso é ainda relativamente comum ao usar componentes recém lançados, ou em algumas configurações problemáticas, como em alguns notebooks com chipset SiS ou VIA.

Diferente dos drivers open-source, que são incluídos diretamente no kernel, os drivers proprietários são distribuídos sob licenças mais restritivas, que impedem sua inclusão direta. Os desenvolvedores do kernel são especialmente cuidadosos com relação ao uso de componentes proprietários, para evitar que o sistema se torne vulnerável a disputas na justiça.

Um bom exemplo de como esta atitude cautelosa é importante, é o caso da SCO (http://en.wikipedia.org/wiki/SCO_v._IBM), que em 2003 entrou na justiça contra a IBM, alegando que ela havia contribuído com trechos de código de propriedade da SCO no kernel Linux e exigindo reparações. No final, as acusações se provaram falsas e a SCO é que acabou sendo condenada a pagar reparações (acabando por ir à falência), mas o caso foi um alerta muito claro.

Em alguns casos, os drivers proprietários são de livre distribuição e (embora não façam parte do kernel) podem ser incluídos diretamente nas distribuições. Em outros, você mesmo precisará baixar e instalar o driver. É aqui que entram os drivers para muitos softmodems, para algumas placas wireless e também os drivers para placas 3D da nVidia e da ATI.

A psicologia para lidar com eles é a seguinte: instalar um destes drivers envolve duas tarefas, baixar e instalar o módulo propriamente dito e criar um “dispositivo” (device), um atalho que aponta para o endereço de hardware usado por ele. Para facilitar esta tarefa, geralmente os drivers vêm com algum tipo de instalador, geralmente um script simples de modo texto que cuida disso para você.

Os módulos são parte integrante do kernel, por isso os módulos compilados para uso em uma determinada distribuição não funcionam em outra, a menos que, por uma grande coincidência, as duas utilizem exatamente a mesma versão do kernel. Isso é bastante improvável, já que o kernel Linux é atualizado quase que diariamente.

Se você usar uma distribuição popular, Mandriva, Fedora, SuSE, etc., é possível que você encontre um driver pré-compilado para download (que pode ser encontrado com a ajuda do bom e velho Google). Neste caso, você só vai precisar instalar um pacote RPM ou executar um arquivo de instalação. Em outras situações, você encontrará apenas um arquivo genérico ainda não compilado, contendo um instalador que se encarrega de compilar um módulo sob medida para o kernel em uso.

Como o script de compilação não tem como adivinhar qual distribuição ou kernel você está utilizando, é necessário ter instalado os pacotes “kernel-source” e “kernel-headers”, que acompanham qualquer distribuição. No Mandriva, por exemplo, você pode instalá-los usando os comandos:

# urpmi kernel-source
# urpmi kernel-headers

Naturalmente, para conseguir compilar qualquer coisa, você precisará também de um compilador (o gcc), que também acompanha as distribuições. Se você tiver estas três coisas, vai conseguir instalar qualquer driver sem maiores problemas, basta seguir as instruções na página de download ou no arquivo INSTALL ou README dentro do pacote.

No Ubuntu, por exemplo, o gcc, juntamente com os utilitários básicos de compilação, podem ser instalados através do pacote “build-essential”, que comentei no tópico sobre instalação do VMware Player na introdução. Ele é um meta-pacote (um pacote que, quando instalado, dispara a instalação de vários outros), que se encarrega de instalar um conjunto básico de compiladores e bibliotecas.

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X