1편에 이어 이제 본격적으로 Yocto에 대해 알아보자.
Yocto Project는 임베디드 리눅스 시스템을 자동으로 빌드하는 통합 빌드 프레임워크.
하나의 명령으로,
를 모두 빌드함.
이 모든 걸 수작업으로 구성하면 매우 복잡하기 때문에, Yocto라는 자동화된 빌드 파이프라인을 이용하게 됨.
예를 들어:
busybox_1.36.1.bb
이런 파일은 BusyBox를 다운로드하고, 패치 적용하고, 빌드해서 rootfs에 넣는 과정을 정의합니다.
BitBake는 Yocto의 핵심 빌드 엔진.
bitbake <image> 명령을 입력하면 BitBake가 다음을 자동으로 수행
.bb 레시피를 읽음즉, BitBake는 “Makefile + 빌드 스케줄러 + 패키지 관리자”의 역할을 동시에 수행
| 구성요소 | 수행 내용 |
|---|---|
| OE-Core | Yocto의 기반 메타데이터 세트. OpenEmbedded와 공유되며, 빌드 규칙·클래스·함수 등 핵심 로직을 제공 |
| BitBake | 실제 빌드 스케줄러로, 모든 레시피(.bb)를 읽고 Task 단위로 실행 |
| Poky | Yocto의 기본 “레퍼런스 배포판”. OE-Core, BitBake, 메타데이터 등을 패키징한 통합 세트 |
| Documentation | 공식 문서 및 개발 가이드라인. 각 컴포넌트의 작성 규칙과 베스트 프랙티스 제공 |
| Toaster | BitBake 빌드를 시각적으로 관리할 수 있는 웹 기반 GUI 도구. 빌드 로그, 레시피, 패키지 상태를 브라우저에서 관리 가능 |
Yocto의 전체 빌드 흐름은 다음과 같이 이어집니다 👇
레시피(.bb) / 메타데이터(.bbclass, .conf)
↓
BitBake 엔진이 파싱 및 의존성 분석
↓
태스크 스케줄링 (fetch → patch → compile → package → rootfs)
↓
OE-Core의 규칙에 따라 각 Task 실행
↓
Poky (레퍼런스 구성) 기준으로 최종 이미지 생성
결과적으로 tmp/deploy/images/<machine>/ 아래에
커널, 부트로더, 루트파일시스템, SD카드 이미지(.wic 등)가 생성됩니다.
OE-Core(OpenEmbedded Core) 는 Yocto 프로젝트가 사용하는 “핵심 빌드 규칙, 클래스, 함수, 레시피”가 모여 있는 기본 메타데이터 계층(Base Metadata Layer).
즉, OE-Core는
을 정의하는 라이브러리 역할을 함.
OE-Core는 poky 내부 meta/ 디렉터리에 존재.
poky/
├── bitbake/ ← BitBake 빌드 엔진
├── meta/ ← OE-Core (OpenEmbedded Core)
├── meta-poky/
├── meta-skeleton/
└── meta-yocto-bsp/
이 meta/ 디렉터리 안에는 아래와 같은 폴더들이 들어 있어요 👇
| 폴더 | 설명 |
|---|---|
classes/ | .bbclass 파일 — 빌드 공통 규칙 (예: autotools, kernel, image 등) |
conf/ | 전역 설정 (distro, machine, bitbake.conf 등) |
recipes-* | 각 패키지별 레시피 (recipes-core, recipes-devtools, recipes-kernel, recipes-graphics 등) |
files/ | 패치, 설정 스크립트, 추가 자료 |
| 역할 | 설명 |
|---|---|
| ① 공통 빌드 클래스 제공 | classes/*.bbclass 파일에 빌드 로직 정의. 예: autotools.bbclass, kernel.bbclass |
| ② 기본 패키지 레시피 제공 | busybox, bash, udev, glibc, opkg 같은 필수 레시피 포함 |
| ③ 전역 설정 제공 | 타깃 CPU, 크로스 컴파일 옵션, 루트FS 포맷, 이미지 정책 등 |
| ④ 태스크 체계 정의 | fetch → unpack → patch → compile → install → package → image 의 빌드 단계(Task) 정의 |
즉, BitBake가 실제로 무엇을 빌드하고 어떤 순서로 실행할지를 정의하는 규칙 이 OE-Core.
예를 들어 busybox를 빌드한다고 하면:
meta/recipes-core/busybox/busybox_1.36.1.bb 레시피를 읽음busybox.bbclass의 빌드 규칙을 적용 (do_compile, do_install 등)bitbake.conf, distro.conf)을 참조하여 빌드 경로, 크로스컴파일러 설정이 전 과정이 OE-Core에 정의된 규칙에 따라 수행.
좋아요 👍
이제 Yocto의 “레이어(layer)” 개념과 bitbake-layers 명령어의 역할을 짚고 넘어가면
Yocto의 구조를 완전히 이해했다고 봐도 될 정도예요.
레이어(Layer) 는 Yocto의 “빌드 구성 요소를 논리적으로 나눈 단위(모듈)”
쉽게 말해 각 기능이나 보드, 배포판, 패키지 그룹을 독립적으로 관리하기 위한 폴더 단위.
Yocto 빌드 시스템은 모든 걸 “메타데이터(metadata)”로 구성.
이 메타데이터는 레시피(.bb), 클래스(.bbclass), 설정파일(.conf) 들로 이뤄져 있는데, 이걸 역할별로 묶은 그룹 단위가 바로 “레이어”
Poky 안에는 이미 여러 개의 레이어가 존재.
poky/
├── bitbake/
├── meta/ ← OE-Core (기본 룰)
├── meta-poky/ ← poky 배포판 정책
├── meta-yocto-bsp/ ← 예제 보드(BSP) 지원
└── meta-skeleton/ ← 예시 템플릿
그리고 실제로 bblayers.conf에는 이런 식으로 등록됩니다 👇
BBLAYERS ?= " \
/home/user/yocto/poky/meta \
/home/user/yocto/poky/meta-poky \
/home/user/yocto/poky/meta-yocto-bsp \
/home/user/yocto/meta-myproject \
"
즉, BitBake는 이 “레이어 목록”을 기준으로 빌드할 때 사용할 메타데이터를 찾음.
| 레이어 종류 | 역할 | 예시 |
|---|---|---|
| Core Layer (meta) | 기본 빌드 규칙과 표준 패키지 제공 | meta (OE-Core) |
| Distro Layer | 배포판 정책 정의 | meta-poky |
| BSP Layer | 하드웨어 보드별 설정 | meta-yocto-bsp, meta-raspberrypi, meta-ti |
| Software Layer | 특정 소프트웨어 패키지 묶음 | meta-openembedded, meta-qt5, meta-python |
| Custom Layer | 사용자가 만든 레시피나 설정 | meta-myproject |
이렇게 역할별로 나누면, 필요한 기능만 조합해서 효율적으로 빌드할 수 있음.
bitbake-layers 명령어| 명령 | 설명 | 예시 |
|---|---|---|
bitbake-layers show-layers | 현재 등록된 레이어 목록 출력 | meta, meta-poky, meta-yocto-bsp 등 |
bitbake-layers add-layer <path> | 새로운 레이어 추가 (bblayers.conf에 등록됨) | bitbake-layers add-layer ../meta-myproject |
bitbake-layers remove-layer <path> | 레이어 제거 | bitbake-layers remove-layer ../meta-qt5 |
bitbake-layers show-recipes | 현재 인식 중인 모든 레시피 목록 표시 | |
bitbake-layers flatten | 모든 레이어 메타데이터를 병합한 단일 디렉터리 생성 (디버깅용) |
즉,
➡️ 커널 모듈(.ko)이나 사용자 공간 프로그램을 하나의 레시피(recipe) 로 정의
➡️ 그 레시피를 새 레이어(meta-led) 에 넣음
➡️ bblayers.conf에 등록
이 과정을 거치면 BitBake는 bitbake core-image-minimal 시, LED 드라이버를 자동으로 빌드해서 rootfs에 포함함.
먼저 Poky 빌드 환경을 초기화하고:
source poky/oe-init-build-env
그 다음 레이어 생성:
bitbake-layers create-layer ../meta-led
→ 결과 구조:
meta-led/
├── conf/
│ └── layer.conf
├── recipes-example/
│ └── example/
│ └── example_0.1.bb
└── COPYING.MIT
meta-led/
└── recipes-kernel/
└── led-driver/
├── led-driver.c
└── led-driver.bb
led-driver.c
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/init.h>
#define LED_GPIO 18 // 예: GPIO 18번 핀
static int __init led_init(void) {
gpio_request(LED_GPIO, "LED");
gpio_direction_output(LED_GPIO, 1);
printk(KERN_INFO "LED ON\n");
return 0;
}
static void __exit led_exit(void) {
gpio_set_value(LED_GPIO, 0);
gpio_free(LED_GPIO);
printk(KERN_INFO "LED OFF\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple LED driver");
MODULE_AUTHOR("You");
led-driver.bbSUMMARY = "Simple LED on/off kernel module"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0-only;md5=c24b0364c2e3c3253a8d2c95e8d8f6f5"
SRC_URI = "file://led-driver.c"
S = "${WORKDIR}"
inherit module
# 모듈 이름 지정
MODULE_NAME = "led_driver"
do_compile() {
oe_runmake -C ${KERNEL_SRC} M=${S}
}
do_install() {
install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/extra
install -m 0644 ${S}/led-driver.ko ${D}${base_libdir}/modules/${KERNEL_VERSION}/extra/
}
이렇게 하면 BitBake가 LED 드라이버를 커널 모듈(.ko)로 자동적으로 빌드.
이제 만든 meta-led를 현재 빌드 환경에 추가.
bitbake-layers add-layer ../meta-led
→ build/conf/bblayers.conf 에 자동으로 추가됨:
BBLAYERS += "${TOPDIR}/../meta-led"
이제 빌드할 이미지(core-image-minimal)에 LED 드라이버를 포함시키려면
meta-led/recipes-core/images/core-image-minimal.bbappend 파일을 만듭니다:
IMAGE_INSTALL:append = " led-driver"
→ 이렇게 하면 bitbake core-image-minimal 시 LED 드라이버가 rootfs에 자동 포함됩니다.
결과 이미지(tmp/deploy/images/.../core-image-minimal.wic) 안에는
/lib/modules/<kernel-ver>/extra/led-driver.ko 가 들어있게 됨.
부팅 후 커널 모듈 삽입:
insmod /lib/modules/$(uname -r)/extra/led-driver.ko
dmesg | tail
# "LED ON" 출력 확인
Yocto는 임베디드 리눅스 시스템을 자동으로 빌드해주는 프레임워크로, 툴체인, 커널, 루트파일시스템 등을 통합적으로 관리할 수 있습니다.
이번 실습에서는 Yocto의 레퍼런스 배포판인 Poky를 기반으로 core-image-minimal을 빌드하며,
BitBake 빌드 엔진이 OE-Core의 룰(.conf)에 따라 레시피(.bb)를 실행하는 과정을 직접 경험했습니다.
또한, 레이어(layer) 구조를 통해 기능별 모듈을 쉽게 추가하거나 제거할 수 있었고, LED 드라이버처럼 커스텀 기능을 별도의 레이어로 빌드 환경에 통합할 수도 있었습니다.
커널 빌드 과정은 다소 시간이 걸리고 복잡했지만, Yocto의 구조를 이해하니 전체 빌드 흐름이 자동화되어 있다는 점에서 큰 효율성을 느꼈습니다.