1 pontos por GN⁺ 21 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Yocto não é uma distribuição, mas uma ferramenta para montar sua própria distribuição Linux, e é difícil tratá-lo como opção padrão se você não precisa desse nível de controle
  • Uma distribuição própria significa manutenção própria, incluindo responsabilidades regulatórias como a CRA e atualizações de segurança durante todo o ciclo de vida do produto
  • Adotar Yocto envolve builds de várias horas, diretórios de build com mais de 100 GiB, uma curva de aprendizado de várias semanas e camadas BSP com qualidade inconsistente
  • Se você só precisa de uma base Linux robusta para executar aplicações, Debian com ferramentas de imagem como mkosi, ELBE e debos pode ser suficiente com muito menos trabalho específico de projeto
  • Yocto só vence quando há forte customização, restrições de tamanho ou tempo de boot, exclusões por licença e suporte sólido de Yocto por parte do fornecedor; em caso de dúvida, uma distribuição existente é melhor

O que o Yocto realmente é e por que costuma virar a escolha padrão

  • Yocto não é uma “distribuição Linux Yocto”, mas um conjunto de ferramentas para criar sua própria distribuição Linux
  • O Yocto Project também fornece a distribuição de referência Poky, composta por bitbake, openembedded-core e meta-yocto
  • O Yocto permite montar com precisão o sistema Linux necessário para projetos embarcados
    • É possível compilar todo o espaço de usuário para a CPU de destino
    • É possível aplicar patches a qualquer componente
    • É possível ativar ou desativar recursos em cada receita
    • É possível fixar ou alterar todas as versões
  • Muitos fornecedores de SoC e parceiros de hardware oferecem camadas BSP (Board Support Package) prontas para uso, criando um ponto de partida que funciona no hardware real
  • Por causa dessa combinação de flexibilidade e suporte de fornecedores, o Yocto vira a escolha padrão, mas, se você não precisa de tanto controle, o custo pode ser maior do que o benefício

Uma distribuição própria significa manutenção própria

  • Regulamentações como o Cyber Resilience Act (CRA) exigem que o fornecedor do produto mantenha seguro o software distribuído e forneça atualizações de segurança durante toda a vida útil do produto
  • Uma release comum do Yocto é mantida por cerca de 7 meses, até a próxima release
  • A partir do Yocto 5.0 Scarthgap, pela política atual, releases LTS recebem atualizações por até 4 anos
  • Uma release do Yocto é composta por um conjunto de receitas bitbake com versões e metadados específicos, além da distribuição de referência Poky
  • Durante o período de manutenção, os mantenedores do Yocto aplicam correções de bugs e segurança aos componentes e ao Poky, e as correções dos componentes normalmente são retroportadas das versões upstream mais recentes
  • Em produtos reais, é comum não usar o Yocto exatamente como ele vem, mas fazer mudanças como:
    • aplicar patches não triviais ou alterações locais a alguns componentes
    • incluir componentes adicionais que o Yocto não fornece
    • atualizar ou fixar versões para receber correções ou manter um estado conhecido como bom
  • A cada nova release de manutenção do Yocto, é preciso verificar se as mudanças locais continuam sendo aplicadas de forma limpa sobre o novo estado
  • Como os componentes adicionados ou fixados não são conhecidos pelos mantenedores do Yocto, também é preciso verificar por conta própria se eles continuam recebendo correções
  • Se você usa o Poky quase sem alterações, vale reconsiderar por que precisa de Yocto

Kernel Linux e dependência do fornecedor

  • O Yocto fornece e mantém o kernel Linux como parte de cada release, mas é raro usá-lo sem modificações em um produto real
  • Normalmente é preciso ao menos aplicar patches do fornecedor e usar um kernel suficientemente novo, com os drivers e correções necessários
  • Quando se inclui até o rastreamento de CVEs, só o kernel já se torna uma grande carga de manutenção, independentemente de usar Yocto ou não
  • Para controlar essa carga, recomenda-se construir sobre um kernel LTS do kernel.org e manter todas as mudanças em uma fila de patches bem organizada
  • Para acompanhar correções de segurança, a prática é migrar para novas releases stable e reaplicar a fila de patches
  • Como o kernel.org mantém kernels LTS por vários anos, em geral a fila de patches se aplica de forma limpa e o trabalho real só aparece ao migrar para uma nova release LTS
  • Dependendo da configuração e dos requisitos de segurança, os mesmos princípios se aplicam ao bootloader, que também costuma ter muitos elementos específicos do fornecedor
  • Manter diretamente o kernel fornecido pelo fornecedor em geral é uma má ideia
    • kernels de fornecedor muitas vezes ficam anos atrás do kernel.org
    • recebem poucas ou nenhuma atualização
    • deixam passar a maior parte das correções de segurança

O custo de adotar Yocto

  • Escolher criar uma distribuição própria exige tempo real de engenharia
  • Tempo de build

    • O Yocto compila praticamente tudo a partir do código-fonte
    • Mesmo um build limpo de uma imagem além do nível mais simples leva várias horas em uma workstation rápida
    • sstate-cache e um DL_DIR compartilhado aceleram builds repetidos, mas até pequenas mudanças em receitas podem invalidar grande parte do cache
  • Custo de disco e CI

    • Um diretório de build do Yocto cresce facilmente para mais de 100 GiB
    • Runners de CI precisam de armazenamento suficiente e de uma forma de compartilhar sstate entre jobs
    • Espelhar sstate e DL_DIR reduz a dor, mas essa infraestrutura também precisa ser operada por você
  • Curva de aprendizado

    • Há muito o que aprender: receitas bitbake, camadas, camadas dinâmicas, classes, overrides, arquivos bbappend, PACKAGECONFIG, a diferença entre DEPENDS e RDEPENDS e mais
    • Colocar um engenheiro em dia com a base de código do Yocto leva semanas, não dias
  • Variação de qualidade nas camadas BSP

    • Alguns fornecedores de SoC fornecem camadas BSP limpas e bem mantidas
    • Outros entregam camadas meta-vendor que fixam kernels ou bootloaders de 5 anos atrás, colocam receitas específicas de máquina na camada errada e quebram a cada atualização do Poky
    • Um BSP que parece um bom ponto de partida pode acabar sendo a pior parte do build
    • Esses fatores não são motivo para evitar Yocto por si só, mas são motivo para confirmar antes da adoção se ele é realmente necessário

Alternativa: reutilizar uma distribuição consolidada

  • Se você só precisa de uma base Linux robusta para executar aplicações, uma distribuição existente como Debian GNU/Linux resolve grande parte do mesmo problema com muito menos trabalho específico de projeto
  • O Debian atualmente oferece cerca de 70.000 pacotes binários
  • As arquiteturas suportadas incluem amd64, i386, arm64, armhf, riscv64, ppc64el e outras
  • Muitos SoCs provavelmente conseguem executar binários Debian diretamente, sem recompilação
  • O Debian não é apenas uma distribuição que fornece um espaço de usuário moderno com systemd, udev e dbus
  • O arquivo da distribuição também inclui elementos para criar sistemas Linux pequenos com init no estilo SysV ou baseados em BusyBox
  • É possível escolher uma base enxuta e instalar apenas os pacotes necessários para o produto, aproveitando ainda o trabalho dos mantenedores de pacotes do Debian

O modelo de manutenção do Debian

  • O Debian stable recebe atualizações de segurança da Debian Security Team por cerca de 3 anos
  • Depois disso, o projeto comunitário Debian LTS estende o suporte por cerca de 2 anos adicionais nas arquiteturas mais comuns
  • Na prática, isso permite cerca de 5 anos de suporte por release, nível semelhante ao do Yocto LTS, mas com muito menos trabalho específico de projeto
  • Para receber correções mais recentes, basta pegar os pacotes Debian mais novos e recriar a imagem
  • A natureza do trabalho é bem diferente de fazer backport manual de patches upstream no Yocto ou verificar novamente se mudanças locais continuam se aplicando sobre releases de manutenção

Como imagens embarcadas são montadas

  • Uma imagem embarcada baseada em Debian não significa iniciar o SoC por um pendrive USB e rodar o instalador do Debian
  • A abordagem é gerar uma imagem gravável no host de build e gravá-la no dispositivo
  • Os componentes necessários são:
    • um bootloader geralmente específico do SoC, por exemplo u-boot
    • um kernel Linux geralmente específico do SoC
    • um root filesystem baseado no espaço de usuário Linux obtido diretamente do Debian
    • uma ferramenta de montagem de imagem que combine os três em uma imagem gravável
  • As opções mais comuns de ferramenta de montagem de imagem são mkosi, ELBE e debos
  • As três são software livre e geram imagens determinísticas que podem ser gravadas no hardware
  • O trabalho de manutenção cai bastante, e a maior parte das atualizações passa a ser atualizar os pacotes dentro da imagem no estilo apt, em vez de reescrever receitas

Exemplo de build Debian com debos

  • O debosreceitas em YAML
  • Uma receita é composta por uma lista de ações, como executar comandos, criar um root filesystem e instalar pacotes Debian a partir de fontes configuradas
  • O fluxo básico é:
    • operar um espelho Debian local com aptly contendo cópias de todos os pacotes Debian necessários
    • compilar o kernel Linux e, se necessário, o bootloader como pacotes Debian e adicioná-los ao espelho
    • criar e etiquetar um snapshot do espelho
    • essa etiqueta se torna a release
    • configurar o debos para usar esse espelho e escrever as ações da receita que constroem a imagem de destino
    • se necessário, armazenar junto da imagem os pacotes-fonte Debian e o SBOM (Software Bill of Materials) da imagem
  • Armazenar os pacotes-fonte e o SBOM ajuda a cumprir a obrigação de fornecer código-fonte sob a GPL e os requisitos da CRA relacionados à lista de materiais
  • Ferramentas como debsbom geram o SBOM diretamente a partir de um sistema Debian

Quando escolher Yocto

  • O Yocto é adequado quando você precisa de uma distribuição fortemente customizada
    • espaço de usuário customizado
    • flags de compilação customizadas
    • mudanças profundas em componentes de base
  • Também faz sentido quando há restrições rígidas de tamanho ou tempo de boot que uma distribuição pronta não consegue atender
  • Também é adequado quando há restrições de licença que exigem excluir categorias comuns de licença
    • em alguns setores, como dispositivos médicos, automotivo e parte da indústria de defesa, componentes GPLv3 não são distribuídos
    • o mecanismo INCOMPATIBLE_LICENSE do Yocto facilita excluir famílias específicas de licença da imagem inteira
    • em uma base Debian comum, é preciso auditar e reduzir os pacotes manualmente
  • Também é adequado quando o caminho oficial de suporte do fornecedor do SoC é Yocto e a qualidade do BSP é sólida

Quando evitar Yocto

  • Se você só precisa de um Linux moderno para rodar sua aplicação, talvez não precise de Yocto
  • Se o orçamento de armazenamento e memória suporta uma imagem Debian comum, as vantagens do Yocto diminuem
    • um ponto de referência seria centenas de MB de flash e 256 MB de RAM ou mais
  • Se a vida útil do produto é longa e faz mais sentido depender da Debian Security Team do que assumir manutenção própria, evitar Yocto é a escolha certa

Quando evitar Debian

  • Se você vai modificar ou recompilar muitos pacotes Debian, o Debian perde atratividade
    • recompilar alguns pacotes é administrável
    • cada pacote recompilado vira trabalho de manutenção seu
    • ao aplicar patches em dezenas de pacotes upstream, você acaba recriando o trabalho que os mantenedores Debian faziam
    • nessa escala, o modelo de receitas do Yocto lida com isso de forma mais limpa
  • Se você precisa de uma libc não glibc, como musl ou uClibc, o Debian não é adequado
    • o arquivo principal do Debian usa glibc de forma ampla
    • substituí-la exigiria recompilar por conta própria a maior parte do arquivo
  • Se você precisa de software muito mais novo do que o Debian stable oferece, o Debian também fica em desvantagem
    • backports ajudam para alguns pacotes
    • se o produto exige compiladores ou runtimes recentes, isso entra em conflito com o Debian stable
    • Debian testing não é um alvo de produção

Princípios de decisão e conclusão

  • A decisão sobre usar ou não Yocto deve ser tomada de forma consciente e no início do produto
  • É uma escolha estrutural difícil de reverter depois que o produto já foi implantado em campo
  • Em caso de dúvida, é melhor começar com uma distribuição existente
  • Migrar mais tarde para Yocto, quando houver um motivo real, custa muito menos do que descobrir no meio do projeto que você assumiu anos de trabalho de manutenção sem ganho concreto
  • O Yocto é uma excelente obra de engenharia, capaz de construir exatamente o sistema Linux de que você precisa, mas justamente esse controle preciso vira problema quando ele não é necessário
  • A mesma lógica também se aplica quase integralmente a outras ferramentas de build baseadas em código-fonte, como o Buildroot
  • No momento em que você começa a montar sua própria distribuição, também passa a ser dono da responsabilidade de mantê-la
  • A conclusão central é clara
    • “distribuição própria” na prática significa manutenção própria
    • a CRA e regulamentações semelhantes transformam esse custo em um ônus real
    • um build Yocto fortemente modificado não herda gratuitamente as correções upstream
    • cada release de manutenção vira revisão e retrabalho
    • uma distribuição existente como Debian, transformada em imagem com mkosi, ELBE ou debos, cobre o caso comum com muito menos esforço específico de projeto
    • quando você precisa de controle cirúrgico sobre o sistema, o Yocto vence
    • quando não precisa, escolher Yocto vira uma forma longa e cara de resolver um problema que não existe

1 comentários

 
Opiniões no Lobste.rs
  • Se o caminho oficial de suporte do fornecedor do SoC for Yocto, então, mesmo que o BSP não seja muito sólido, em geral ainda parece melhor do que um port de Ubuntu de baixa qualidade
    Um port de Ubuntu torna trabalhos como integração com RAUC ou deixar o sistema de arquivos raiz imutável mais complicados. Eu realmente odeio o Yocto e seus dialetos estranhos de bash/python, mas no fim das contas continuo preso a isso

  • Faço bastante consultoria de Yocto, mas quase nunca passei pelos problemas lamentados no texto. Normalmente é o contrário: mesmo quando Yocto é a melhor opção, o cliente insiste em evitar, e aí é preciso convencer a gerência
    Ainda assim, dá para entender por que Yocto é odiado. É difícil, confuso, lento, e as ferramentas poderiam ser melhores. Mesmo assim, não sei se existe uma alternativa de verdade, e fico curioso se há algo parecido no lado BSD

    • Não sei o quanto isso se parece com Yocto, mas a forma geral de criar imagens para sistemas embarcados no FreeBSD é o NanoBSD
      https://docs.freebsd.org/en/articles/nanobsd/
    • Não usei isso tão a fundo em produção, e pode ser menos completo que o Yocto, mas o buildroot tem coisas bem legais
      Usei principalmente no contexto do Nerves, que basicamente é uma combinação de buildroot + fwup + Erlang VM e software de suporte. Achei bem confortável para desenvolver, empacotar e distribuir sistemas Linux embarcados
    • Não trabalho diretamente com sistemas Linux/BSD embarcados, mas, como alguém que já usou NetBSD, o sistema de build build.sh por si só já parece suficiente
      Dá para fazer cross-compilation do kernel e do userland com facilidade. No final, se você quiser adicionar aplicações do pkgsrc ou colocar um bootloader como o u-boot na imagem gerada, talvez precise de alguns scripts. Pode não ser um fluxo pronto para customização imediata conforme a aplicação, mas como base é bom
    • O NetBSD é estruturado de forma a facilitar cross-compilation para ambientes limitados e, depois que você pega o jeito, ele é bem agradável
  • Pela minha experiência limitada, tendo passado por um pouco do horror da área de embarcados, o NixOS funcionou muito bem para esse tipo de uso, e as ferramentas de build eram muito melhores que as do Yocto

    • Fico curioso se isso também vale para dispositivos ARM. Eu achava que o ecossistema do NixOS ainda era um pouco prematuro para esse tipo de aparelho
  • Coincidentemente, comecei agora no trabalho a planejar e construir um kernel Linux e uma distribuição customizados para dispositivos baseados em Rockchip, então o texto veio em boa hora
    O BSP parece ter bastante coisa para manter, e simplesmente usar Debian parece muito mais administrável do que tarefas de bitbake mal escritas por mim. Ainda assim, o ecossistema do Yocto em si é bem legal, e existem ferramentas como kas e isar que facilitam o começo

    • Pelo README do isar, ele parece ser baseado em Debian, não em Yocto. Fico curioso se misturar os dois é comum
      No texto, parece mais uma escolha entre Yocto ou Debian, não uma abordagem que combine os dois