O kernel Linux

O kernel é o componente central do sistema. É tão importante que muitas vezes é confundido com o sitema em sua totalidade. Ou seja, apesar de o termo Linux designar apenas o componente central - o kernel -, ele é normalmente utilizado para designar todo o sistema, que é composto por muitos outros programas.

Por isso, muitos desenvolvedores e personagens importantes do mundo do software Livre preferem nomear o sistema como GNU/Linux, dado que a maior parte dos programas que funcionam em conjunto com o kernel Linux fazem parte do projeto GNU, cujo propósito é manter um ambiente de desenvolvimento e ferramentas o mais próximo possível de seus similares do Unix, porém obedecendo ao modelo de desenvolvimento aberto.

O termo código aberto refere-se a um modelo de desenvolvimento de programas de computador no qual o acesso ao código fonte é liberado para consulta, alteração e redistribuição. Isso faz com que um número muito grande de programadores possa analisar e contribuir para o desenvolvimento de uma ferramente ou sistema, na medida em que podem alterá-lo para satisfazer suas próprias necessidades. Alterações feitas no programa original podem ser tornadas públicas ou enviadas à pessoa ou equipe responsável, que analisará a qualidade da alteração e a incorporará ao produto. Linus Torvalds, o criador e atual administrador do kernel, adotou o modelo de desenvolvimento e as licenças GNU para o Linux.

O kernel Linux é um desses componentes que juntos formam o sistema operacional. O papel do kernel é identificar e controlar a comunicação com o hardware, administrar os processos em execução e a comunicação de rede, entre outras atividades relacionadas.

O kernel e seus módulos.

Existem basicamente duas formas de se escrever um kernel para qualquer plataforma: um kernel monolítico ou um micro-kernel. Diferente de um micro-kernel, um kernel monolítico agrega todas as funções dentreo de um único processo. Já um micro-kernel delega cada função específica a processos derivados. Por exemplo, um micro-kernel delega a outro processo o controle das conexões de rede. Dessa forma, possíveis instabilidades na rede não compormetem o funcionamento essencial do sistema. Entretanto, o desenvolvimento de um micro-kernel é muito mais demorado em relação a um kernel monolítico, pois rastrear eventuais falhas e incluir novos recursos é muito mais complicado do que em um kernel monolítico.

O kernel Linux é monolítico. Porém, sua arquitetura é chamada modular. Isso significa que, mesmo sendo um kernel monolítico, todas as suas funções nào precisam necessariamente estar todo o tempo presentes na memória. Por exemplo, o kernel pode estar configurado para trabalhar com dispositivos USB, mas não para manter em memória as funções somente serào carregadas para a memória quando forem necessárias, ou seja quando for conectado um dispositivo USB.

É importante não confundir um kernel modular com um micro-kernel. Apesar de modular, o kernel Linux é um kernel monolítico. Cada módulo carregado é integrado ao kernel ativo e, apesar de em sua maioria poderem ser descarregados da memória, o kernel continua se comportando como único e centralizado.

Antes mesmo que o kernel linux existisse, já havia o projeto GNU. O projeto foi iniciado em 1983 por Richard Stallman, desenvolvedor e ativista do software livre. O propósito do projeto GNU é criar um sistema operacional de código aberto qua corresponda ao mesmo padrão dos sistemas Unix tradicionais.

Versões do kernel

A versão de um kernel Linux é composta de quatro números. juntos, eles informam não só quão recente é o kernel, mas também algumas outras características. Esses quatro números que compõem a versão do kernel são separados por pontos, no formato A.B.C.D. O último elemento - D - nem sempre é utilizado, mas tem função muito importante.

Sufixos do kernel

Além dos quatro números, a versão do kernel pode possuir um sufixo que representa um kernel diferente do oficial - chamado vanilla -, que por sua vez representa um recurso adicional, uma versão de testes ou outra diferença em relação à versão estável.

Os sifixos mais comuns são rc e mm. O sufixo rc(release candidate, ou candidato à versão) representa em prepatch, que é equivalente a uma versão alfa do kernel, e seus arquivos fonte ficam no diretório de teste no servidor do site oficial do kernel www.kernel.org. Essas versões parciais são aplicadas ao kernel completo da versão imediatamente anterior, usando o comando patch. Por exemplo, o patch 2.6.31-rc5 deve ser aplicado à versão 2.6.30. Apenas as versões de kernel com três números podem receber um patch rc.

Portanto, as versões release candidate não devem ser aplicadas a um kernel com quatro números de versão, como 2.6.30.4. O sufixo mmrepresenta um kernel com as modificações realizadas pelo desenvolvedor Andrew Morton, feitas sobre a versão oficial do kernel. Essas alterações são geralmente mais experimentais do que aquelas feitas nas versões oficiais. Todas essas diferentes versões podem ser obtidas diretamente do site oficial do kernel www.kernel.org.

Versão do kernel Linux

Exemplo de versão uma versão de kernel 2.6.30.4

NúmeroSignificadoDescrição
2Versão principalMuda apenas quando ocorrem transformações radicais na estrutura do kernel. Está atualmente na versão 2.
6Número de revisão principalAté a versão 2.4 do kernel, esse segmento, quando par, tratava de uma versão estável. Quando ímpar, tratava de uma versão em desenvolvimento, considerada instável. Da versão 2.6 em diante, não utiliza-se mais essa distinção entre par e ímpar.
30Número de revisão secundárioNas versões mais antigas do kernel, determinava correções e patches de segurança. Hoje demostra se houve inclusões de novos recusos, como drivers de dispositivos, por exemplo.
4Correções urgentesUtilizando quando há revisões de seguraça urgentes, que alteram aspectos relativos à revisão secundária.

Localização do kernel no sistema

O kernel Linux oficial é distribuído como código fonte, ou seja, precisa ser configurado e compilado para ser utilizado pelo sistema. Depois de copiado do site oficial ou usando as ferramentas de instalação da distribuição, o código-fonte do kernel deve ser mantido na máquina local, no diretório /usr/src, num lugar com as informações de versão do kernel, como /usr/src/linux-2.6.30.

Como é possível possuir mais de uma versão dos códigos-fonte, é importante criar um link simbólico /usr/src/linux que aponta para o diretório do código-fonte do kernel atualmente em uso. Esse procedimento é importante para que outros programas possam eventualmente localizar os arquivos do kernel atual. Ali encontram-se não só os arquivos de código-fonte do kernel, mas também a documentação oficial e onde estará o arquivo imagem do kernel após compilado. O arquivo é o kernel em si, que mais tarde será invocado pelo carregador de boot durante o carregamento do sistema.

Imagem e documentação do kernel

A documentação oficial do kernel em questão fica em /usr/src/linux/Documentation/. Neste diretório encontram-se vários arquivos de texto que documentam aspectos específicos do kernel. Por exemplo, para descobrir quais parâmetros o kernel aceita ao ser carregado, o arquivo kernel-parameters.txt pode ser consultado.

Após compilar um novo kernel a partir de seu dódigo-fonte, o arquivo imagem final será encontrado em /usr/src/linux/arch/x86/boot/. Note que o subdiretório x86 varia conforme a arquitetura escolhida durante a configuração do kernel. Se for escolhida a arquitetura PowerPC, por exemplo, a imagem estará em /usr/src/linux/arch/powerpc/boot/.

O nome e o tamanho do kernel variam conforme for invocada a compilação. Existem basicamente dois formatos de imagem de kernel: zImage e bzImage. Ambos são compactados com o método zlib, mas o que os difere é o tamanho máximo de arquivo. Um arquivo zImage possui tamanho máximo de 512 Kb, tamanho adequado para versões mais antigas do kernel. As versões recentes exigem um tamanho maior, por isso foi instituído o arquivo bzImage - big zImage -, que não possui essa limitação de tamanho.

Compilando um kernel

Apesar de a maioria das distribuições acompanhar imagens de kernel pré-compiladas, pode ser necessário personalizar o kernel para corresponder a necessidades específicas, como suporte a hardware incomum ou a um sistema de arquivos exótico. Também é comum recompilar o kernel para ocupar menos recursos e operar em máquinas mais antigas.

O código-fonte do kernel pode ser obtido por meio de pacote específico da distribuição ou diretamente do site oficial www.kernel.org. Nó último caso, o código é distribuído como um arquivo Tar compactado, e deve ser extraído no local padrão, /usr/src/linux, que geralmente é um link simbólico para o diretório criado na extração, como /usr/src/linux-x.x.xx. O processo de personialização de um kernel exige três etapas principais: configuração, compilação e, por fim, instalação.

Pré-requisitos para configuração e compilação: Para que seja possível compilar um kernel, é necessário que estejam presentes no computador as ferramentas de desenvolvimento, ou seja, os programas e arquivos necessários para compilar outros programas. Essencialmente, é necessário um compilador da linguagem C - o gcc - e alguns acessórios, como o próprio comando make e bibliotecas.

A instalação dessas ferramentas varia de acordo com a distribuição. Em distribuições Debian e derivados, como a distribuição Ubuntu, basta executar o comando apt-get install build-essential, que se encarrega de isntalar os programas de desenvolvimento e compilação fundamentais.

Em ambientes Red Hat ou derivados, como o Fedora, a instalação pode ser feita com os comandos yum groupinstall “Development Tools” e yum install kernel-devel kernel-headers. Mesmo as interfaces de configuração do kernel são compiladas antes de serem utilizadas. Por isso, é necessário que estejam instalados os pacotes de desenvolvimento para a interface desejada, sejam eles ncurses, Qt ou Gtk.

Configuração

A configuração de um novo kernel é feita invocando o comando make, de dentro do diretório onde está o código-fonte do kernel. Existem diferentes tipos de interfaces de configuração, mas a mais tradicional é a interface ncurses, invocada por meio do comando make menuconfig. A configuração é feita no próprio terminal, numa interface simples de menu.

Existem outras maneiras de configurar o kernel, mas todas elas produzem o mesmo resultado, que é gerar o arquivo .config no diretório do código-fonte do kernel. Interfaces alternativas à configuração via terminal são os assistentes de configuração fetiso em Qt e em Gtk. Ambos devem ser executados de dentro do ambiente gráfico X.

DICA: Quando vamos configurar novo kernel para um sistema já em funcionamento ele carraga por padrão o arquivo .config da versão do kernel que já esta em uso com todos os módulos que estão compilados para ela porem em algumas circunstâncias não necessitamos de todos aqueles módulos, em /usr/src/linux/arch/XX/configs temos os arquivos de configuração mínimas para o funcionamento do kernel aonde esta XX troque pela arquitetura exemplo x86 seria /usr/src/linux/arch/x86/configs dentro deste diretório temos os arquivos de configuração mínimos para aquela versão do kernel funcionar. Então como dever ser feito copie o arquivo dentro de configs para /usr/src/linux com o nome de .config ex: cp /usr/src/linux/arch/x86/configs/i386_defconfig /usr/src/linux/.config agora quando carregar ou o menuconfig ou outra ferramente para gerenciamento ele vai carregar essas configurações agora é só adicionar outros módulos necessários que não estão na configuração. Outra forma de efetuar isso seria utilizando o comando make defconf em /usr/src/linux

O arquivo gerado após a configuração do kernel, .config, também pode ser editado num editor de texto convencional. Porém, essa prática não é recomendada, pois além de o arquivo ser demasiado extenso há opções interdependentes que podem ser quebradas. A recomendação é sempre utilizar um meio tradicional de configuração.

Outras formas de configurar o kernel são:

  • make config: Criar ou atualizar a configuração por meio de uma interface orientada a perguntas e respostas na linha de comando;
  • make oldconfig: Recupera todas as configurações do arquivo .config pré-existente e pergunta apenas sobre novas opções.

Compilação

Finalizada a configuração, o kernel já pode ser compilado. Se não for a primeira compilação do kernel, pode ser conveniente executar make mrproper, que apaga as configurações e os arquivos gerados durante uma compilação anterior. Dessa forma, se evita que hajam objetos com dependências desencontradas. Para apagar apenas os arquivos compilados anteriormente, mas preservar a configuração, utiliza-se make clean.

Para gerar a imagem zImage ou bzImage do kernel, utiliza-se make zImage ou make bzImage, respectivamente. Os comandos apenas funcionarão se for obedecida a grafia correta, com o I maiúsculo em zImage ou bzImage. A compilação pode demorar de minutos a horas, dependendo do número de recursos escolhidos e do computador utilizado. Provavelmente o novo kernel será modular, e os módulos precisarão ser compilados separadamente. Isso é feito com o comando make modules.

Acelerando a compilação: Boa parte das máquinas modernas são equipadas com mais de um processador ou processadores de mais de um núcleo. Para aproveitar essa capacidade é recomendável disparar processos de compilação simultâneos. Isso é feito com a opção -j do comando make. Por exemplo, make -j4 bzImage compilará o kernel em quatro processos simultâneos, o que agilizará bastante a compilação

Instalação

Depois que o kernel e os módulos forem compilados, é necessário copiá-los para localização correta e configurar o carregador de boot para que possa encontrá-lo ao iniciar o sistema.

Num computador de arquitetura x86, o arquivo de imagem do novo kernel estará em /usr/src/linux/arch/x86/boot/zImage ou em /usr/src/linux/arch/x86/boot/bzImage. Esse arquivo deve ser copiado para o diretório /boot e deve ser renomeado para algo mais claro e apropriado, como vmlinuz-2.6.30-abc. O termo vmlinuz é a nomenclaruta padrão para os arquivos de kernel do Linux. Recomenda-se também especificar a versão no nome do kernel em questão e utilizar um sufixo que indique a sua especificidade.

Já os módulos possuem comandos específicos para instalação. Após compilados, são instalados usando o comando make modules_install. Será criado um diretório com a numeração do kernel em /lib/modules. Portanto, para um kernel 2.6.30 o diretório dos módulos será /lib/modules/2.6.30. O comando make modules_install também se encarrega de gerar o arquivo modules.dep nesse diretório, que armazena as informações de interdepdendência dos módulos.

INSTALAÇÃO EM UMA LINHA DE COMANDO APÓS BAIXADO O KERNEL E CRIADO O LINK

make -j 6 bzImage && make -j 6 modules && make -j 6 modules_install && make -j 6 install \
&& cd /boot && mkinitramfs -o /boot/initrd.img-2.6.xx 2.6.xx && update-grub && reboot

Acima troque o initrd.img-2.6.xx pela versão do seu kernel exemplo 2.6.30 aonde tem os xx tem que ser mudado pela versão que você esta utilisando.

Aqui acima o que estou fazendo primeiro compilando a imagem do kernel, depois eu vou compilar os modulos, após isso vou efetuar a instalação dos modulos e a instalação do kernel, após isso eu gero a inital ramdisk e atualizo o grub e por final reinicio o sistema. Note que para seprar os comandos eu utilizei && que é um teste lógico que vai na tabela verdade E que somente vai executar o segundo comando senão ocorrerem erros no anterior com isso eu vou garantir que sómente vai ser executado a próxima tarefa se a anterior foi bem sucedida.

Referências

  1. /usr/src/linux/Documentation/kernel-parameters.txt
  2. /usr/src/linux/Documentation/kernel-docs.txt