Compilar o kernel do Raspbian

Sistemas embarcados (http://www.glyn.com)
Sistemas embarcados (http://www.glyn.com)

Compilar o kernel para o Raspberry

Compilar o kernel do Raspbian pode ser útil para adicionar ou remover recursos ao seu Raspberry. Nesse outro artigo mostrei como configurar um ambiente virtual para compilação, de forma a aproveitar o processamento de uma plataforma x86 invés de fazê-lo diretamente na ARM. Também citei esse outro artigo, onde mostro os diversos modos de compilação possíveis. Dessa vez vou mostrar como fazê-lo nessa máquina virtual que criamos no post anterior e também como fazer a compilação cruzada ou, “cross-compilling”.

Processo para compilação local ou na VM

O processo é o mesmo para compilação nativa na board ou compilação nativa na máquina virtual que criamos no artigo anterior. Devo reafirmar a necessidade da leitura do post anterior devido às dependências que você precisará instalar antes de iniciar o processo de compilação. Mas aqui deixo uma dica; você pode fazer um dump do sistema que você tem rodando em sua RPi e então fazer a compilação na VM, desse modo você ganha em processamento. Posteriormente, você pode jogar essa imagem de volta para o cartão! Claro que seria melhor ter um segundo cartão para testar se a imagem não foi corrompida por qualquer razão, mas se desejar fazer esse processo, é bastante simples. Primeiro, a cópia do cartão para seu notebook:

Troque essa variável $CARTAO pelo dispositivo. Para identificar o dispositivo, antes de inserí-lo no computador, faça:

Se o messages estiver desabilitado em seu sistema, então verifique o dispositvo adicionado ao sistema após inserí-lo no computador.

Nas últimas linhas haverá alguma indicação do dispositivo inserido. Supondo /dev/sdb, basta substituir $CARTAO por sdb.

Atendidas as necessidades, vamos ao próximo passo.

Baixar os fontes do kernel





Obviamente é o primeiro passo, considerando ser essa a nossa “matéria prima”. Pegue-a então:

Preparar o .config

Antes de compilar, você precisa preparar o arquivo .config, que conterá as informações necessárias do que deve ser habilitado ou desabilitado no kernel. Uma das formas de fazê-lo é copiar o arquivo de configuração através da instalação dos fontes do kernel através do repositório. Também mostrei isso no artigo anterior, leia-o se ainda não o fez. A outra maneira de fazer esse arquivo de configuração inicial é criando-o com as configurações padrão ou através de uma chamada especial para o Raspberry. Essa chamada varia apenas entre o RPi 1 e os demais RPi.

Para o Raspberry Pi 1:

Para o Raspberry Pi 2 e 3:

Repare que kernel7 é o nome do kernel que utilizamos pra fazer o boot da nossa VM do post anterior. Isto porque com o parâmetro ‘-M’ utilizado na chamada do QEmu foi indicada que a máquina emularia um Raspberry Pi 2.

Esse processo eu estou fazendo em uma RPi 3, portanto sigo com o segundo comando.

Configurar as opções do kernel

Após criada a configuração, podemos incluir ou excluir algo através de um confortável menu gráfico chamando o comando:

Essa opção só estará disponível se você tiver instalada a ‘libncursesw5-dev’. E para instalá-la, use o apt-get:

Iniciar a compilação

Agora o processo de compilação é bastante simples e discorro em seguida.

A primeira linha tem muita informação importante pra quem não tem experiência com compilação de kernel ainda. Primeiro, o parâmetro ‘-j4’ divida a tarefa pelo número de processadores indicados, o que certamente é mais eficiente em caso de compilação nativa na RPi. Se fosse uma Banana Pi M3, esse parâmetro poderia ser até ‘-j8’!

O parâmetro zImage significa que o kernel é pequeno o suficiente para ser colocado em memória baixa (até 640K). Em plataformas x86 o comum nos dias atuais é ver o uso do bzImage, que ao contrário do que muitos acham, não se trata de uma compressão do kernel com bz, mas sim uma referência à ‘big zImage’. Eu trato desse assunto nesse outro artigo sobre embarcados.

O make também recebe o parâmetro ‘modules’ para criação dos módulos e o parâmetro ‘dtbs’, que é um arquivo blob do device tree. E o que é o device tree? – Eu pergunto, eu respondo, mas se você não entende o conceito do initrd, sugiro uma leitura nesse artigo que escrevi sobre sistemas embarcados.




Você já reparou que o Raspbian não tem initrd? Pois é, então como fazer o preload das necessidades para o devido reconhecimento de hardware, naquilo que precisa ser carregado tão logo o kernel levante? É pra isso que existe o device tree, que tem um comportamento semelhante ao initrd, exceto que o initrd carrega todo um sistema raiz e depois migra para o disco, mas enfim, esse parâmetro não deve ser esquecido. Se filosofarmos um pouco mais, podemos também dizer que o device tree binary pode lembrar também a BIOS, que não existe nessas boards, por isso que se não tiver o sistema no cartão, sequer há um sinal que possa ser interpretado; toda a inteligência vem do software externo.

A primeira linha pode ser executada como usuário comum porque toda a compilação é feita localmente, mas adiante dela as outras linhas são precedidas pelo comando su. Se preferir, inicie a sequência de comandos com ‘sudo su’ e dispense sua chamada adiante:

Com isso, você já concluiu a tarefa. Agora se pretende um outro método, sigamos.

Compilação cruzada ou Cross-compilling

Se você usa Windows invés de Linux, talvez você já tenha aí uma máquina virtual com o pinguim instalado e pode ser mais simples pra você utilizar essa máquina invés de criar uma VM ARM. Por outro lado, se você tem uma máquina rodando Linux nativamente, o desempenho será consideravelmente maior fazendo compilação cruzada do que fazendo-a através de virtualização, por isso achei importante descrever mais esse modo para que você possa construir seu kernel.

Preparação do ambiente

Para tal, você precisará de um toolchain, que é o conjunto de ferramentas que permitirão gerar binários para uma plataforma diferente da que se está utilizando para a compilação. Felizmente, a propria fundação Raspberry oferece um git para facilitar as coisas, de modo que o primeiro passo será baixar as ferramentas:

Ao término, você poderá mover o diretório para um lugar comum onde pretenda deixar a ferramenta. O mais comum é copiar para /opt/, mas você pode deixar até em seu home, isso é indeferente, uma vez que será necessário colocar o diretório binário no path do sistema:

Inclua também a linha do path ao seu aruivo .bashrc (no seu home) caso você compile como usuário. Porém, ainda que digitar ‘sudo su’ antes da compilação, basta digitar ‘source /home/seuUsuario/.bashrc’, ou adicione a linha de path também ao .bashrc em /root.

Mais uma vez, você pode baixar o kernel como mostrado mais acima.

Compilando





E para compilar, é tão fácil quanto nativamente, agora que você já tem um toolchain para gerar o binário no formato certo. O que você fará de diferente é indicar um valor à variável de cross-compilação (agora misturei inglês com português, ficou chique).

Para RPi 1:

E para o RPi 2 ou 3:

Não é necessária muita explicação. Como você pode ver, a mudança no make está relacionada ao binário do cross-compiller, indicação da arquitetura para a qual será gerada o binário e mais uma vez, indica-se qual o processador.

A opção ‘-j’ para o make continua sendo válida.

Copiar as coisas para o cartão

Se você optou por compilação cruzada, o lado negativo começa agora. Dá um pouco de trabalho pra copiar tudo para o cartão. Uma das opções é fazer uma cópia recursiva do diretório de compilação do kernel para o SD. Daí você faz o boot no sistema e então executar os comandos:

Onde a variável $KERNEL corresponde a um dos valores citados lá no começo desse artigo. Antes de tentar montar o cartão e acessar o sistema, é seguro fazer um dump do SD para ter um backup. Depois, haja como quiser, mas eu recomendo que se faça como descrito no post anterior para acessar os dados de uma partição a partir da imagem.

A outra opção é mais prática em relação ao tempo, porque copiar o diretório para um cartão e depois executar a instalação leva um tempinho.

Se já tiver feito o backup ou se decidir proceder qualquer execução diretamente no cartão SD, você precisará dispor das duas partições para a cópia, portanto, crie 2 diretórios temporários para o acesso ao cartão:

Supondo que o dispositivo relacionado ao seu cartão SD seja /dev/sdb, monte as duas partições do cartão, já proceda com a instalação dos módulos e a cópia dos dados relacionados ao boot:

Agora você já pode dr boot em seu próprio kernel! Em outro artigo vou mostrar uma coisa legal que qualquer um pode querer implementar para deixar o kernel mais bacana, acompanhe o nosso site!

Inscreva-se no nosso newsletter, alí em cima à direita e receba novos posts por email.

Siga-nos no Do bit Ao Byte no Facebook.

Prefere twitter? @DobitAoByte.

Inscreva-se no nosso canal Do bit Ao Byte Brasil no YouTube.

Nossos grupos:

Arduino BR – https://www.facebook.com/groups/microcontroladorarduinobr/
Raspberry Pi BR – https://www.facebook.com/groups/raspberrybr/
Orange Pi BR – https://www.facebook.com/groups/OrangePiBR/
Odroid BR – https://www.facebook.com/groups/odroidBR/
Sistemas Embarcados BR – https://www.facebook.com/groups/SistemasEmbarcadosBR/
MIPS BR – https://www.facebook.com/groups/MIPSBR/
Do Bit ao Byte – https://www.facebook.com/groups/dobitaobyte/

Próximo post a caminho!

Agregador de Links - Loucuras da Net

Comments

comments

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.