Aula 1 – Prova 201 – Kernel Linux

A partir de hoje irei começar a postar aqui em meu blog tudo que aprender referente aos meus estudos para adquirir a LPIC-2. Planejo realizar a prova 201 no próximo mês de Julho e a prova 202 no próximo mês de Agosto. Então até lá, estarei postando o conteúdo da prova como uma série de “aulas” sobre tópicos bem definidos. Como estou em um processo de aprendizado, é possível e inevitável que eu escreva algo que pode ter sido erroneamente interpretado por mim, sendo assim, se alguém ler este tópico e tiver correções a realizar, por favor, sinta-se a vontade.

Importante observar que o conteúdo aqui apresentado tem o objetivo de ajudar aqueles que estão estudando para mais esta certificação (assim como eu) e não têm alguma referência em português, apesar da prova requerer conhecimentos em inglês.

Neste primeiro post irei tratar do Kernel do Linux. Este tópico possui quatro objetivos:

  • Apresentar os componentes do Kernel Linux
  • Compilar o Kernel Linux
  • Aplicar um patch no Kernel
  • Customizar um Kernel

Objetivo 1 – Componentes do Kernel

Antes de iniciarmos a trabalhar com o kernel, é necessário ter a curiosidade de conhecer alguns componentes dele. Dar uma olhada no diretório da árvore do kernel poderá nos dar uma idéia dos vários componentes que são necessários para a funcionalidade do mesmo. O kernel gerencia todos os aspectos do seu computador, como memória virtual, drivers de dispositivos, acesso a recursos de rede e assim por diante. O kernel também executa aplicações, porém, estas são executadas em um espaço fora do kernel, chamado de User Space.

Detalhes sobre o desenvolvimento do kernel estão além do escopo da prova 201. Essencialmente, o que a LPI irá cobrar é um entendimento dos vários tipos de kernel, utilização de branches do desenvolvimento do kernel e eficientemente aplicar patches.

Existem basicamente dois tipos de imagens do kernel:

  • zImage – imagem em um formato antigo, voltado para arquiteturas Intel. O nome zImage representa que ela está compactada utilizando o método zlib. O tamanho máximo permitido para esta imagem é de 512KB. Se desejar utilizar uma imagem de kernel superior a este tamanho, é necessário o uso da imagem bzImage.
  • bzImage – a letra “b” (big) indica que é uma imagem maior que a zImage. Este tipo de imagem não é restrita aos 520KB, podendo chegar até 2,5MB. Sendo assim, hoje é a opção preferencial para a imagem do kernel Linux.

Patches

Os patches também são encontrados em duas árvores de desenvolvimento diferentes: stable e development. Porém, existem terceiros que realizam a implementação de algumas características específicas que os mantenedores do kernel acharam melhor não incluir (pelo menos no momento). Patches são atualizações ou correções pequenas que podem ser aplicadas para específicos kernels sem a necessidade de baixá-los inteiramente.

Patches são normalmente nomeados da seguinte maneira: patch-versão. Por exemplo: patch-2.6.22-rc2.bz2. Será discutido sobre patches mais adiante.

Módulos do Kernel

O kernel Linux permite o carregamento e descarregamento de módulos em tempo de execução. São utilizados para adicionar novas funcionalidades ao kernel sem a necessidade de recompilá-lo.

Quando você constrói um kernel, algumas características podem ser utilizadas como módulos. Porém, módulos podem depender de outros módulos. Depois de instalado o kernel e os módulos, o comando depmod pode ser utilizado para realizar a interdependência entre os módulos. O resultado é armazenado em /lib/modules/versão-do-kernel/modules.dep.

Objetivo 2: Compilando um Kernel

Para melhor acompanhar este tópico, é importante realizar teste com uma imagem de kernel baixada de http://www.kernel.org. A compilação do kernel ocorre basicamente através das seguintes etapas:

  1. Descompactar a imagem do kernel em /usr/src.
  2. Criação do link simbólico de maneira que o diretório /usr/src/linux aponte para a árvore do kernel descompactada. Não que isto seja realmente fundamental para a realização da compilação, porém, antigas aplicações dentro do kernel desenvolvidas utilizando a antiga biblioteca libc podem ter problemas caso a árvore esteja em outro diretório. Hoje com a implementação da glibc, este problema foi, acredito eu, solucionado.
  3. Caso não seja a primeira compilação desta árvore do kernel, é necessário realizar uma limpeza dos arquivos gerados. Podemos utilizar o comando make com as opções “clean”, “mrproper” e “distclean”. Uma descrição de cada uma dessas opções podem ser obtida aqui.
  4. Agora temos que realizar a configuração do kernel. Para isso, pode ser utilizada alguma das opções disponíveis com o comando make: config, oldconfig, menuconfig, xconfig e gconfig.
  5. Se estivermos trabalhando com o kernel 2.4, após a configuração é necessário a resolução da dependência entre os diversos módulos configurados. Para tanto, utilize o comando make dep.
  6. Realizar a criação da imagem do kernel. Esta etapa irá depender do tipo de kernel escolhido. Para a criação de uma zImage, utilize o comando make zImage e para a geração de uma bzImage, utilize make bzImage. Esse comando compila o kernel e o coloca em /usr/src/linux/arch/i386/boot/bzImage ou /usr/src/linux/arch/i386/boot/zImage.
  7. Realizar a cópia da imagem gerada para /boot utilizando o padrão de nome vmlinuz-versão.
  8. Copiar o arquivo /usr/src/linux/System.map para /boot. Uma boa explicação sobre a finalidade do System.map pode ser obtida aqui.
  9. Compile os módulos. Ou seja: make modules.
  10. Instale os módulos. make modules_install.
  11. Crie a RAM Disk, se ela for necessária. Para tanto, utiliza-se o comando mkinitrd. Mais detalhes sobre seu funcionamento adiante neste post. Depois a copie para o diretório /boot, se necessário.
  12. Por último, realize a configuração do LILO ou do GRUB.

OBS: Para que não seja necessária a execução de cada um destes comandos separadamente pelo usuário, podemos coloca-los em fila. Para tanto, basta digitar o comando abaixo.

# make clean dep bzImage modules modules_install

Utilizando o Initrd

Initrd é uma contração de initial ram disk. A Initrd é utilizada pelo kernel para carregar alguns drivers antes que o kernel seja carregado. É preciso para que se crie o ambiente necessário para o acesso ao disco rígido e assim ser possível carregar os outros módulos. Sua criação e funcionamento irão diferir de acordo com o padrão da RedHat e do Debian. Para cada um dos padrões, será dito como proceder para a criação da Initrd.

mkinitrd no RedHat

Para que seja possível a criação de imagens Initrd no RedHat, o mesmo deve possuir suporte a RAM disks e dispositivos loop. O sistema RedHat irá checar os arquivos de configuração de módulos (/etc/modprobe.conf ou /etc/modules.conf) para verificar quais os módulos que serão necessários ao boot. Suporte a SCSI, LVM, RAID, ext2 e IDE são normalmente requeridos.

O comando para a geração da initrd no RedHat segue abaixo.

# mkinitrd -v /boot/initrd-versão-do-kernel

mkinitrd no Debian

Para a geração da imagem Initrd no Debian é necessário suporte cramfs em seu kernel. Em sistemas Debian, o comando mkinitrd irá seguir a configuração realizada no arquivo /etc/mkinitrd/mkinitrd.conf. O arquivo é auto-explicativo, pois contém diversos comentários sobre cada uma de suas opções. O comando abaixo irá gerar a imagem Initrd para o Debian.

# mkinitrd -o /boot/initrd-versão-do-kernel /lib/modules/versão-do-kernel

Objetivo 3: Patching um Kernel

Na prova LPIC 201 é cobrada a aplicação e remoção de patches no seu kernel. Para tanto, é necessário possuir uma árvore do kernel e um patch específico para atualizá-la. Cada patch é desenvolvido para uma versão específica do kernel. Para aplicar um patch, basta seguir estes passos:

  1. Realizar um backup de sua árvore do kernel, pois, caso haja algum problema na aplicação do patch, será possível reverter o processo.
  2. Acessar o diretório raiz da árvore do kernel que será modificada.
  3. Aplicar o patch com o comando a seguir.
  4. # bunzip2 -c patch-versão-do-patch | patch -p1

    A opção “-p1” indica qual o nível do diretório em que o patch será aplicado. Ou seja, apenas o primeiro nível abaixo do diretório atual será “patcheado”.

  5. Alguns arquivos poderão ser rejeitados durante a aplicação do patch. O arquivo contendo as diferenças será criado com a extensão “.rej”. Importante verificá-los e corrigir as rejeições.
  6. Modificar o Makefile de maneira a identificar que houve alterações por patches. Adicione alguma identificação na variável EXTRAVERSION.
  7. Atualize a configuração do kernel. Pode ser facilmente feito com o comando make oldconfig que irá aproveitar a configuração anterior. Caso não haja uma configuração anterior, podem ser utilizados alguns dos comandos de configuração já mencionados.
  8. Compile o kernel, da mesma maneira que foi realizada anteriormente.

Removendo um Patch

Para a remoção do patch, basta realizar o mesmo comando que foi feito para aplicar. Será questionado se realmente deseja realizar a remoção do patch ou aplicá-lo novamente. Podemos também indicar no comando explicitamente que iremos realizar uma operação de remoção do patch. Para tanto, a linha de comando ficaria como a seguir.

# bunzip2 -c patch-versão-do-patch | patch -p1 -R

Da mesma maneira que quando aplicamos um patch, durante sua remoção também podemos obter algumas rejeições que serão registradas nos arquivos “.rej”.

Objetivo 4: Customizar um Kernel

Você pode aplicar diferentes tipos de customizações para seu kernel. A simples customização é, claro, para melhorar a configuração do kernel. Além dos patches lançados pelos mantenedores do kernel, existem muitos outros patches de terceiros. Alguns desses são desenvolvidos por hackers do kernel e têm a finalidade de adicionar novos recursos de segurança (ou não) no kernel. Estes patches de terceiros, podem ser disponibilizados em um formato diferente do visto. Para aplicá-los, basta o comando abaixo.

# zcat patchdeterceiro-versão-do-patch | patch -p1

Finalizando

Bem, é isso aí, este primeiro tópico sobre a prova 201 foi discutido em quase sua totalidade. Caso alguém possua dúvidas ou críticas a realizar, fiquem a vontade! 🙂

Em breve voltarei para falar do assunto do próximo tópico: Sistema de Inicialização.

Até a próxima!

14 comentários sobre “Aula 1 – Prova 201 – Kernel Linux

  1. Israel Junior disse:

    Parabens pela iniciativa…

    Com certeza vou dar uma lida nesses artigos. To querendo tirar minhas certificações LPI mas faltava estimulo pra estudar. Quando realizar as provas conta o resultado (se tava facil, dificil, etc) =)

  2. Mayck Xavier disse:

    Boa… Gostei da iniciativa… Estou fazendo o mesmo no meu blog, porém para a prova 101… Estou tendo dificuldades pra postar por causa do tempo muito apertado (só sentei no pc agora pra ver os emails). Vou ler e tentar salvar seus posts pra quando eu estiver estudando pra 202.
    T+
    Fique com Deus

  3. Toti disse:

    Eu fiz a lpic-2, e estudei pelo material da ibm..

    O material foi só uma referencia mesmo.. Nem tudo que estava lá caiu na prova.. E algumas coisas cairam na prova e nem foram referenciadas lá..

    [ ]´s

  4. Ronaldo Pacheco Wanzeller disse:

    Parabéns pela iniciativa, só complementando:

    – Tamanho máximo para a imagem zimage, segundo a documentação do kernel(/usr/src/linux/Documentation/i386/boot.txt) é 512k.

    – Tamanho máximo para a imagem bzimage, segundo tutorial do site da ibm, é 2.5 MB.

  5. ThigU disse:

    Olá Ronaldo,

    Valeu pela correção! Como estou seguindo muito um único livro como referência eu posso realmente cometer alguns deslizes como esse… vou corrigir e complementar no tópico!

    Valeu e até a próxima! 🙂

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *