Yocto Project: Definições e Conceitos

yocto project introdução
Este post faz parte da série Yocto Project

Na primeira parte dessa série apresentamos os prós e contras ao se utilizar distribuições Linux prontas e customizadas, uma breve introdução sobre o Yocto Project, bem como suas características principais e seus diferenciais.

Nessa segunda parte veremos em detalhes a arquitetura desse sistema de build assim como alguns conceitos e definições importantes que nos darão a base necessária para desenvolvermos distribuições Linux embarcado customizadas a serem utilizadas em produtos eletrônicos.

Yocto Project – Arquitetura

A figura 1 apresenta um panorama da arquitetura do ambiente de desenvolvimento do Yocto Project:

Yocto Project Definições e Conceitos
Figura 1 – Arquitetura do ambiente de desenvolvimento do Yocto Project

Basicamente podemos considerar que temos 6 entidades principais no sistema: 

  • Código fonte upstream (Upstream sources);
  • Metadados e entradas (Metada/Inputs);
  • Sistema de Build propriamente dito (Build System);
  • Pacotes resultantes (Output Packages);
  • Tarefas (Process steps – tasks);
  • Imagem resultante (Output Data Image).

De posse das configurações de usuário, BSP (board support package) e políticas, juntamente com os metadados, o Bitbake irá processar tais informações e criar uma cadeia de execução de tarefas ordenadas de acordo com suas interdependências. O workflow comumente encontrado das tarefas (tasks) é o representado na figura 1, onde: 

  1. O código fonte é baixado;
  2. Aplicação de patches se necessários;
  3. Configuração e compilação;
  4. Análise do resultado para a divisão do pacote e suas relações de dependência;
  5. Geração de pacotes (rpm, deb ou ipk);
  6. Testes de garantia de qualidade dos pacotes gerados (ex.: verificação se todos os binários esperados estão presentes no pacote);
  7. Geração do feed de pacotes;
  8. Geração da imagem ou do SDK.

Yocto Project – Conceitos e Definições

Layer (camada)

Grupo de metadados (metadata) que podem ser incorporados ao sistema de build de forma a estendê-lo (ex.: Software, BSP e Distro).

Distro (distribuição)

Configurações, políticas e regras para geração da imagem do sistema.

Machine (máquina)

Plataforma de hardware alvo da distribuição a ser gerada, implementada através de uma camada de BSP.

Image (imagem)

Imagem final do rootfs do sistema gerado para determinada máquina, implementado através de uma receita de imagem.

Task (tarefa)

Procedimentos executados pelo sistema de build ao processar as receitas.

Package (pacote)

Resultado do processamento da receita de um componente de software, agregado em algum formato popular de empacotamento (.ipk, .deb, .rpm).

Tipos de Metadados

Recipes – Receitas (*.bb)

  • Descrevem instruções de como se constrói um pacote;
  • Podem ser estendidas em outras camadas (.bbappend);
  • Podem compartilhar “dados” através de arquivos “.inc”.

PackageGroups – Grupos de Pacotes (*.bb)

Usado para agrupar pacotes para serem inclusos em uma imagem.

Classes (*.bbclass)

Mecanismo de herança para prover funcionalidades comuns.

Configuration – Configuração (*.conf)

Dita o comportamento do processo de build de maneira global.

Detalharemos a diante cada um desses conceitos apresentados.

Layer

Estrutura típica de diretórios (ex.: meta-yocto-bsp):

conf
lib
recipes-bsp
recipes-core
recipes-graphics
recipes-kernel

Possui um arquivo de configuração a ser usado pelo Bitbake para processamento dos metadados (ex.: meta-yocto-bsp/conf/layer.conf):

# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
            ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "yoctobsp"
BBFILE_PATTERN_yoctobsp = "^${LAYERDIR}/"
BBFILE_PRIORITY_yoctobsp = "5"
LAYERVERSION_yoctobsp = "3"

As camadas devem ser adicionadas no arquivo “build/conf/bblayers.conf“. Exemplo:

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"
 
BBPATH = "${TOPDIR}"
BBFILES ?= ""
 
BBLAYERS ?= " \
    ${TOPDIR}/../poky-krogoth/meta-embarcados \
    ${TOPDIR}/../poky-krogoth/meta-embarcados/meta-rpi \
    ${TOPDIR}/../poky-krogoth/meta-qt5 \
    ${TOPDIR}/../poky-krogoth/meta-raspberrypi \
    ${TOPDIR}/../poky-krogoth/meta-openembedded/meta-oe \
    ${TOPDIR}/../poky-krogoth/meta-openembedded/meta-ruby \
    ${TOPDIR}/../poky-krogoth/meta \
    ${TOPDIR}/../poky-krogoth/meta-yocto \
  "

Documentação sobre Layers

Distro

Possui um arquivo de configuração a ser usado pelo Bitbake para definição de regras e políticas da imagem a ser gerada (ex.: meta-poky/conf/distro/poky.conf):

DISTRO = "poky"
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
DISTRO_VERSION = "2.1+snapshot-${DATE}"
DISTRO_CODENAME = "master"
SDK_VENDOR = "-pokysdk"
SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"

MAINTAINER = "Poky <poky@yoctoproject.org>"

TARGET_VENDOR = "-poky"

LOCALCONF_VERSION = "1"

DISTRO_VERSION[vardepsexclude] = "DATE"
SDK_VERSION[vardepsexclude] = "DATE"

# Override these in poky based distros
POKY_DEFAULT_DISTRO_FEATURES = "largefile opengl ptest multiarch wayland"
POKY_DEFAULT_EXTRA_RDEPENDS = "packagegroup-core-boot"
POKY_DEFAULT_EXTRA_RRECOMMENDS = "kernel-module-af-packet"

DISTRO_FEATURES ?= "${DISTRO_FEATURES_DEFAULT} ${DISTRO_FEATURES_LIBC} ${POKY_DEFAULT_DISTRO_FEATURES}"

PREFERRED_VERSION_linux-yocto ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemux86 ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemux86-64 ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemuarm ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemumips ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemumips64 ?= "4.4%"
PREFERRED_VERSION_linux-yocto_qemuppc ?= "4.4%"

SDK_NAME = "${DISTRO}-${TCLIBC}-${SDK_ARCH}-${IMAGE_BASENAME}-${TUNE_PKGARCH}"
SDKPATH = "/opt/${DISTRO}/${SDK_VERSION}"

DISTRO_EXTRA_RDEPENDS += " ${POKY_DEFAULT_EXTRA_RDEPENDS}"
DISTRO_EXTRA_RRECOMMENDS += " ${POKY_DEFAULT_EXTRA_RRECOMMENDS}"

POKYQEMUDEPS = "${@bb.utils.contains("INCOMPATIBLE_LICENSE", "GPL-3.0", "", "packagegroup-core-device-devel",d)}"
DISTRO_EXTRA_RDEPENDS_append_qemuarm = " ${POKYQEMUDEPS}"
DISTRO_EXTRA_RDEPENDS_append_qemuarm64 = " ${POKYQEMUDEPS}"
DISTRO_EXTRA_RDEPENDS_append_qemumips = " ${POKYQEMUDEPS}"
DISTRO_EXTRA_RDEPENDS_append_qemuppc = " ${POKYQEMUDEPS}"
DISTRO_EXTRA_RDEPENDS_append_qemux86 = " ${POKYQEMUDEPS}"
DISTRO_EXTRA_RDEPENDS_append_qemux86-64 = " ${POKYQEMUDEPS}"

TCLIBCAPPEND = ""

QEMU_TARGETS ?= "arm aarch64 i386 mips mipsel mips64 ppc x86_64"
# Other QEMU_TARGETS "mips64el sh4"

PREMIRRORS ??= "\
bzr://.*/.*   https://downloads.yoctoproject.org/mirror/sources/ \n \
cvs://.*/.*   https://downloads.yoctoproject.org/mirror/sources/ \n \
git://.*/.*   https://downloads.yoctoproject.org/mirror/sources/ \n \
gitsm://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \n \
hg://.*/.*    https://downloads.yoctoproject.org/mirror/sources/ \n \
osc://.*/.*   https://downloads.yoctoproject.org/mirror/sources/ \n \
p4://.*/.*    https://downloads.yoctoproject.org/mirror/sources/ \n \
svn://.*/.*   https://downloads.yoctoproject.org/mirror/sources/ \n"

MIRRORS =+ "\
ftp://.*/.*      https://downloads.yoctoproject.org/mirror/sources/ \n \
https://.*/.*     https://downloads.yoctoproject.org/mirror/sources/ \n \
https://.*/.*    https://downloads.yoctoproject.org/mirror/sources/ \n"

# The CONNECTIVITY_CHECK_URI's are used to test whether we can succesfully
# fetch from the network (and warn you if not). To disable the test set
# the variable to be empty.
# Git example url: git://git.yoctoproject.org/yocto-firewall-test;protocol=git;rev=master
CONNECTIVITY_CHECK_URIS ?= "https://www.example.com/"

SANITY_TESTED_DISTROS ?= " \
            poky-1.7 \n \
            poky-1.8 \n \
            poky-2.0 \n \
            Ubuntu-14.04 \n \
            Ubuntu-14.10 \n \
            Ubuntu-15.04 \n \
            Ubuntu-15.10 \n \
            Ubuntu-16.04 \n \
            Fedora-22 \n \
            Fedora-23 \n \
            CentOS-7.* \n \
            Debian-8.* \n \
            openSUSE-project-13.2 \n \
            "
#
# OELAYOUT_ABI allows us to notify users when the format of TMPDIR changes in 
# an incompatible way. Such changes should usually be detailed in the commit
# that breaks the format and have been previously discussed on the mailing list 
# with general agreement from the core team.
#
OELAYOUT_ABI = "11"

# add poky sanity bbclass
INHERIT += "poky-sanity"

# QA check settings - a little stricter than the OE-Core defaults
WARN_TO_ERROR_QA = "already-stripped compile-host-path install-host-path \
                    installed-vs-shipped ldflags pn-overrides rpaths staticdev \
                    useless-rpaths"
WARN_QA_remove = "${WARN_TO_ERROR_QA}"
ERROR_QA_append = " ${WARN_TO_ERROR_QA}"

require conf/distro/include/poky-world-exclude.inc
require conf/distro/include/no-static-libs.inc
require conf/distro/include/yocto-uninative.inc
INHERIT += "uninative"

Basicamente define toolchain, libc, sistema de init e versões de determinados pacotes. Possui a variável DISTRO_FEATURES que pode receber os seguintes valores:

alsa
bluetooth
cramfs
directfb
ext2
ipsec
ipv6
irda
keyboard
nfs
opengl
pci
pcmcia
ppp
ptest
smbfs
systemd
usbgadget
usbhost
wayland
wifi
x11

A figura 2 ilustra as principais distribuições disponíveis.

Principais distribuições disponíveis no Yocto Project.
Figura 2 – Principais distribuições disponíveis no Yocto Project.

Para configurarmos qual distribuição queremos gerar devemos atribuir o nome da distribuição à variável DISTRO no arquivo build/conf/local.conf.

Documentação sobre DISTRO e DISTRO_FEATURES.

Machine

A Machine é a nossa plataforma alvo, ou seja, a placa para a qual desejamos gerar a nossa distribuição customizada. Ela é definida através de um arquivo de configuração a ser usado pelo Bitbake que armazena as features de hardware que vão influenciar a compilação e instalação pacotes, bem como quais receitas de bootloader e kernel a serem consideradas. Vejamos o exemplo da Beaglebone Black (arquivo meta-yocto-bsp/conf/machine/beaglebone.conf):

#@TYPE: Machine
#@NAME: Beaglebone machine
#@DESCRIPTION: Machine configuration for https://beagleboard.org/bone and https://beagleboard.org/black boards

PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
XSERVER ?= "xserver-xorg \
           xf86-input-evdev \
           xf86-input-mouse \
           xf86-video-fbdev \
           xf86-input-keyboard"

MACHINE_EXTRA_RRECOMMENDS = " kernel-modules kernel-devicetree"

EXTRA_IMAGEDEPENDS += "u-boot"

DEFAULTTUNE ?= "cortexa8hf-neon"
include conf/machine/include/tune-cortexa8.inc

IMAGE_FSTYPES += "tar.bz2 jffs2"
EXTRA_IMAGECMD_jffs2 = "-lnp "

SERIAL_CONSOLE = "115200 ttyO0"

PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
PREFERRED_VERSION_linux-yocto ?= "4.4%"

KERNEL_IMAGETYPE = "zImage"
KERNEL_DEVICETREE = "am335x-bone.dtb am335x-boneblack.dtb"
KERNEL_EXTRA_ARGS += "LOADADDR=${UBOOT_ENTRYPOINT}"

SPL_BINARY = "MLO"
UBOOT_SUFFIX = "img"
UBOOT_MACHINE = "am335x_evm_config"
UBOOT_ENTRYPOINT = "0x80008000"
UBOOT_LOADADDRESS = "0x80008000"

MACHINE_FEATURES = "usbgadget usbhost vfat alsa"

IMAGE_BOOT_FILES ?= "u-boot.${UBOOT_SUFFIX} MLO"

A Machine possui uma variável (MACHINE_FEATURES) para definição de suas características que pode receber os seguintes valores:

acpi
alsa
apm
bluetooth
efi
ext2
irda
keyboard
pcbios
pci
pcmcia
phone
qvga
rtc
screen
serial
touchscreen
usbgadget
usbhost
vfat
wifi

Para configurarmos para qual Machine queremos gerar a distribuição devemos atribuir o nome da  Machine à variável MACHINE no arquivo build/conf/local.conf.

Documentação sobre MACHINE e MACHINE_FEATURES.

Receitas

As Receitas (recipes) disponibilizam os “ingredientes” e as instruções de “culinária” a serem consumidas pelo Bitbake para se construir um determinado pacote ou imagem. São nomeadas da seguinte maneira: basename_version.bb. Onde: basename representa o nome do pacote e version a versão do pacote em questão. As recipes sempre terão a extensão “.bb” como identificação.

Dentro de uma receita as informações comumente encontradas são:

DESCRIPTION
HOMEPAGE
LICENSE
SECTION
DEPENDS
LIC_FILES_CHKSUM
SRC_URI

Documentação sobre as variáveis que podem ser utilizadas em uma receita.

Vejamos o exemplo da receita para o pacote libogg na versão 1.3.2 (meta/recipes-multimedia/libogg/libogg_1.3.2.bb):

SUMMARY = "Ogg bitstream and framing libary"
DESCRIPTION = "libogg is the bitstream and framing library \
for the Ogg project. It provides functions which are \
necessary to codec libraries like libvorbis."
HOMEPAGE = "https://xiph.org/"
BUGTRACKER = "https://trac.xiph.org/newticket"
SECTION = "libs"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://COPYING;md5=db1b7a668b2a6f47b2af88fb008ad555 \
                    file://include/ogg/ogg.h;beginline=1;endline=11;md5=eda812856f13a3b1326eb8f020cc3b0b"

SRC_URI = "https://downloads.xiph.org/releases/ogg/${BP}.tar.xz"

SRC_URI[md5sum] = "5c3a34309d8b98640827e5d0991a4015"
SRC_URI[sha256sum] = "3f687ccdd5ac8b52d76328fbbfebc70c459a40ea891dbf3dccb74a210826e79b"

inherit autotools pkgconfig

As receitas podem ser modificadas através de arquivos “.bbappend” (e.: libogg_1.3.2.bbappend) localizados em outras camadas. Dessa maneira não precisamos editar a receita original e podemos concentrar todas as customizações necessárias em uma camada específica, facilitando a manutenção e controle de mudanças.

De posse dos ingredientes e instruções básicas o Bitbake irá executar tarefas (tasks) para construção da receita. A seguir listamos as tasks comumentes executadas para uma receita:

  • do_fetch: Localiza e baixa o código fonte;
  • do_unpack: desempacota o fonte no diretório de trabalho;
  • do_patch: aplica patches se necessários;
  • do_configure: executa se necessário alguma configuração pré-build;
  • do_compile: compila o código fonte;
  • do_install: instalação dos artefatos de software resultantes do build em um local temporário;
  • do_populate_sysroot: copia os artefatos para o sysroot (área comum a ser usada para satisfação de dependência);
  • do_package_*: cria os pacotes de instalação.

Tudo começa no local.conf

O arquivo “build/conf/local.conf” irá ditar “as regras do jogo”. A partir dele com configurações mínimas da DISTRO e MACHINE que iremos utilizar o Bitbake será capaz de construir imagens e  pacotes presentes nas camadas definidas no arquivo”build/conf/bblayers.conf“. Exemplo de um arquivo”local.conf“:

MACHINE = "raspberrypi2"
DISTRO = "poky"
DL_DIR = "${TOPDIR}/../dl"
PACKAGE_CLASSES = "package_ipk"
DISTRO_FEATURES_remove = "x11 wayland"
LICENSE_FLAGS_WHITELIST = "commercial license"

Conclusão 

Na segunda parte dessa série vimos em mais detalhes a arquitetura e conceitos e definições do Yocto Project. Na terceira parte faremos um Quick Start e demonstraremos na prática o uso dos conceitos aqui apresentados.

Yocto Project

Yocto Project: Introdução Yocto Project: Quick Start
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
1 Comentário
recentes
antigos mais votados
Inline Feedbacks
View all comments
Ricardo
Ricardo
22/03/2022 20:31

Oi Diego. Muito obrigado por essa série do Yocto! Muito claro e detalhes no ponto pra ler se perder. Valeu mesmo!

Home » Linux Embarcado » Yocto Project: Definições e Conceitos

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: