개요
Poky로 빌드된 Raspberry Pi 4 이미지는 완전히 순수한 형태로 존재한다. 다시 말해, 기본적인 쉘 명령이나 유틸리티를 제외한 아무런 애플리케이션이 올라가 있지 않다. 따라서, 유저 애플리케이션을 이미지에 빌드시키기 위해서는 직접 새 애플리케이션을 구현하고 이를 이미지에도 빌드될 수 있도록 레시피 파일을 작성해주어야 한다.
본 페이지에서는 예제로 “Hello, World”를 출력하는 C언어 유저 애플리케이션을 구현 후, 이를 Raspberry Pi 4 이미지내에 함께 빌드 될 수 있도록 레시피를 작성하는 방법에 대해서 설명한다.
Raspberry Pi 4 사용자 설정을 위한 커스텀 레이어
새로운 유저 애플리케이션을 구현 후 패키지화하여 이미지에 빌드시키기 위해 아래와 같은 커스텀 레이어(meta-custom)를 작성하였다. 본 레이어를 생성하고 구성하는 방법은 앞 8장에 작성되어 있으니 참고하길 바란다.
참고로 새 레이어를 생성하기 위해서는 아래와 같은 명령을 따른다.
source path/to/poky/oe-init-build-env build
# 새 레이어 생성
bitbake-layers create-layer path/to/poky/meta-custom
# 생성된 새 레이어를 빌드에 추가 (build/conf/bblayers.conf에 자동으로 레이어 경로가 등록됨)
bitbake-layers add-layer path/to/poky/meta-custom

레시피 파일이 저장된 각 디렉터리의 역할은 다음과 같다.
- recipes-applications
- 사용자 예제 애플리케이션(hello)을 이미지에 빌드시키기 위해 활용
- recipes-connectivity
- 와이파이 연결을 위한 설정 파일을 이미지에 빌드시키기 위해 활용
- 이미 앞 8장에서 다룬 내용
- recipes-core
- 유저 애플리케이션을 패키지 형태로 이미지에 빌드시키기 위해 활용
본 페이지에서는 recipes-applications에 들어가는 유저 애플리케이션(hello-app)을 구현하기 파일(C, Makefile)과 이를 빌드하기 위한 레시피 파일의 세부 내용을 어떻게 구성하면 되는지 다음 섹션부터 설명한다.
Raspberry Pi 4 유저 애플리케이션 구현
가장 먼저, Hello World가 출력되는 유저 애플리케이션을 구현하기 위해 아래 두 파일을 작성한다.
vi path/to/poky/meta-custom/recipes-applications/hello-app/files/hello-app.c
vi path/to/poky/meta-custom/recipes-applications/hello-app/files/Makefile
hello-app.c는 다음과 같은 내용으로 작성한다.
#include <stdio.h>
int main() {
printf(“Hello, pakji !!\n”);
return 0;
}
hello-app을 컴파일 할 Makefile은 다음과 같은 내용으로 작성한다.
TARGET = hello
SRCS = hello-app.c
all: $(TARGET)
$(TARGET): $(SRCS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(SRCS)
clean:
rm -f $(TARGET)
유저 애플리케이션 구현을 마쳤으면, 이제 이 애플리케이션을 위한 레시피를 작성하여서 패키지 형태로 이미지에 빌드되도록 해준다. 이 과정은 다음 섹션을 참조하면 된다.
Raspberry Pi 4 유저 애플리케이션 패키지 등록
유저 애플리케이션을 이미지에 빌드되도록 하기 위한 이미지 레시피(core-image-full-cmdline)의 IMAGE_INSTALL 변수에 hello-app 패키지를 등록한다.
vi path/to/poky/meta-custom/recipes-core/images/core-image-full-cmdline.bbappend
# core-image-full-cmdline.bbappend
IMAGE_INSTALL:append = " … hello-app"
패키지를 등록하였다면 이제 이 패키지를 빌드시키기 위한 레시피 파일을 작성해준다.
vi path/to/poky/meta-custom/recipes-applications/hello-app/hello-app.bb
# hello-app.bb
SUMMARY = "Hello example application"
LICENSE = "CLOSED"
SRC_URI += " \
file://hello-app.c \
file://Makefile \
"
S = "${WORKDIR}"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/hello ${D}${bindir}/hello
}
FILES:${PN} += "${bindir}/hello"
gcc나 make 명령을 실행시켜서 직접 컴파일이 가능하지만, 비트베이크의 빌드 시스템을 제대로 활용하기 위해선 제공하는 도구를 그대로 사용하는 것이 가장 적절하다. 왜냐하면, 빌드 시스템에서 관련 툴체인 등을 자동으로 불러와 사용할 수 있기 때문이다. 이를 위해 Makefile 등을 비트베이크에서 파싱할 수 있는 형태로 작성을 해주어야 한다. 그리고 Makefile의 경우에는 oe_runmake 명령문을 작성해서 간단하게 컴파일이 가능하다.
.bb 레시피는 패키지 빌드에 필요한 메타데이터를 정의하는 파일이다. 레시피의 do_install 단계에서 설치한 파일이 최종 패키지와 rootfs에 포함되려면, 해당 파일이 어떤 패키지에 포함될지 패키징 규칙에 의해 매핑되어야 한다. 기본 패키징 경로에 포함되지 않는 파일은 FILES:${PN} 등을 사용해 명시적으로 지정한다.
앞 8장에서는 새로운 패키지를 정의하는 .bb 레시피가 아니라, 기존 레시피를 확장하는 .bbappend 파일을 작성하였다. 따라서 원본 레시피에서 이미 정의된 패키징 설정을 그대로 사용할 수 있었고, 추가한 결과물이 기존 FILES 변수에 포함되는 경로에 설치되었기 때문에 별도로 FILES:${PN}을 작성하지 않았다.
Raspberry Pi 4 이미지 빌드 및 결과
유저 애플리케이션 구현과 레시피 파일의 작성을 마쳤다면, 이제 이미지 빌드를 수행하고 이에 대한 결과를 Raspberry Pi 4에서 확인한다.
source path/to/poky/oe-init-build-env build
bitbake core-image-full-cmdline

빌드가 정상적으로 완료되면, rootfs/usr/bin/ 경로에 유저 애플리케이션(hello)이 저장되어 있는 것을 확인할 수 있다.

이제 빌드가 완료된 이미지 파일(.wic.bz2)을 SD 카드에 구워준다. 이를 위해 다음 명령을 사용한다.
※ SD 카드는 fdisk 명령 등을 활용해 완전히 초기화된 상태로 사용하는 것을 권장한다.
cd path/to/poky/build/tmp/deploy/images/raspberrypi4/
bzcat core-image-full-cmdline-raspberrypi4.wic.bz2 | sudo dd of=/dev/sde
이미지 굽기가 끝났다며 이제 SD 카드를 Raspberry Pi 4에 꽂은 후 부팅한다. 부팅을 하게 되면 앞 8장 과정에서 진행하였던 와이파이 연결을 활용해 Raspberry Pi 4로 원격으로 접근한 뒤 hello 결과를 확인한다. 기본적으로 이미지에서 SSH 서버를 제공하고 있을 것이므로 IP 주소를 활용해 원격 접근하면 된다.
# powershell 등 터미널 프로그램 활용
ssh root@<ip_address>
원격 접근을 하였다면 이제 hello 명령을 실행시켜서 결과를 확인한다.

끝.
Yocto 학습을 끝마치며
임베디드 리눅스 개발자는 필요한 디바이스 드라이버를 직접 구현하고, 해당 드라이버를 활용하는 애플리케이션까지 함께 개발할 수 있어야 한다고 생각한다. 나아가 이를 빌드 시스템에 통합하여 최종적으로 이미지 형태로 배포할 수 있는 역량도 중요하다.
또한 애플리케이션 개발 과정에서 필요한 네트워크, 이미지, 오디오 등 특수 목적 라이브러리를 크로스 컴파일 환경에서 사용할 수 있도록 구성하고, 동적 라이브러리의 경우 타깃 이미지에 함께 포함되도록 배포 구조를 설계할 수 있어야 한다.
뿐만 아니라 특정 하드웨어 장치에 맞는 리눅스 BSP를 구성하는 능력도 필요하다. 즉, 부트로더, 커널, 디바이스 드라이버와 같은 저수준 소프트웨어 요소를 하드웨어 특성에 맞게 설정하고 빌드하여, 안정적으로 동작하는 임베디드 리눅스 시스템을 구축할 수 있어야 한다고 생각한다.
이번 Yocto 학습은 내가 앞으로 어떤 역량을 더 갖춰야 하는지 명확히 인식하게 해준 과정이었다. 지금까지는 주로 드라이버와 애플리케이션 개발 역량을 중심으로 학습해왔지만, 임베디드 리눅스 시스템을 실제 제품 수준으로 구성하기 위해서는 그보다 더 넓은 관점이 필요하다는 것을 알게 되었다. 드라이버와 애플리케이션을 빌드 시스템에 통합하고, 필요한 라이브러리를 크로스 컴파일 환경에 맞게 구성하며, 최종 이미지를 생성하고, 하드웨어에 맞는 BSP까지 다룰 수 있어야 비로소 하나의 완성된 임베디드 리눅스 시스템을 구축할 수 있다고 생각한다. 따라서 앞으로는 현재의 역량에 만족하지 않고 Yocto, BSP, 커널, 라이브러리 통합, 이미지 배포 과정까지 지속적으로 학습하며 더 깊이 있는 임베디드 리눅스 개발자로 성장해 나가야겠다.
'Linux > Yocto' 카테고리의 다른 글
| [Yocto 학습] 8장: Poky를 활용한 Raspberry Pi 4 와이파이 초기화 (0) | 2026.05.29 |
|---|---|
| [Yocto 학습] 7장: Poky를 활용한 Raspberry Pi 4 이미지 빌드 (0) | 2026.05.26 |
| [Yocto 학습] 6장: 레시피(*.bb, *.bbappend) 커스터마이징 방법 - 2 (0) | 2026.05.12 |
| [Yocto 학습] 5장: 레시피(*.bb, *.bbappend) 커스터마이징 방법 - 1 (0) | 2026.05.12 |
| [Yocto 학습] 4장: 레이어(meta-*) 생성 방법 (0) | 2026.05.10 |




