Monthly Archives: November 2015

Introdução ao Linux Kernel

Próximo artigo da série: Introdução a módulos no Linux Kernel

Devido a escassez de conteúdo em português sobre o Linux Kernel eu resolvi começar uma série de artigos introdutórios sobre o Linux e programação para o mesmo. Como o Linux Kernel é um projeto bem grande, acaba sendo um pouco difícil e intimidador para novos programadores a se achegarem, já que o conteúdo dos artigos na internet são bem técnicos e em inglês.

O objetivo desta série é de servir como guia e introdução para novatos começarem a aprender sobre o Linux Kernel e, quem sabe assim, procurar mais a respeito e contribuir. 😉

Todos são bem-vindos aos estudos. Porém eu recomendo as seguintes habilidades para o maior proveito:

  • Esteja rodando alguma distribuição Linux;
  • Conhecimento intermediário em ciência da computação;
  • Conhecimento avançado (ou corajoso o suficiente) em C;
    • Eu digo isso porque quem não tem experiência com C irá se assustar com algumas coisas feitas no Kernel, como a implementação da estrutura de dados em pilha FIFO. 😎
  • Conhecimento avançado em inglês.
    • Você irá perceber que eu uso diversos links para mais informações em inglês.

O Que é o Linux?

O Linux é um Núcleo do Sistema Operacional (ou Operating System Kernel) do típo monolítico. “Apenas” isso e ponto. O sistema que você usa em seu Desktop, como Fedora, Ubuntu e outros são distribuições de um Sistema Operacional composto pelo Linux Kernel e muitos outros componentes do Sistema Operacional GNU, conseqüentemente o nome GNU/Linux. Outra distribuição que usa o Linux Kernel é o Android. E existem muitas e muitas outras. O importante entender é que o Kernel em si pode ser usado em qualquer Sistema Operacional, já que é apenas um  dos componentes (muito importante, por sinal).

Um ponto muito importante é que o Linux é licenciado sob a licença GPLv2. Isso garante a liberdade do Kernel e a do usuário, já que a licença obriga a que modificações sejam publicadas (idealmente reintegradas ao mainline) sob a mesma licença.

Como dito anteriormente, o Linux é monolítico. De forma simplificada, isto significa que o Kernel é executado num espaço chamado kernel-space (também chamado supervisor mode ou ring 0 da CPU) onde todo o código tem o maior nível de privilégio e acesso. Todo o seu código está em um bloco linear de memória e o acesso da API interna é sempre visível por todos os componentes internos. Isso tem suas vantagens e desvantagens. A principal vantagem é rapidez, já que não existe overhead entre comunicações de drivers de periféricos e outros sub sistemas do Linux. A grande desvantagem é a fragilidade do Kernel como um todo, já que um driver mal escrito pode matar o sistema inteiro (o temido Kernel Panic).

É interessante notar que o Linux suporta uma funcionalidade muito importante herdada dos Kernels do tipo microkernel: o suporte a módulos. Com o Linux é possível adicionar e remover módulos em tempo de execução. Será que isso o torna um sistema híbrido (meio monolítico e meio microkernel)? Não! Pois uma vez que o módulo é é adicionado ao Kernel, ele é incorporado da mesma forma como se ele fosse compilado diretamente no sistema. Ou seja, ele continua um sistema monolítico.

No próximo artigo escreveremos nosso primeiro módulo.

Como Obter o Linux

O código fonte do Linux é mantido num repositório git pelo Linus Torvalds. O repositório dele é o central (também chamado de mainline) do Linux, já que ele que realiza os ‘releases’ oficiais do Linux.

Você pode baixar os códigos fontes empacotados em .tar.xz no site kernel.org para cada versão do Linux, ou baixar o repositório como um todo, recomendado para quem quer desenvolver.

Vamos então baixar o repositório git do Linus no diretório ~/devel/linux, para isso execute o seguinte comando:

Pode ir tomar um café e assistir um filme porque vai demorar. O repositório atual para o v4.4-rc2 do Linus tem 2,5GB de tamanho depois de desempacotado, porém o download do repositório deve ser ~1GB. 😯

Mãos na massa

Agora vamos compilar e rodar um Kernel bem fresquinho.

Para facilidade de desenvolvimento, vamos usar o QEMU para rodar nosso Kernel em sua arquitetura nativa do seu computador. Muito provavelmente todos lendo este artigo estão rodando AMD64 (ou x86_64).

Agora no seu diretório de desenvolvimento, vamos compilar o Kernel usando o seu build system, KBuild. Para isso precisamos gerar um arquivo .config que irá conter todas as configurações do nosso Kernel. Essas configurações irão habilitar ou não funcionalidades do Kernel por dizer ao KBuild quais arquivos a compilar e quais -D MACROS devem ser passadas pro compilador (GCC) ao pre-processar os códigos fonte. O Linux já vem com diversas configurações para certas arquiteturas e máquinas pré-definidos, vamos usá-la por simplicidade.

Para gerar o .config para a arquitetura AMD64 execute:

O parâmetro ‘O‘ significa output. Eu gosto de usar o diretório ‘build‘ como a saída dos arquivos gerados pelo build system, assim deixando sua árvore de código fonte limpa.

Agora precisamos apenas compilar o Kernel com o comando (vai levar uns 3-5 minutos, dependendo da sua máquina, ou seja, dá tempo para ir ao banheiro tirar aquela água do joelho):

bzImage é a imagem do Linux (vmlinux) só que compactada usando o bzip2.  O parâmetro ‘-j4‘ é padrão do make . O número, neste caso 4, é o número de operações em paralelo que o make irá executar. O número ideal seria o mesmo número de CPUs disponíveis. Execute o commando  nproc  para retornar esse número.

Agora baixe o QEMU em seu sistema. Provavelmente sua distribuição já tem empacotado alguma versão recente.

No meu Fedora 23 eu precisei apenas rodar:

Para rodar o seu Kernel fresco, execute dentro do diretório que você baixou o Linux:

Se você viu um tipo similar de Kernel Panic, então tudo funcionou como deveria.

O Linux foi executado na máquina virtual e tentou ‘montar’ o root file system porém não conseguiu, gerando assim o erro. Parabéns! Você acabou de rodar a versão de desenvolvimento do Linux.

Ficamos por aqui no momento. No próximo artigo da série, iremos escrever nosso primeiro módulo do Kernel e rodar no QEMU. Por favor, caso tenha críticas e sugestões, fique à vontade em seus comentários.


Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.