Manual

do

Maker

.

com

Cross-compiling para a Omega

Cross-compiling para a Omega

Existem muitas opções de linguagens para a Omega e dentre elas, prefiro muito utilizar Python devido à simplicidade. Mas se por alguma razão você quiser mesmo programar em C, a melhor opção pode ser utilizar cross-compiling.

O que é cross-compiling

Em diversos casos, já fazemos isso sem nos dar conta. Quando geramos um arquivo binário para uma plataforma diferente da que estamos utilizando, chamamos de compilação cruzada. É o caso do Arduino, onde geramos binários para AVR. Mas fazê-lo para outras plataformas como ARM ou MIPS já dá um pouco mais de trabalho.

Nesse artigo demonstro a compilação do kernel para o Raspberry Pi.

Nesse outro mostro a virtualização de um sistema compilado para ARM utilizando o QEmu.

Se quiser configurar uma IDE para fazer cross-compiling para Raspberry, eis o artigo.

Escrevi também como fazer a compilação em um ambiente virtual para o Raspberry aqui.

Se você reparar, nos artigos supracitados existem algumas diferenças; uns são virtualizados, outros compilações no sistema nativo. Existem quatro tipos de toolchains diferentes; a nativa, cruzada, hibrida e canadian. Explico mais a respeito nesse artigo.

Alguns sistemas são gerados a partir de ferramentas como o buildroot. Eu mostrei como gerar um pacote para o buildroot nesse artigo.

Antigamente já tinhamos diversas opções de construção de firmwares, mas a maioria era bastante complexa. Já tive que trabalhar em algumas plataformas cujo sistema era distribuido em forma binária, ainda que utilizando Linux. Ainda existem plataformas assim, mas é uma verdadeira porcaria ficar à mercê de uma empresa, porque o desenvolvimento é lento, custoso e arriscado para seu projeto. Não vou me estender sobre o assunto de embarcados, mas recomendo 3 livros que tenho e os considero ótimos:

  • Building Embedded Linux Systems
  • Embedded Linux Primer
  • Embedded Linux System - Design and Development

Daí, tive tanto problema com essa questão de firmware que acabei tendo que descompilar alguns firmwares. Por isso, um dia resolvi escrever a respeito. O procedimento você vê aqui.

Certa vez mostrei como modificar um sistema live CD, que é o mesmo processo até hoje. Se quiser experimentar essa divertida tarefa, dê uma olhada nesse artigo.

Tenho também uma série importante sobre sistemas embarcados.

E pra deixa essa coleção sobre embarcados mais completa, vamos ver hoje o cross-compiling para MIPS, mais especificamente para o Onion Omega.

Material necessário

Adivinha? Se ainda não adivinhou, apenas siga esse link.

Cross-compiling para a Omega

O sistema Linux da Omega é baseado no OpenWRT e é chamado de LEDE. Vamos utilizar a base dele para fazer cross-compiling, de modo a aproveitar os recursos de uma arquitetura x86 ou AMD64 - e por falar em AMD64 - essa arquitetura se refere a qualquer processador baseado em x86, seja Intel ou AMD. A arquitetura x86 de 64 bits foi criada pela AMD, por isso se você olhar na árvore de arquiteturas do kernel do Linux, vai ver que tem x86 e ia64. Antigamente tinha também amd64, que agora está integrado à árvore do x86. Bem, vi durante um bom tempo a galera compilando ia64 pensando que se tratava de "Intel e AMD 64". Mas ia64 é a arquietura Itanium da Intel, diferente dos computadores pessoais x86. O nome amd64 fazia o pessoal pensar que se tratava de uma compilação exclusiva para os processadores da AMD.

Mas não se preocupe, não é necessário ter conhecimento sobre kernel para fazer essa compilação cruzada, apenas quis fazer o esclarecimento sobre as arquiteturas.

Configurando a base do sistema

O sistema de construção utilizado para a cross-compilação pode criar firmwares completos e pacotes para serem instalados via opkg. Minha humilde opinião a respeito é que, se pretende experimentar a cross-compilação, fique apenas na construção de binários para a Omega. Erros na construção do firmware podem acabar definitivamente com sua Omega. Já qualquer erro na construção de binários não afetarão o funcionamento do sistema.

Conforme a documentação da Onion, existem alguns pacotes que precisam previamente serem instalados. Faça-o:

sudo apt-get install -y git wget subversion build-essential \
libncurses5-dev zlib1g-dev gawk flex quilt git-core unzip \
libssl-dev python-dev python-pip libxml-parser-perl

A barra invertida é só quebra de linha, pode copiar e colar no terminal que vai funcionar normalmente. Feita a instalação, agora clone o repositório do sistema:

git clone https://git.lede-project.org/source.git

Depois de clonado, algumas configurações prévias são necessárias. Para isso, entre no diretório sources e execute:

cd source
make menuconfig

Um menu em curses se abrirá. Ajuste alguns parâmetros:

  • Em Target System, selecione MediaTek Ralink MIPS
  • Em Subtarget, selecione MT76x8****based boards
  • Em Target Profile, selecione Multiple Devices
  • No novo ítem que aparecerá, selecione Target Devices
  • Em Target Devices, selecione Onion Omega2Onion Omega2+. Repare que tem configuração também para a VoCore, que trataremos em outro artigo.
  • Saia e salve a configuração.

Agora o construtor está configurado para criar a toolchain, firmware e pacotes compatíveis com a Omega e Omega2 Plus. Agora faça acontecer. Se tiver múltiplos núcleos na sua máquina, aproveite a opção -j, senão use apenas make:

make -j4 V=s

Não execute como root porque vai dar um erro no mknod e a compilação será interrompida. Faça o processo como um usuário comum.

Esse processo é assustadoramente lento, podendo levar horas, dependendo do computador que estiver utilizando, mas uma vez tendo o ambiente para compilação cruzada, seus programas serão compilados tão rápido quanto um programa nativo.

Se "tudo der certo e nada der errado", essa compilação "acaba no fim", sem muita (ou nenhuma) verbosidade.

Agora já podemos compilar nossos próprios programas.

Toolchain

O compilador agora está no diretório staging_dir, com 2 níveis; o primeiro nível é a versão da toolchain e no segundo nível temos bin, incluide e lib. Em bin se encontra o compilador, em include estão os headers que você pode utilizar em seus programas e em lib as bibliotecas padrão.

Target

Nesse nível primário se encontram todas as coisas necessárias para a construção do sistema. Os includes dentro do diretório staging_dir contém os cabeçalhos que serão utilizados em nossa compilação. Em lib estão os objetos compartilhados para linking com nossa compilação.

Exemplo

Primeiro, façamos uma breve modificação em nossa compilação. Use novamente o comando make menuconfig e vá até o menu Libraries e inclua a libugpio:

ugpio-makemenuconfig.webp

Saia e salve a mudança. Então compile mais uma vez (não se preocupe, só será compilada a diferença, apesar de você ver um montão de coisas passando na tela):

make -j4 V=s

Um exemplo pronto, utilizando um Makefile pode ser baixado do git da Onion:

git clone https://github.com/OnionIoT/c-cross-compile-example.git

Edite o script xCompile.sh e corrija a versão do compilador para a que você está utilizando:

Para compilar o exemplo, use:

sh xCompile.sh -buildroot /path/to/source -lib ugpio

Lembre-se que pode haver mudanças na estrutura de diretórios e nomes de arquivos. Eu tive que fazer várias modificações, mesmo me baseando na documentação, que está um pouco defasada.

Usando uma imagem Docker

Esse é o caminho mais simples, mas se eu colocasse no começo do artigo, você certamente não leria até o final. Existe uma imagem oficial prontinha pra cross-compiling. É só baixar e usar. Seu nome é **onion/omega2-toolchain.**Se quiser optar por ela mas não tem nenhuma noção de docker, recomendo esse artigo. Leia a parte de docker e não se preocupe com o restante.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.