Developer Document

Embedded Software 개발을 하면서 습득한 내용을 적은 시니어 개발자들의 글

코 독 코 독 CoderDocument

Embedded SW 기초

Yocto 기초

뜨요르 2024. 6. 9. 21:30

Yocto 란?

리눅스를 개발하려면 개발하려는 아키텍처를 확인해야 하고 어떤 OS를 사용할 건지 또 호환되는 버전은 무엇인지 부트로더 roofs 등등... 수많은 선택이 많다. 그걸 다 정했다 하더라도 빌드할 수 있는 환경을 구축하는데도 엄청난 시간이 소요된다.

 

이런 개발 환경을 좀 더 쉽게 만들어주는 게 빌드 툴이이다. 즉 하드웨어 아키텍처와 무관하게 커스텀 임베디드 리눅스를 만들기 위한 빌드 프레임워크이다, 빌드 툴은 buildroot. LTIB , Yocto 등 여러 가지가 존재하는데 그중 yocto project를 살펴볼 예정이다.

 

yocto에서 다운로드한 컴파일러를 통해서 이미지들이 빌드되기 때문에 개발자는 컴파일러를 설치하려고 찾아다닐 필요가 없다는 큰 장점이 있지만 yocto의 전체 구조를 한마디로 표현하면 매우 어렵다. yocto를 사용하려면 기본적인 임베디드 리눅스에 대한 전반적인 이해가 필요하다고 생각된다.  그렇기에 이번 내용은 Yocto의 기본 개념을 설명하고자 한다.

 

Yocto Project의 구성 - 출처 https://slowbootkernelhacks.blogspot.com/2016/12/yocto-project.html

 

Yocto의 기본 구성요소

  • OpenEmbedded-Core

OpenEmbedded Project와 공유되는 core meta data, base layer의 묶음이다.  http://openembedded.org 사이트에서 yocyo가 직접 관리하는 별도의 build system으로 이것만 가지고도 linux 배포판을 만들 수 있을 정도로 매구 강력한 yocto의 핵심 요소이다.


  • Poky

Yocto project의 reference system으로 다양한 tool과 meta data로 이루어져 있다. 여기에 자신만의 타깃 보드에 대한 내용을 추가해 줌으로써 최종적으로 원하는 리눅스 시스템을 만들어 낼 수 있다.


bitbake wayland
bitbake -c cleansstate wayland
  • BitBake

python과 shell script로 만들어진 task scheduler로써, build 하고자 하는 소스를 다운로드하고 빌드한 후, 최종 install 하기까지의 전 과정을 담당. Make와 유사하다고 볼 수 있으나 실제로는 규모면에서 차이가 있음

bitbake는 접두사 meta로 시작하는 모든 레이어를 실행한다. 빌드 클래스, 구성 파일 및 레시피를 구문 분석하고 즉시 쉘 스크립트를 생성하여 각 작업을 실행한다.

아래의 표는 bitbake의 Main Tasks이다.

TASK DESCRIPTION FUNCTION
Build Default task for a recipe - depends on all other normal tasks required to 'build' a recipe do_build
Init RAMFS Combines an initial ramdisk image and kernel together to form a single image do_bundle_initramfs
Check URI Validates the SRC_URI value do_checkuri
Clean Removes all output files for a target do_clean
Clean all Removes all output files, shared state cache, and downloaded source files for a target do_cleanall
Clean SSTATE Removes all output files and shared state cache for a target do_cleansstate
Compile Compiles the source in the compilation directory do_compile
Configure Configures the source by enabling and disabling any build-time and configuration options for the software being built do_configure
Dev Shell Starts a shell with the environment set up for development/debugging do_devshell
Fetch Fetches the source code do_fetch
Install Copies files from the compilation directory to a holding area do_install
List Tasks Lists all defined tasks for a target do_listtasks
Package Analyzes the content of the holding area and splits it into subsets based on available packages and files do_package
Package QA Runs QA checks on packaged files do_package_qa
Write IPK Creates the actual IPK packages and places them in the Package Feed area do_package_write_ipk
Patch Locates patch files and applies them to the source code do_patch
Populate License Writes license information for the recipe that is collected later when the image is constructed do_populate_lic
Populate SDK Creates the file and directory structure for an installable SDK do_populate_sdk
Populate SYSROOT Copies a subset of files installed by do_install into the sysroot in order to make them available to other recipes do_populate_sysroot
Root FS Creates the root filesystem (file and directory structure) for an image do_rootfs
Unpack Unpacks the source code into a working directory do_unpack

  • meta data

아래 3가지를 일컬어 meta data라고 한다.

- Recipes (. bb) : 빌드할 소프트웨어/이미지 논리 단위

- Class (. bbclass) : 공통 코드로 추상화

- Configuration files (. conf) : 전역 변수 설정


  • Recipe

buildroot의 package에 해당하는 내용. source download -> build -> install 관련 내용을 기술하고 있음. BitBake가 이 내용을 보고, 실제 action을 취하게 됨 meta폴더 안에 존재한다.

레시피는 파일 확장자 *. bb로 표시되는 가장 기본적인 메타데이터 파일이다. 레시피는 소스 코드에서 하나 이상의 패키지를 빌드할 수 있다.

 

  • bb파일 내용
    • 패키지에 대한 설명 정보
    • 기존 종속성(빌드 및 런타임 종속성 모두)
    • DEPENDS 및 RDEPENDS 변수는 빌드 및 런타임 종속성을 보유합니다.
      • ex) DEPENDS = "closedcaption-hal-headers"
      •       RDEPENDS = "libcrypto"
    • 소스 코드가 있는 위치와 이를 가져오는 방법
    • SRC_URI 변수는 가져올 URL 경로를 보유한다.
      • ex) SRC_URI = "${RDK_GENERIC_ROOT_GIT}/devicesettings/generic;protocol=${RDK_GIT_PROTOCOL};branch=${RDK_GIT_BRANCH}"
    • 레시피 버전
      • ex) SRCREV= "${AUTOREV}" /
      •       SRCREV= "6c492f7452a6b4b240f1b572dbda2f2bcc4faf2d"
    • 소스 코드에 패치가 필요한지 여부, 패치를 찾을 수 있는 위치 및 적용 방법
    • 소스 코드를 구성하고 컴파일하는 방법
    • 대상 컴퓨터에서 생성된 패키지를 설치할 위치     
  • 레시피 추가 파일

추가 파일은 *. bbappend 확장자로 식별됨. 기존 레시피 파일의 정보를 확장하거나 재정의하는 데 사용된다.

BitBake는 모든 추가 파일에 해당 레시피(*. bb) 파일이 있을 것으로 예상한다.

누락된. bb 파일은 BitBake 파서에 의해 경고로 표시된다. 추가 파일과 해당 레시피 파일은 동일한 루트 파일 이름을 사용해야 한다.
ex)  linux-firmware.bb  및 linux-firmware.bbappend

 

위의 파일 내용을 조금 더 구체적으로 설명해 보겠다. 각각의 메타 데이터에 대한 설명이다.

  • bitbake 변수/메타 데이터

이는 bitbake에 의해 자동으로 설정됨

TOPDIR – 빌드 디렉터리

LAYERDIR – 현재 레이어 디렉터리

FILE – 처리 중인 파일의 경로 및 파일 이름

 

  • 빌드 시간 메타데이터

PN – 패키지 이름(“myrecipe”)

PV - 패키지 버전(1.0)

PR – 패키지 릴리스(r0)

P = “${PN}-${PV}”

PF = “${PN}-${PV}-${PR}”

FILE_DIRNAME – FILE의 디렉터리

FILESPATH = "${FILE_DIRNAME}/${PF}:\

TOPDIR – 빌드 디렉터리

TMPDIR = "${TOPDIR}/tmp"

WORKDIR = ${TMPDIR}/work/${PF}”

S = “${WORKDIR}/${P}” (소스 디렉터리)

B = “${S}”(빌드 디렉터리)

D = “${WORKDIR}/${image}”(대상 디렉터리)

DEPLOY_DIR = “${TMPDIR}/deploy”

DEPLOY_DIR_IMAGE = “${DEPLOY_DIR}/images”

 

  • 종속성 메타데이터

빌드 시간 패키지 변수

    DEPENDS – 빌드 시간 패키지 종속성

    제공 = “${P} ${PF} ${PN}”

런타임 패키지 변수

    RDEPENDS – 런타임 패키지 종속성

    RRECOMMENDS – 런타임 권장 패키지

    RSUGGESTS – 런타임 추천 패키지

    RPROVIDES – 런타임은 다음을 제공

    RCONFLICTS – 런타임 패키지 충돌

    RREPLACES – 런타임 패키지 대체

 

  • 공통 메타데이터

일반적으로 설정하는 변수

SUMMARY – 패키지/레시피에 대한 간단한 설명

HOMEPAGE – 업스트림 웹페이지

LICENSE – 포함된 소스 코드의 라이선스

LIC_FILES_CHKSUM – 패키징 시 라이선스 파일의 체크섬(빌드별 변경 사항 확인)

SRC_URI – 패키지를 빌드하는 데 사용할 소스 코드, 패치 및 추가 파일의 URI. URI를 기반으로 다양한 가져오기 도구를 사용

FILES – 바이너리 패키지에 포함될 파일

 

  • Patch

ffmpeg 위치
ffmeg.bbappend 파일
patch 파일 경로

레시피 파일에 패치를 적용할 수 있습니다. 패치 파일 확장자 *. patch 

레시피의 하위 디렉터리에 패치 파일을 배치합니다. 하위 디렉터리의 이름은 구성 요소 이름이나 파일로 저장하는 것이 좋습니다.

레시피 파일 SRC_URI += " file://temp.patch " 에 아래 줄을 추가합니다.


  • classes
  • class file은 다수의 레시피(. bb)에서 일반적인 기능을 요약
  • 레시피는 class를 상속받는다.
    • e.g. inherit classname
    • extension:. bbclass
  • 레이어/classes(meta*/classes) 디렉터리 둔다.
  • Example of classes
    • cmake.bbclass : 레시피 내 cmake를 처리한다.
    • kernel.bbclass : 커널 building을 처리한다. 모든 커널 트리를 빌드하는 코드를 포함
    • module.bbclass : 리눅스 커널 모듈 out-of-tree building에 대한 support를 제공한다.

Yocto Project 순서

yocto 동작 방식 출처 - https://slowbootkernelhacks.blogspot.com/2016/12/yocto-project.html

  1. poky를 다운로드하고 환경 설정한다.
  2. 자신의 타깃 보드에 맞는 BSP Layer를 준비한다.
    2.1. 있는 레이어 다운로드하여서 레시피나 레이어에 추가하는 게 정신건강에 좋음
  3. 자신의 타깃 보드에 맞는 general layer를 만듦
  4. 이 이후 bitbake가 일을 진행한다. recipe 파일을 토대로, build에 필요한 모든 소스코드를 다운로드 fetch 한다.
  5. patch가 있다면, patch도 한다.
  6. configurecompile을 진행한다.
  7. install 한다.
  8. build가 성공하면, Package 파일(. rpm,. deb, ipk) 등이 생성된다.
  9. image를 생성한다.

Build Directory

yocto는 처음 build space를 만들고 설정되어야 bitbake를 사용이 가능하다.

$ source poky/oe-init-build-env build  // 일반적인 설정 
or 
$ source fsl-setup-release.sh -b build-fb   // BSP 기반의 다른 설정 

//자동으로 build space로 이동

$ ls conf/
bblayers.conf  bblayers.conf.org  local.conf  local.conf.org  local.conf.sample  sanity_info  templateconf.cfg

source에서 위와 같이 build space를 설정하면 자동으로 build space 생성 및 이동

 

build의 user configuration 설정 - build/conf 

  • bblayers.conf

각 Yocto의 Layer의 위치와 Layer를 추가 /삭제를 담당하며 이외 SUB 설정도 가능하다.
이곳에서 BBFILES는 의미가 없으며, 실제 Layer configuration에서 설정된다.

아래의 BSPDIR은 python으로 동작되며, 다른 곳에서는 없을 수도 있으며, BBLAYERS를 절대 PATH로 사용해도 상관없다.

POKY_BBLAYERS_CONF_VERSION = "2"
  
BBPATH = "${TOPDIR}"
## $ bitbake -e | grep ^FILE= 와 동일 (bblayer.conf 위치찾기) '/../..' 를 expand하여 source 위치를 찾음
BSPDIR := "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../..')}"

## BBLYAERS를 이용하여 현재 존재하는 Layer들을 추가 
BBLAYERS ?= " \
  ${BSPDIR}/poky/meta \
  ${BSPDIR}/poky/meta-poky \
  ${BSPDIR}/poky/meta-yocto-bsp \
  ${BSPDIR}/meta-tegra \
  ${BSPDIR}/meta-tegra/contrib \
  ${BSPDIR}/meta-openembedded/meta-oe \
  ${BSPDIR}/meta-openembedded/meta-python \
  ${BSPDIR}/meta-openembedded/meta-networking \
"
  • local.conf

Build directory의 전체 환경설정으로 Build 관련설정을 비롯하여, 기본적인 MACHINE 설정 DISTRO 설정 기타 Package 관련설정등 다양한 설정이 가능하다. 

  1. Yocto project tool의 기본 설정들을 오버라이드(override)하기에 매우 유용하다.
  2. 특정 변수를 바꿀 수 있고, 이미지에 들어가는 패키지 추가
  3. 하지만 local.conf에 변화된 사항은 어떠한 소스코드 추적 불가이기 때문에 임시 변경으로 생각한다.

* 참고 :  https://docs.yoctoproject.org/1.4/ref-manual/ref-manual.html

## MACHINE을 선택을 해야 MACHINE Layer가 동작하므로 중요 (Device Tree 및 Kernel/Uboot Config에 영향)
MACHINE = 'IMX8MQ'
## DISTRO를 선택해야 배포하는 Distro Layer 설정이 되므로 중요 
DISTRO = 'poky'
## PACKAGE 방식의 선택 rpm /ipk / deb 
PACKAGE_CLASSES ?= 'package_rpm'
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats"
PATCHRESOLVE = "noop"
## Disk Monitor 이며, 각각의 Directory의 제한을 둘 수가 있다. 
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    HALT,${TMPDIR},100M,1K \
    HALT,${DL_DIR},100M,1K \
    HALT,${SSTATE_DIR},100M,1K \
    HALT,/tmp,10M,1K"
PACKAGECONFIG:append:pn-qemu-system-native = " sdl"
CONF_VERSION = "2"

## 리소스를 사용하는 방법 설정
BB_NUMBER_THREADS="10"
PARALLEL_MAKE = "-j 10"

## 각 DL_DIR를 이용하여 Download의 위치를 마음대로 변경할 경우 직접설정
DL_DIR ?= "${TOPDIR}/../downloads/"

 

build/tmp 디렉터리

tmp : 모든 빌드 시스템의 아웃풋 유지

         tmp/deploy/images/[machine] : 이미지 경로

tmp/work : 모든 빌드한 정보를 담고 있다.

ex) jetson-nano의 kernel경로 : tmp/work/jetson_nano_poky-linux/linux-tegra/4.9.253+gitAUTOINC+ac2a37e821-r0

ex) imx8mq의 uboot경로 : tmp/work/imx8mq-fscl-linux/u-boot-imx/2022.04

위의 해당 컴포넌트의 빌드 경로를 가게 되면 temp 경로가 존재

temp경로는 build task들이 있다. bitbake로 run.do_{task}로 실행 가능하다.

 

<주요 task 정리>
do_fetch : source code를 가져온다(download).
do_unpacksource code의 압축을 푼다(tar.gz, zip, xz, tar ..)
do_patchsource code에 적용할 patch가 있다면 이를 적용한다.
do_configuresource code에 configure script가 있을 경우 이를 수행한다.
do_compilecompile을 진행한다.
do_installbuild 결과물을 rootfs에 포함시킨다.
do_package: 패키지를 만든다.
do_rootfs: rootfs 이미지를 생성한다.

 

build/ 다른 디렉터리

downloads : 빌드에서 사용되는 레시피의 git 레파지토리 와 upstream tarballs 다운로드 장소

sstate-cache : 공유 상태의 캐시

chche : bitbake의 parser에 의해 사용되는 캐시

Layer

관계있는 레시피 모음 레시피 컨테이너라고도 한다.

ex ) meta-{layer_name} 

 Image 생성

$ bitbake <image_name>
  • Image_name (나중에 다양한 image, specific image 등 많음)
    • core-image-minimal: Device가 boot할 수 있게 하는 small image. very useful
      • Kernel, Bootloader 개발 시 유용
  • build에서 bitbake core-image-minimal 명령 실행
  • core-image-weston-jetson-nano.tegraflash.tar.gz 이미지 압축 파일 생성

 

'Embedded SW 기초' 카테고리의 다른 글

메모리 구조  (0) 2024.06.10
임베디드 리눅스 부팅 절차  (0) 2024.06.10
SHELL script  (0) 2024.06.03
Bluetooth란 + BLE 동작 방식  (0) 2024.06.03
SQLD 1장 데이터 모델링의 이해  (0) 2024.06.02