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.

  • Que maldade, você parou na melhor parte kkkkk Vou esperar ansiosamente o próximo artigo. Você tem data para isso?

    • Felipe Tonello

      Oi Willian, eu pretendo publicar mais um semana que vêm. Mas pode ser que atrase pois eu quero ter tempo para escrever algo de qualidade e tentar ser didático ao mesmo tempo. Abraços.

      • Entendi. Mas, mesmo assim parabéns pelo trabalho e espero o próximo! o/

  • Leo Melo

    Ótima iniciativa. Parabéns!

  • Parabéns pelo artigo Felipe!

  • Antony

    Muito bom, vou acompanhar.

  • Igor Tavares

    Sensacional, muito bom seu trabalho!
    Obrigado por compartilhar seu conhecimento.

    Obs: No último parágrafo você escreveu “memento”.

    • Felipe Tonello

      Valeu pelo comentário e pelo conserto no typo! Impressionante é que eu li e reli este artigo umas 20 vezes e cada vez achava um erro. hehehe

      • Igor Tavares

        Opa! Não esquenta, esse tipo de erro é insignificante perto da qualidade do conteúdo.

        Fique a vontade para apagar o comentário com a correção.

        Abraços.

        • Felipe Tonello

          Que isso, faz parte! =D

  • Oswaldo Fratini Filho

    Vou acompannhar seus artigos por aqui Felipe. Parabéns pela iniciativa!

  • Felipe Bandeira

    Show demais!!!!! Estou esperando a parte 2 🙂

  • Joniel Gallo Sturião

    Opa, sensacional!! Muito bom mesmo!

    Parabéns pelo artigo e obrigado por compartilhar tão preciosa informação!

    Obrigado Felipe!

  • Felipe existe o http://minimal.linux-bg.org/ que faz tudo isso, o difícil é reconhecer o hardware e transformar o kernel em um ISO bootável…

    seria interessante ensinar como “remixar” o kernel do Ubuntu que é mais out-of-the-box, mas se conseguir mostrar como instalar o Tiny C Compiler no “mininal linux” já ganhou um fã! =)

    • Felipe Tonello

      Oi.

      Como assim esse minimal linux-bg faz tudo isso? O que seria “remixar” o Kernel do Ubuntu? Instalar o Tiny C Compiler no “minimal linux”?

      Vou ser sincero que não entendi seu comentário. 😉

      Sobre essas distribuição mínimas, eu vou acabar usando alguma coisa nos próximos artigos já que irei precisar de um rootfs mínimo com shell para poder me comunicar com o Kernel via user-space.

      • remix = variação do ubuntu, tipo essa http://www.ubuntu-mini-remix.org/

        o tiny c é um compilador de c mais simples e rápido que o gcc http://bellard.org/tcc/

        legal, seguindo já =)

        • Felipe Tonello

          Sim. O ponto importante é que tudo isso não é relacionado ao Linux em si. O que você comentou é uma distribuição Linux, um ponto que não vou tocar. Os artigos desta série é relacionado ao Linux Kernel *apenas*.
          Mas obrigado pelas referências. 😉

      • tentei “empacotar” outros programas junto no minimal mas não rolou =

        se conseguisse empacotar um compilador de c seria fácil rodar outras linguagens entende?

  • Muito bom.
    Parabéns pelo artigo

  • Glaucio Fonseca

    Sensacional mano tá de parabéns

  • Pingback: Introdução a módulos no Linux Kernel | Hacking Linux Thoughts()

  • Sidnei Marques

    muito bom maninho!!!

  • Glaucio Fonseca

    Muito bom artigo Felipe meus parabéns. É isso que faz a diferença.