Yocto 란?
리눅스를 개발하려면 개발하려는 아키텍처를 확인해야 하고 어떤 OS를 사용할 건지 또 호환되는 버전은 무엇인지 부트로더 roofs 등등... 수많은 선택이 많다. 그걸 다 정했다 하더라도 빌드할 수 있는 환경을 구축하는데도 엄청난 시간이 소요된다.
이런 개발 환경을 좀 더 쉽게 만들어주는 게 빌드 툴이이다. 즉 하드웨어 아키텍처와 무관하게 커스텀 임베디드 리눅스를 만들기 위한 빌드 프레임워크이다, 빌드 툴은 buildroot. LTIB , Yocto 등 여러 가지가 존재하는데 그중 yocto project를 살펴볼 예정이다.
yocto에서 다운로드한 컴파일러를 통해서 이미지들이 빌드되기 때문에 개발자는 컴파일러를 설치하려고 찾아다닐 필요가 없다는 큰 장점이 있지만 yocto의 전체 구조를 한마디로 표현하면 매우 어렵다. yocto를 사용하려면 기본적인 임베디드 리눅스에 대한 전반적인 이해가 필요하다고 생각된다. 그렇기에 이번 내용은 Yocto의 기본 개념을 설명하고자 한다.
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
레시피 파일에 패치를 적용할 수 있습니다. 패치 파일 확장자 *. 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 순서
- poky를 다운로드하고 환경 설정한다.
- 자신의 타깃 보드에 맞는 BSP Layer를 준비한다.
2.1. 있는 레이어 다운로드하여서 레시피나 레이어에 추가하는 게 정신건강에 좋음 - 자신의 타깃 보드에 맞는 general layer를 만듦
- 이 이후 bitbake가 일을 진행한다. recipe 파일을 토대로, build에 필요한 모든 소스코드를 다운로드 fetch 한다.
- patch가 있다면, patch도 한다.
- configure, compile을 진행한다.
- install 한다.
- build가 성공하면, Package 파일(. rpm,. deb, ipk) 등이 생성된다.
- 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 관련설정등 다양한 설정이 가능하다.
- Yocto project tool의 기본 설정들을 오버라이드(override)하기에 매우 유용하다.
- 특정 변수를 바꿀 수 있고, 이미지에 들어가는 패키지 추가
- 하지만 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_unpack: source code의 압축을 푼다(tar.gz, zip, xz, tar ..)
do_patch: source code에 적용할 patch가 있다면 이를 적용한다.
do_configure: source code에 configure script가 있을 경우 이를 수행한다.
do_compile: compile을 진행한다.
do_install: build 결과물을 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 개발 시 유용
- core-image-minimal: Device가 boot할 수 있게 하는 small image. very useful
- 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 |