Kernel e Internals

Linux embarcado com Buildroot e Yocto Project

• 6 min de leitura

Linux embarcado com Buildroot e Yocto Project
O Linux embarcado é uma versão otimizada do sistema operacional Linux, projetada para rodar em dispositivos com recursos limitados, como roteadores, câmeras IP, dispositivos IoT, equipamentos médicos e sistemas de automação industrial. Diferente de um desktop Linux, o sistema embarcado exige cross-compilação, boot customizado e um sistema de arquivos mínimo.

Linux embarcado com Buildroot e Yocto Project

1. Introdução ao Linux Embarcado

O Linux embarcado é uma versão otimizada do sistema operacional Linux, projetada para rodar em dispositivos com recursos limitados, como roteadores, câmeras IP, dispositivos IoT, equipamentos médicos e sistemas de automação industrial. Diferente de um desktop Linux, o sistema embarcado exige cross-compilação, boot customizado e um sistema de arquivos mínimo.

Os principais desafios incluem:
- Gerenciamento eficiente de memória RAM e armazenamento flash
- Configuração de bootloaders como U-Boot ou GRUB
- Criação de toolchains cruzadas para arquiteturas como ARM, MIPS ou RISC-V
- Manutenção de dependências entre pacotes

Duas ferramentas dominam o cenário de construção de sistemas Linux embarcados: Buildroot e Yocto Project. Ambas automatizam a compilação cruzada, a geração de imagens e a configuração do kernel, mas possuem filosofias e complexidades distintas.

2. Fundamentos do Buildroot

Buildroot é um sistema de build simples e direto, baseado em Makefiles. Sua estrutura é organizada em:
- configs/: arquivos de configuração pré-definidos para placas populares
- package/: receitas de compilação para cada pacote
- toolchain/: definições da cadeia de ferramentas (gcc, uClibc, glibc)

O fluxo de trabalho básico é:

# Baixar e extrair o Buildroot
wget https://buildroot.org/downloads/buildroot-2024.02.tar.gz
tar -xzf buildroot-2024.02.tar.gz
cd buildroot-2024.02

# Configurar para Raspberry Pi 3
make raspberrypi3_defconfig

# Personalizar configurações (opcional)
make menuconfig

# Compilar o sistema (pode levar horas na primeira vez)
make

Após a conclusão, a imagem será gerada em output/images/. Para criar um sistema mínimo para Raspberry Pi, você pode usar:

# Exemplo de configuração mínima via menuconfig
# Target options -> Target Architecture -> ARM (little endian)
# Toolchain -> C library -> glibc
# System configuration -> System hostname -> meupi
# Kernel -> Linux kernel -> Enable
# Target packages -> Show packages -> marcar busybox e dropbear (SSH)

3. Personalização com Buildroot

Para adicionar pacotes customizados, você pode usar overlays rootfs. Crie uma pasta board/meupi/rootfs-overlay/ e coloque arquivos que serão copiados para a raiz do sistema.

Exemplo de adição de um script de inicialização:

# board/meupi/rootfs-overlay/etc/init.d/S99meuapp
#!/bin/sh
case "$1" in
  start)
    echo "Iniciando minha aplicação"
    /usr/bin/meuapp &
    ;;
  stop)
    killall meuapp
    ;;
esac

Configure o Buildroot para usar o overlay:

# No menuconfig:
# System configuration -> Root filesystem overlay directories
# Adicionar: board/meupi/rootfs-overlay

Para otimizar o tamanho da imagem, use make menuconfig e desabilite pacotes desnecessários. No Target packages, desmarque busybox se você usar apenas comandos específicos. Ajuste também o kernel removendo drivers não utilizados via make linux-menuconfig.

4. Introdução ao Yocto Project

Yocto Project é um framework mais complexo, baseado em BitBake (um sistema de build similar ao Make) e OpenEmbedded. Seu componente principal é o Poky, que fornece as receitas básicas e o ambiente de build.

A estrutura é organizada em layers (camadas) que contêm recipes (receitas). Cada recipe descreve como baixar, configurar, compilar e instalar um pacote.

Fluxo de trabalho básico:

# Clonar o Poky
git clone git://git.yoctoproject.org/poky.git
cd poky

# Inicializar o ambiente de build
source oe-init-build-env build-rpi

# Configurar para Raspberry Pi 3 (editar conf/local.conf)
# MACHINE = "raspberrypi3"
# Adicionar layer meta-raspberrypi

# Construir imagem mínima
bitbake core-image-minimal

A imagem gerada estará em tmp/deploy/images/raspberrypi3/. O Yocto gera múltiplos artefatos: kernel, bootloader, sistema de arquivos raiz (ext4, squashfs, etc.) e image completa para gravação em SD.

5. Personalização Avançada com Yocto

Criar um layer customizado permite adicionar suas próprias receitas e configurações sem modificar as camadas oficiais.

# Criar estrutura do layer
mkdir -p meta-meupi/recipes-meupi/meuapp
cd meta-meupi

# Criar conf/layer.conf
# LAYERDEPENDS_meta-meupi = "core"
# LAYERSERIES_COMPAT_meta-meupi = "scarthgap"

# Criar recipe (recipes-meupi/meuapp/meuapp_1.0.bb)
SUMMARY = "Minha aplicação embarcada"
LICENSE = "MIT"
SRC_URI = "file://meuapp.c"
S = "${WORKDIR}"

do_compile() {
    ${CC} meuapp.c -o meuapp
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 meuapp ${D}${bindir}
}

Adicione o layer ao bblayers.conf:

# bblayers.conf
BBLAYERS ?= " \
  /path/to/poky/meta \
  /path/to/poky/meta-poky \
  /path/to/poky/meta-yocto-bsp \
  /path/to/meta-raspberrypi \
  /path/to/meta-meupi \
  "

Para configurar o kernel, use o comando bitbake linux-raspberrypi -c menuconfig. Para o bootloader, edite as variáveis em local.conf:

# Configurar U-Boot
PREFERRED_PROVIDER_u-boot = "u-boot"
UBOOT_CONFIG = "rpi_3_defconfig"

6. Comparação Prática: Buildroot vs. Yocto

Aspecto Buildroot Yocto Project
Curva de aprendizado Baixa (horas) Alta (semanas)
Tempo de build inicial 10-30 min 1-4 horas
Tamanho da imagem 2-10 MB 10-50 MB
Flexibilidade Média Alta
Suporte a pacotes ~2000 ~10000
Reproducibilidade Parcial Completa

Casos de uso recomendados:
- Buildroot: Projetos pequenos e médios, prototipagem rápida, dispositivos com recursos muito limitados (ex: roteador WiFi, sensor IoT).
- Yocto Project: Sistemas complexos, produtos comerciais com requisitos de certificação, suporte a múltiplas arquiteturas e atualizações OTA.

7. Boas Práticas e Considerações Finais

  • Versionamento: Mantenha os arquivos de configuração (buildroot.config ou local.conf) no Git. Use tags para marcar versões de release.
  • Reproducibilidade: No Yocto, use BB_NO_NETWORK = "1" após o primeiro build para garantir que nenhuma dependência externa mude. No Buildroot, congele as versões dos pacotes via BR2_PACKAGE_*_VERSION.
  • CI/CD: Integre o build com Jenkins ou GitLab CI. Exemplo de pipeline Yocto:
# .gitlab-ci.yml
build:
  script:
    - source oe-init-build-env
    - bitbake core-image-minimal
  artifacts:
    paths:
      - tmp/deploy/images/
  • Testes automatizados: Use QEMU para testar a imagem sem hardware real. No Buildroot: make run. No Yocto: runqemu qemuarm.
  • Comunidades: Participe das listas de discussão (buildroot@buildroot.org, yocto@yoctoproject.org) e fóruns como o Stack Overflow.

Referências

💬 Comentários
Mais em Kernel e Internals