Índice das dicas

Linux: entendendo o Kernel

Por Carlos E. Morimoto em 1 de dezembro de 2010 às 20h07

30

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 idéia 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 idéia é que outros sistemas Unix, como o FreeBSD e o Solaris 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 idéia de usar o termo Linux para a plataforma como um todo é bem mais simples e natural.

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.

Esta é 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 comentes 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 opçõ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 idéia 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 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 carregamentos dos módulos está passando a ser feito de forma 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".

Em 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

Algumas distribuições oferecem uma opção de carregar módulos adicionais durante a instalação, justamente pensando nos raros casos onde você precisa de um determinado módulo para ativar a placa SCSI onde está instalado o HD para poder prosseguir com a instalação, 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.

30 comentáriosPor Carlos E. Morimoto. Revisado 1 de dezembro de 2010 às 20h21

Comentários

Dúvida sobre o arquivo vmlinuz
por Hugo Martins (anônimo) em 3 de dezembro de 2010 às 04h28
Bem, a postagem foi bem interessante, mas seria muito melhor se fosse explicado detalhadamente o porquê do nome vmlinuz - até entendo que iria fugir um pouco do tema se fosse abordado sobre isso por aqui. No entanto posso encontrar algo a respeito em algum outro artigo daqui do guiadohardware?
Z por Slayer-Slack (anônimo)
Sim, mas... por Hugo Martins (anônimo)
Hugo, se você deseja um curso completo de linux, compre livro ou procure um. por Ricardo (anônimo)
Winmodems
por Hamilton (anônimo) em 2 de dezembro de 2010 às 14h27
O pessoal que usa linux a mais tempo deve lembrar do trampo que era pra fazer esses modems funcionarem no Linux, quanta recompilação de kernel e kernel panic. Pra minha sorte um tio meu tinha um Usrobotics ISA(!!!!) sobrando e a partir daí nunca mais tive dor de cabeça ;)
é verdade... por Thiago Cantero Mari Monteiro (anônimo)
Hoje em dia...
por Rodrigo Zimmermann (anônimo) em 2 de dezembro de 2010 às 08h33
Hoje em dia quase ninguém compila o kernel, as distribuições continuam a disponibilizar versões diferenciadas: com suporte a PAE e o kernel omnislash. Geralmente, quem compila o kernel deseja algo bem específico.
 
por Tancredo Sena (anônimo) em 13 de março de 2010 às 16h28
ありがとう
 
por Carlos E. Morimoto em 26 de janeiro de 2009 às 12h43
O "z" no "/boot/vmlinuz" surgiu por que o arquivo é compactado. Essa ideia surgiu com objetivo de acelerar o boot, lendo um arquivo menor no HD (que é lento) e em seguida rodando-o a partir da memória RAM (que é rápida).
 
por Fábio André (anônimo) em 26 de janeiro de 2009 às 12h21
E quanto a história do linuz com "z"?
 
por Daniel Sader Pontello Neves (anônimo) em 18 de dezembro de 2008 às 21h14
Muito bom!!! Deu pra explicar muita coisa. Por quê você não escreve um livro: "O Kernel do Linux"??
 
por Thiago Melkior de Toledo Borges (anônimo) em 14 de dezembro de 2008 às 17h08
Ótimo post, gostaria de saber mais sobre o kernel.
Vou pesquisar sobre.
 
por Túlio Adriano Cutrim Muniz (anônimo) em 7 de novembro de 2008 às 18h16
Me desculpem pelo erro no português, só reparei quando publiquei meu comentário.
Eu sou novo no linux, o conheci a um ano, e minha primeira distro foi o Kurumin 4, depois disso já usei DSL, Puppy, Ubuntu e Basic Linux. Hoje tenho em meu PC o Kurumin 7 e o Puppy 2.17.

Me aventurei a compilar kernel e do inicio tive algumas dificuldades. Diversos erros de compilação, um deles foram por opções que marquei inadequadamente, outros foram por causa de incompatibilidade do meu compilador, já executei a 19ª tentativa de compilação e a maioria dos erros já foram corrigidos, só me restou o que postei acima.
Sempre usei o comando #make após o comando #make allnoconfig e #make menuconfig.
Isso mesmo, sempre usei o modo de texto para marcar as opções para serem compiladas.
Marquei a maioria das opções contidas, pois minha intenção é compilar um Kernel com suporte a vários dispositivos.
Nisso é que está a minha dúvida pois existe um monte de arquivos .o e .ko, como vi neste blog eles são os módulos do Kernel. Certo?
Só queria saber de antemão como faço para corrigir o erro que pedir anteriormente?

Obrigado a todos!
 
por Túlio Adriano Cutrim Muniz (anônimo) em 6 de novembro de 2008 às 18h13
Exelente artigo Marimoto, gostei muito das informaões descritas, mas me resta uma dúvida.
Estou trabalhando na compilação do kernel 2.6.26.5 e está aparecendo o seguinte erro quando marco a opção PCI SUPPORT em BUS OPTIONS:

drivers/pci/search.c: In function 'pci_get_dev_by_id':
drivers/pci/search.c:284: warning: passing argument 1 of 'pci_dev_put'
discards qualifiers from pointer target type

Gostaria de saber como faço para corrigir esse problema? Estou usando o compilador GCC 3.4

E outra coisa, o que são os arquivos .o que estão nas pastas drivers/scsi por exemplo?

Grato a quem me ajudar!