26. Recompilação do Kernel - Debian 5.0 (Lenny)

Talvez você ache estranho o título dessa seção Recompilação do Kernel!

O que isso tem a ver com automação?

Vou primeiramente explicar porque tive que recompilar o kernel do linux.

Tenho usado as portas seriais para comunicação com equipamentos de laboratório (instrumentos, bombas etc), mas o número de portas seriais disponíveis nos computadores é limitado. No passado os computadores eram comercializados com 2 portas seriais, depois reduziram para 1 porta serial e atualmente alguns não possuem portas seriais RS232.

Eu conheço 2 alternativas:

  1. Usar adaptadores USB-RS232 e aproveitar as portas USB disponíveis nos micros modernos para comunicação com os equipamentos de laboratório.

  2. Instalar uma Placa Multiserial com 2, 4 ou mais portas seriais RS232, permitindo conectar vários equipamentos.

Como já tinha disponível algumas placas multiserial no nosso laboratório, resolvi instalar uma placa de 8 portas (no slot pci), mas percebi que o sistema reconhecia apenas 4 portas seriais (duas da placa mãe e 2 da placa multiserial)! :^(

Depois de pesquisar descobri que eu precisava recompilar o Kernel mudando apenas a opção: CONFIG_SERIAL_8250_RUNTIME_UARTS para um valor adequado ao número de portas instaladas 10 (2 originais + 8 da placa multiserial = 10).

Me conectei com um modem 3G mas ao tentar rodar o apt-get update percebi que o apt tentava usar o proxy da intranet apesar do navegador funcionar normalmente.

Depois de pesquisar descobri que o arquivo /etc/apt/apt.conf especificava o proxy da seguinte forma:

Acquire::http::Proxy "http://login:senha@nome_proxy.empresa.com:8080";

Bastou apagar essa linha e o apt-get rodou normalmente.

Usei informações sobre recompilação do kernel nos seguintes locais:

O Debian oferece 2 maneiras de compilar o kernel:

Em seguida instalei os pacotes:

# apt-get install kernel-package wget build-essential

No site ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ baixei os arquivos linux-2.6.26.2.tar.bz2 e linux-2.6.26.2.tar.bz2.sign.

Baixei o fonte do kernel 2.6.26-2 atualmente instalado para evitar maiores problemas.

Dica

Para saber qual a versão do kernel instalado na sua máquina digite em um terminal:

uname -a

O arquivo com extensão .sign é usado para verificar a autenticicade do arquivo baixado com o comando:

# gpg --verify linux-2.6.26.2.tar.bz2.sign linux-2.6.26.2.tar.bz2

Mas antes é necessário baixar a chave pública com os comandos:

# gpg  --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E
gpg: requesting key 517D0F0E from hkp server wwwkeys.pgp.net
gpg: /root/.gnupg/trustdb.gpg: banco de dados de confiabilidade criado
gpg: key 517D0F0E: public key "Linux Kernel Archives Verification Key " imported
gpg: no ultimately trusted keys found
gpg: Número total processado: 1
gpg:               importados: 1

E em seguida rodar o comando:

# gpg --armor --export 0x517D0F0E | apt-key add -

No entanto ao verificar a integridade recebo uma mensagem estranha:

# gpg --verify linux-2.6.26.2.tar.bz2.sign linux-2.6.26.2.tar.bz2
gpg: Signature made Qua 06 Ago 2008 14:30:35 BRT using DSA key ID 517D0F0E
gpg: Good signature from "Linux Kernel Archives Verification Key "
gpg: AVISO: Esta chave não está certificada com uma assinatura confiável!
gpg:        Não há indicação de que a assinatura pertence ao dono.
Impressão da chave primária: C75D C40A 11D7 AF88 9981  ED5B C86B A06A 517D 0F0E

Segundo informações do site www.kernel.org/signature.html#expire essa mensagem é normal e por isso resolvi tocar em frente.

Copiar o arquivo linux-2.6.26.2.tar.bz2 para o diretório /usr/src:

# cp linux-2.6.26.2.tar.bz2 /usr/src/

Entrar no diretório /usr/src e descompactar o arquivo:

# cd /usr/src/
/usr/src# tar -xjf linux-2.6.26.2.tar.bz2

Criar um link simbólico para o diretório linux-2.6.26.2 criado e entrar neste diretório:

/usr/src# ln -s linux-2.6.26.2 linux
/usr/src# cd linux

Copiar o arquivo de configuração do seu kernel atual para o diretório local com o nome .config para fazer as modificações necessárias:

/usr/src/linux# cp /boot/config-2.6.26-2-686 .config

Mas ao chamar o menuconfig para editar o arquivo de configuração, recebi a mensagem:

/usr/src/linux# make menuconfig

*** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 *** 
 *** Install ncurses (ncurses-devel) and try again.
 *** 

Então me lembrei de instalar a biblioteca ncurses com o comando:

/usr/src/linux# apt-get install libncurses5-dev

E finalmente pude rodar o menuconfig.

/usr/src/linux# make menuconfig

Inicialmente selecionei a opção Load an alternate Configuration File e digitei .config o qual contém as configurações do kernel instalado.

Em seguida ajustei o número máximo de portas seriais com as seguintes opções:


Device Drivers --->
Character devices  ---> 
  Serial drivers  ---> 
(10) Number of 8250/16550 serial ports to register at runtime

Definindo o número 10 como o número máximo de portas seriais.

Conforme a dica do site www.hardware.com.br/dicas/recompilando-kernel-debian.html, acesse a opção general setup, que será aberta em um menu separado. Logo na primeira opção ( ) Local version - append to kernel release, você deve colocar um nome personalizado para seu kernel, afim de não acabar com mais de um kernel com o mesmo nome, o que pode gerar problemas mais tarde.

No meu caso, coloquei -serial na opção, e o kernel ficou com o identificador 2.6.26.2-serial.

Após fazer as alterações selecionar a opção Exit e salvar o arquivo com as novas configurações.

Em seguida dar início à recompilação com o comando:

/usr/src/linux# make all

Muita calma nessa hora. :^)

Não sei quanto tempo demorou porque deixei rodando durante a noite.

No dia seguinte rodei:

/usr/src/linux# make modules_install
/usr/src/linux# make install

Após a instalação verifiquei que foi instalado os arquivos System.map-2.6.26.2-serial e vmlinuz-2.6.26.2-serial no diretório /boot.

Em seguida criar o arquivo initrd.img para o novo kernel compilado. Segundo o artigo http://forum.clubedohardware.com.br/tutorial-compilar-kernel/722300 este arquivo contém o mapa de driver de dispositivos necessários para carregar o resto do sistema operacional.

Se você quiser saber mais sobre o initrd e initramfs existem mais informações nas páginas:

Entrar no diretório /boot e criar o arquivo initrd.img-2.6.26.2-serial:

/usr/src/linux# cd /boot
/boot# mkinitramfs -o initrd.img-2.6.26.2-serial 2.6.26.2-serial

E finalmente a edição do arquivo /boot/grub/menu.lst para o Grub reconhecer o novo kernel.

Editar o final do arquivo /boot/grub/menu.lst com um editor qualquer (Ex: vi, gedit, emacs) adicionando após ## ## End Default Options ## as linhas:


title Debian GNU/Linux, kernel 2.6.26.2-serial
root (hd0,0)
kernel /boot/vmlinuz-2.6.26.2-serial root=/dev/hda1 ro quiet
initrd /boot/initrd.img-2.6.26.2-serial

Atenção

Alterar os nomes das partições (hd0,0 e hda1) de acordo com as suas partições e não modificar as linhas do kernel original.

E por último:

#  update-grub

Pronto! Agora é só reiniciar a máquina, selecionar o novo kernel instalado e cruzar os dedos. :^)

Se houver algum problema, basta reiniciar a máquina e selecionar a opção do kernel antigo para corrigir algum problema.

No meu caso funcionou direitinho e o sistema reconheceu e configurou todas as portas seriais da placa multiserial instalada. :^)

Somente depois de ter tido todo esse trabalho descobri que poderia fazer a mesma coisa apenas passando o seguinte argumento para o kernel na hora do boot:

8250.nr_uarts=10

Para saber mais sobre passagem de parâmetros na hora do boot pesquise por Passing the kernel argument.

Apesar de ter seguido o caminho mais longo e trabalhoso, enquanto poderia ter resolvido de maneira muito mais simples, não fiquei chateado pois acho que conhecer o processo de recompilação do kernel pode ser muito útil para otimizar o sistema, habilitar recursos de hardware e conhecer as ferramentas necessárias para a compilação de programas no Linux.

Além disso, toda essa informação poderá ser útil para você! :^)