yoncho`s blog
10. Custom Image & BSP Layer | Poky기반 타깃 시스템 이미지와 BSP Layer 본문
10. Custom Image & BSP Layer | Poky기반 타깃 시스템 이미지와 BSP Layer
욘초 2024. 9. 21. 18:58
이번 학습에서는 타깃 시스템을 만들 수 있는 타깃 시트템 Image와 타깃 머신과 관련된 BSP Layer를 학습할 것이다.
학습을 통해 만들고자 하는 시스템은 great이라고 할 것이고 시스템 전체 구조는 아래와 같다.
위 구조에서 Custom Layer 中 배포 Layer와 BSP Layer 작업을 이번 학습에서 진행하겠다.
#목차
1. Custom Image Recipe 생성
2. BSP Layer
3. bitbake 문법
4. Custom BSP Layer 생성
5. 최종
[1] Custom Image Recipe 생성
앞 글에서 진행한 meta-great Layer에 추가 작업을 진행하겠다.
*meta-great Layer는 우리가 별도로 커스텀한 빌드 환경과 패키지 그룹화 등을 적용한 이미지 생성 레시피이다.
우리가 만들려는 meta-great Layer의 파일 구조는 아래와 같다.
meta-great/
|--classes/
| |--great-base-image.bbclass
|--conf/
| |--layer.conf
|--recipes-core/
| |--image/
| | |--core-image-minimal.bbappend
| | |--great-image.bb
| |--packagegroups/
| |--packagegroup-great.bb
|--template/
|--bblayer.conf.sample
|--conf-notes.txt
|--local.conf.sample
이미지 생성을 위한 정보와 추가 기능들이 정의된 패키지 그룹 레시피는 great-base-image.bbclass 클래스 파일에 추가되어있다. 여기에 추가된 패키지 그룹 내용은 Oe-Core에서 사전 정의된 것들이다.
커스텀 이미지 생성 레시피 파일은 great-image.bb 파일로 great-base-image.bbclass 클래스 파일을 상속 받는다.
이미지 생성 레시피는 어떤 패키지가 이미지에 설치되어야하는지 정의해야한다.
이미지 생성 관여하는 기반 클래스로 core-image.bbclass 클래스를 사용할 것이다. 이 클래스에서 IMAGE_INSTALL 변수를 관리하고 이 변수는 이미지에 rootfs에 설치할 패키지를 정의 할 때 사용한다.
#Custom Image 생성
I. meta-great/conf/ 디렉터리 아래 layer.conf 파일을 아래와 같이 작업한다.
BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes*/*/*.bb"
BBFILES += "${LAYERDIR}/recipes*/*/*.bbappend"
BBFILE_COLEECTIONS += "great"
BBFILE_PATTERN_great = "^${LAYERDIR}/"
BBFILE_PRIORITY_great = "11"
LAYERDEPENDS_great = "core"
LAYERSERIES_COMPAT_great = "${LAYERSERIES_COMPAT_core}"
여기선 LAYERDEPENDS_great 변수에 "core"라는 의존성 변수를 추가해줌으로써 great Layer는 core Layer에 의존성을 갖게된다. core Layer와의 의존성은 => Oe-Core와의 의존성이라 볼 수 있다.
core Layer를 추가한 이유는 콘솔로 부팅하는 rootfs을 생성할 때 필요한 변수들을 관리하는 core-image.bbclass를 사용해야 하기 때문이다.
II. meta-great/classes/ 디렉터리 아래 great-base-image.bbclass 파일을 생성하고 아래와 같이 작업한다.
inherit core-image
IMAGE_FSTYPES = " tar.bz2 ext4"
IMAGE_ROOTFS_SIZE = "10240"
IMAGE_ROOTFS_EXTRA_SPACE = "10240"
IMAGE_ROOTFS_ALIGNMENT = "1024"
CORE_IMAGE_BASE_INSTALL = "\
packagegroup-core-boot \
packagegroup-base-extended \
${CORE_IMAGE_EXTRA_INSTALL} \
"
IMAGE_FSTYPES : rootfs을 어떤 확장자로 생성할지 의미하며 'tar.bz2 ext4'의 경우 2개 rootfs이 생성되며 tar 압축 파일과 ext4 파일이 생성되게된다.
IMAGE_ROOTFS_SIZE : rootfs의 크기를 kb로 지정한다, 단 설치 중 크기를 초과할 경우 당연히 이 값은 증가한다.
기본값을 설정해놓는거라 생각하면 된다.
IMAGE_ROOTFS_EXTRA_SPACE : rootfs에 추가적인 빈 공간을 만들며, 단위는 kb이다.
IMAGE_ROOTFS_ALIGNMENT : rootfs 이미지 크기 값의 배수 설정,
III. meta-great/recipes-core/images/ 디렉터리 아래 great-image.bb 파일을 생성하고 아래와 같이 작업한다.
SUMMARY ="A very small image for yocto test"
inherit great-base-image
LINGUAS_KO_KR = "ko-kr"
LINGUAS_EN_US = "en-us"
IMAGE_LINGUAS = "${LINGUAS_KO_KR} ${LINGUAS_EN_US}"
IMAGE_INSTALL += "packagegroup-great"
IMAGE_OVERHEAD_FACTOR = "1.3"
great-image.bb 파일은 great-base-image.bbclass 클래스 파일을 상속 받는다.
한글/영어 지원을 위해 IMAGE_LINGUAS 변수를 사용했으며 IMAGE_INSTALL에는 앞서 작업한
패키지 그룹 레시피 파일을 추가했다.
IMAGE_OVERHEAD_FACTOR의 1.3 값은 1*(rootfs 크기) + 0.3*(rootfs 크기) => 1.3 * (rootfs 크기)를 뜻 한다.
즉, 최종 이미지를 생성할 때 rootfs의 크기에서 30% 여유 크기를 추가한다는 뜻이다.
IV. poky/meta-great/template/ 디렉터리 아래 conf-notes.txt 파일을 아래와 같이 작업한다.
### Shell environment set up for builds. ###
Welcome! this is my yocto example
You can now run 'bitbake <target>'
Common targets are:
great-image
You can also run generated qemu images with a command like 'runqemu qemux86'
YONCHO WORLD!
앞 글에서 만든 빌드 스크립트인 buildenv.sh 실행 시 출력되는 문구를 수정했다.
V. 새로 만들 이미지에 사용자 생성 및 그룹추가, meta-great/recipes-core/images 디렉터리 아래 great-image.bb 파일을 아래와 같이 작업한다.
SUMMARY ="A very small image for yocto test"
inherit great-base-image
LINGUAS_KO_KR = "ko-kr"
LINGUAS_EN_US = "en-us"
IMAGE_LINGUAS = "${LINGUAS_KO_KR} ${LINGUAS_EN_US}"
IMAGE_INSTALL += "packagegroup-great"
IMAGE_OVERHEAD_FACTOR = "1.3"
inherit extrausers
EXTRA_USERS_PARAMS = "\
groupadd greatgroup; \
useradd -p `openssl passwd 0416` great; \
useradd -g greatgroup great; \
"
extrausers.bbclass 클래스 파일에는 사용자 및 그룹을 추가하는 변수를 제공해준다. 제공해주는 변수 中EXTRA_USERS_PARAMS 변수는 그룹 계정을 생성하고 사용자 계정을 추가하며 암호 설정도 할 수 있다.
VI. meta-great/template/ 디렉터리 아래 local.conf.sample 파일에 아래와 같이 코드를 추가한다.
...
EXTRA_IMAGE_FEATURES += "splash"
앞 단계들을 통해 우리는 기본적인 기능을 가진 이미지 생성 작업을 마무리 했다.
현업에서는 더 많은 기능들과 설정들을 하게 된다..! 우리는 학습차원이므로 적은 기능들만 추가해놓은 것이다.
우리는 이번장에서 만든 이미지를 계속 발전시켜나가 학습할 것이다!
나중엔 그래도 나름 커져 있을 것이다 : )
VII. 작업 확인을 위해 build2/conf/ 디렉터리 삭제 및 재빌드
#conf 디렉터리 삭제
rm -rf build2/conf
#재빌드
source buildenv.sh
bitbake great-image
runqemu great-image nographic
VIII. 결과 확인
qemu 실행 시 login을 우리가 추가해준 user (great)와 password (0416)으로 진행한다.
성공적으로 user (great) 계정을 이용할 수 있음을 확인했고
user 계정으로 qemu 실행 시 poweroff는 su 명령어 수행 후 진행해야한다.
[2] BSP Layer
BSP는 Board Support Package의 약자로 장치(H/W) 구동에 필요한 OS, Driver등을 말하며
BSP에는 OS와 Driver를 메모리에 배치해주는 Bootlooader라는 프로그램도 포함한다.
어떻게 보면 H/W 구동과 관련된 low level과 관련된 Layer라 볼 수 있다!!
Yocto Project는 BSP Layer에서만 BSP 기능을 활용할 수 있는건 아니다.. Oe-Core나 특정 Layer에서도 BSP 기능을 지원하고있다. 하지만 영역을 분리해 관리하는건 관리적 측면과 기타 여러 사항을 고려했을 때 편리하기 때문에
H/W 관련 필요 기능 추가는 BSP Layer에서 진행하는게 올바른 방법이다.
Poky 소스 中 meta-yocto-bsp/ 디렉터리를 확인할 수 있다. 이 디렉터리가 Poky가 제공한 참조 BSP Layer이다.
BSP는 이것 뿐만 아닌 Oe-Core에서도 제공된다.
우리는 Oe-Core에서 제공하는 BSP Layer를 사용할 것이다.
=> 이유는 Oe-Core에서 제공하는 BSP Layer에는 특정 가상머신을 타깃으로한 BSP Layer가 존재한다.
우리는 qemux86-64를 사용하는데 이에 대한 참조 BSP Layer가 있다.
=> poky/meta/conf/machine/ 디렉터리 아래 qemux86-64.conf 파일이 Oe-Core에서 제공하는 QEMU BSP Layer이다.
#Oe-Core 참조 qemux86-64.conf BSP Layer 확인
I. qemux86-64.conf 파일 확인
PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg" -> (1)
PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"
require conf/machine/include/qemu.inc
DEFAULTTUNE ?= "core2-64" -> (2)
require conf/machine/include/tune-core2.inc
require conf/machine/include/qemuboot-x86.inc
UBOOT_MACHINE ?= "qemu-x86_64_defconfig"
KERNEL_IMAGETYPE = "bzImage" -> (3)
SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyS1" -> (4)
# Install swrast and glx if opengl is in DISTRO_FEATURES and x32 is not in use.
# This is because gallium swrast driver was found to crash X server on startup in qemu x32.
XSERVER = "xserver-xorg \
${@bb.utils.contains('DISTRO_FEATURES', 'opengl', \
bb.utils.contains('TUNE_FEATURES', 'mx32', '', 'mesa-driver-swrast xserver-xorg-extension-glx', d), '', d)} \
xf86-video-cirrus \
xf86-video-fbdev \
xf86-video-vmware \
xf86-video-modesetting \
xf86-video-vesa \
xserver-xorg-module-libint10 \
"
MACHINE_FEATURES += "x86 pci" -> (5)
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "v86d" -> (6)
MACHINE_EXTRA_RRECOMMENDS = "kernel-module-snd-ens1370 kernel-module-snd-rawmidi" -> (7)
WKS_FILE ?= "qemux86-directdisk.wks"
do_image_wic[depends] += "syslinux:do_populate_sysroot syslinux-native:do_populate_sysroot mtools-native:do_populate_sysroot dosfstools-native:do_populate_sysroot"
#For runqemu
QB_SYSTEM_NAME = "qemu-system-x86_64"
(1) 은 다중 패키지 中 어떤 패키지를 사용할지 결정한다.
(2) DEFAULTTUNE 변수는 build system에서 사용할 cpu 아키텍처와 ABI(App,OS 간 사용된 low level interface)를 선택한다.
(3) KERNEL_IMAGETYPE 변수는 kernel image file의 명명 체계를 지정, 최종 빌드 시 커널 이미지 파일을 link한 변수로 사용된다.
(4) SERIAL_CONSOLES 변수는 getty(get tty 줄임, 호스트 PC에서 실행되며, 연결 시 login 과정 실행)를 사용할 수 있게 serial console (tty)를 정의한다. 장치 이름 앞에 전송 속도가 지정되며 콜론(:)으로 tty 장치 구분
(5) MACHINE_FEATURES 변수는 장치에서 지원하는 H/W 관련 기능(Feature)들 정의한다.
Ex) MACHINE_FEATURES = "bluetooth screen ... " => bluetooth 기능 지원!
+ 보드에서 지원하는 H/W 기능 정의
+ 포함 / 제외 시킬 패키지 정의
+ 머신 환경 설정 파일에 이 변수 값 할당
(6) MACHINE_ESSENTIAL_EXTRA_RDEPENDS 변수는 이미지 빌드 중 일부로 타깃 머신에 설치해야할 필수 패키지 목록을 가진다. 변수에 할당된 패키지들은 부팅 시 필수 요소들로 구성되어있다.
+ packagegroup-core-boot.bb 패키지 그룹을 기반으로하는 core-image-minimal과 같은 이미지에만 영향을 줌
+ packagegroup-base.bb 패키지 그룹을 기반으로 하는 이미지 생성 시 MACHINE_EXTRA_RDEPENDS 변수에 정의해야함. 단, 이 변수는 부팅시 필수적 패키지가 아님
(7) MACHINE_EXTRA_RRECOMMENDS 변수는 이미지 빌드 중 일부로 타깃 머신에 설치해야할 필수 패키지 목록을 가진다. 하지만 (6)변수와 다른 점은 부팅시 필수적이진 않다는 것이다.
하지만 더 많은 기능을 가진 이미지 생성을 위해 이 변수에 추가 패키지들을 정의해놓아야 하며 빌드에는 영향을 주지 않지만 주로 커널에 컴파일되서 들어가 있는 커널 모듈에 많이 사용된다.
+ packagegroup-base.bb 패키지 그룹을 기반으로 하는 이미지 생성 시 영향을 준다.
+ packagegroup-core-boot.bb 패키지 그룹을 기반으로 하는 이미지의 경우 MACHINE_ESSENTIAL_EXTRA_RECOMMENDS 변수에 정의해야한다.
II. qemux86-64.conf 파일 내용 中 qemu.inc 인클루드 파일 확인
PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
PREFERRED_PROVIDER_virtual/egl ?= "mesa"
PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"
XSERVER ?= "xserver-xorg \
${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'mesa-driver-swrast xserver-xorg-extension-glx', '', d)} \
xf86-video-fbdev \
"
MACHINE_FEATURES = "alsa bluetooth usbgadget screen vfat"
MACHINEOVERRIDES =. "qemuall:" -> (1)
IMAGE_FSTYPES += "tar.bz2 ext4" -> (2)
# Don't include kernels in standard images
RDEPENDS_${KERNEL_PACKAGE_NAME}-base = ""
# Use a common kernel recipe for all QEMU machines
PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto" -> (3)
EXTRA_IMAGEDEPENDS += "qemu-system-native qemu-helper-native" -> (4)
# Provide the nfs server kernel module for all qemu images
KERNEL_FEATURES_append_pn-linux-yocto = " features/nfsd/nfsd-enable.scc" -> (5)
KERNEL_FEATURES_append_pn-linux-yocto-rt = " features/nfsd/nfsd-enable.scc"
IMAGE_CLASSES += "qemuboot"
(파일 위치 : /home/yoncho/poky_src/poky/meta/conf/machine/include/qemu.inc)
(1) MACHINEOVERRIDES 변수에 대해 알려면 OVERRIDES 문법을 알아야해서 추후 설명 하겠다.
(2) IMAGE_FSTYPES : 변수는 최종 생성될 이미지의 타입을 알려준 변수다. 'tar.bz2 ext4'는 tar 압축 파일과 ext4 파일 형태의 rootfs을 만들겠단 소리다.
(3) 은 다중 PROVIDES가 존재할 때 어떤 PROVIDES를 선택할지 결정한다. 선택된 레시피 파일 이름이 할당된다.
=> 위 내용에선 linux-yocto.bb 레시피 파일에서 만들어진 커널을 사용한다.
(4) EXTRA_IMAGEDEPENDS 변수는 최종 이미지 rootfs을 구성하기 위한 패키지 목록이 아니라 네이티브. 즉, 호스프 환경에서 필요한 패키지를 생성하는 레시피를 정의해 놓은 것이다.
=> Bootloader 같은 rootfs에는 포함 안되지만 H/W level에 꼭 필요하기 때문에 이 변수에 할당한다.
(5) KERNEL_FEATURES 변수에는 Advanced된 metadata로부터 제공 받은 커널 환경 설정 정보나 패치 등이 포함된다.
머신 환경 설정 파일들은 깊게 배울 필요는 없다.. 대부분 칩 밴더에서 칩과 함께 같이 배포되며
세상에는 너무 많은 H/W가 존재하고 아키텍처가 존재해서.. 내용이 자주 바뀐다.
[3] bitbake 문법
조건부 변수 할당에 대해 알아보겠다.. 꽤 중요하며 우선순위 부여와 존재여부로 값이 변하게된다..!
I. OVERRIDES - 조건부 변수 사용 형태
OVERRIDES = "A:B:C"
위 콜론(:)기준으로 A, B, C가 존재한다. 이 변수에서 우선순위는 C => B => A 순이다.
C가 제일 높고 A가 제일 낮다.
II. 조건부 변수 사용 예제
OVERRIDES = "korea:japan:usa"
FOOD_korea = "rice"
FOOD_japan = "sushi"
FOOD_china = "..."
CLOTHES = "kilt"
CLOTHES_korea = "hanbok"
FOOD 변수 뒤 언더스코어(_)와 조건에 따라 FOOD 변수에 조건부로 값을 할당한다.
FOOD 변수의 경우 OVERRIDES에 정의된 순서를 적용하면 FOOD_korea보다 FOOD_japan이 우선순위가 높아 FOOD에는 FOOD_japan 값이 들어간다. FOOD_usa가 없기 때문에 적용 안되고 FOOD_china의 경우 조건부변수에 정의되어있지 않기 때문에 실행되지 않는다.
CLOTHES의 경우 기본 변수 값이 설정되어있지만 조건부변수가 CLOTHES_korea가 존재함으로 CLOTHES 변수는 최종적으로 "hanbok" 값을 갖게 된다.
III. 특정 변수에 조건부 변수 값 할당
OVERRIDES = "a:b"
VARIABLE_a = "test_a"
VARIABLE_b = "test_b"
어떤 변수든 조건부 변수를 할당하려면 언더스코어(_) 뒤에 조건부 변수를 넣고 값을 할당하면 된다.
조건부 변수가 어떻게 쓰였는지 core-image-minimal.bb 레시피에 할당된 OVERRIDES 조건부 변수를 확인해보면
(확인 명령어 : bitbake-getvar -r core-image-minimal OVERRIDES)
qemu.inc 인클루드가 관리하는 MACHINEOVERRIDES 변수가 조건부 변수 OVERRIDES에 할당되어있다.
MACHINEOVERRIDES 변수는 bitbake.conf 파일에서 MACHINE 변수의 값이 할당된다.
그리고 MACHINE 변수는 local.conf 파일에서 할당된다.
local.conf) MACHINE = "qemux86-64"
v
bitbake.conf) MACHINEOVERRIDES = ${MACHINE}
v
bitbake.conf) OVERRIDES = ${MACHINEOVERRIDES}
MACHINE 변수에는 사용하고자 하는 타깃 머신에 대한 값을 넣는다.
세상에는 다양한 H/W가 존재하기 때문에 이 MACHINE 변수 값 할당에 대해선 매우 중요하고 필수적이다.
IV. 조건부 변수 버전에 따른 사용법
우리는 bitbake dunfell 버전을 사용 중이지만 이후 honister 버전 이상 부터는 아래와 같이 사용된다.
#공통
OVERRIDES = "A:B"
#dunfell 사용시
VAR_A = "AAA"
VAR_B = "BBB"
VAR_append_C = "CCC"
#honister 이상 버전 사용시
VAR:A = "AAA"
VAR:B = "BBB"
VAR:append:C = "CCC"
[4] Custom BSP Layer 생성
이제 Custom BSP Layer를 만들어보자. 우리는 great이고 이름지어주고
고유 타깃 머신 환경 설정을 제공해보자.
막 큰 작업은 아니다... 우린 qemu를 사용하기 때문에 Poky에서 제공해주는 qemu 머신 관련 설정을 그대로 사용하고 BSP Layer에 포함된 커널 레시피를 수정하는 정도로 진행하겠다.
=> 커널 부분을 수정해보는 수준!!
#Custom BSP Layer 생성
I. meta-great-bsp Layer를 생성하고 아래와 같은 파일 구조를 가진다.
#meta-great-bsp Layer 생성
poky/meta-great-bsp
#meta-great-bsp 파일 구조
meta-great-bsp/
|--conf/
|--layer.conf
|--machine/
|--great.conf
II. 새로만든 BSP Layer를 bitbake가 인식할 수 있게 meta-great/template/ 디렉터리 아래 bblayers.conf.sample 파일을 아래와 같이 작업한다.
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
##OEROOT##/meta \
##OEROOT##/meta-poky \
##OEROOT##/meta-yocto-bsp \
##OEROOT##/meta-hello \
##OEROOT##/meta-great \
##OEROOT##/meta-great-bsp \
"
방금 만든 meta-great-bsp Layer를 추가했다.
III. 수정한 bblayers.conf.sample을 빌드 환경에 적용 시키기 ( conf/ 디렉터리 삭제 및 재빌드 )
#build/conf/ 디렉터리 삭제
rm -rf build/conf
#재빌드
source buildenv.sh
IV. meta-great-bsp/conf/ 디렉터리 아래 layer.conf 파일을 생성하고 아래와 같이 작업한다.
BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes*/*/*.bb"
BBFILES += "${LAYERDIR}/recipes*/*/*.bbappend"
BBFILE_COLEECTIONS += "greatbsp"
BBFILE_PATTERN_greatbsp = "^${LAYERDIR}/"
BBFILE_PRIORITY_greatbsp = "6"
LAYERSERIES_COMPAT_greatbsp = "${LAYERSERIES_COMPAT_core}"
V. meta-great-bsp/conf/ 디렉터리 아래 machine/ 디렉터리 생성 후 그 아래 great.conf 파일 생성하고 아래와 같이 작업한다.
#meta-great-bsp/conf/machine/ 디렉터리 생성
mkdir machine
#great.conf 파일 작업
vi great.conf
--- great.conf 내용 ---
PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"
require conf/machine/include/qemu.inc -> (1)
DEFAULTTUNE ?= "core2-64"
require conf/machine/include/tune-core2.inc
require conf/machine/include/qemuboot-x86.inc
UBOOT_MACHINE ?= "qemu-x86_64_defconfig"
KERNEL_IMAGETYPE = "bzImage"
SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyS1"
# Install swrast and glx if opengl is in DISTRO_FEATURES and x32 is not in use.
# This is because gallium swrast driver was found to crash X server on startup in qemu x32.
XSERVER = "xserver-xorg \
${@bb.utils.contains('DISTRO_FEATURES', 'opengl', \
bb.utils.contains('TUNE_FEATURES', 'mx32', '', 'mesa-driver-swrast xserver-xorg-extension-glx', d), '', d)} \
xf86-video-cirrus \
xf86-video-fbdev \
xf86-video-vmware \
xf86-video-modesetting \
xf86-video-vesa \
xserver-xorg-module-libint10 \
"
MACHINEOVERRIDES =. ":great:" -> (2)
MACHINE_FEATURES += "x86 pci"
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "v86d"
MACHINE_EXTRA_RRECOMMENDS = "kernel-module-snd-ens1370 kernel-module-snd-rawmidi"
WKS_FILE ?= "qemux86-directdisk.wks"
do_image_wic[depends] += "syslinux:do_populate_sysroot syslinux-native:do_populate_sysroot mtools-native:do_populate_sysroot dosfstools-native:do_populate_sysroot"
#For runqemu
QB_SYSTEM_NAME = "qemu-system-x86_64"
위 코드는 Poky가 제공해준 qemux86-64.conf 파일 (파일 위치 : poky_src/poky/meta/conf/machine/qemux86-64.conf) 내용을 복사해온 뒤 (2) 부분을 추가해주었다.
(2) MACHINEOVERRIDES변수에 "great"이라는 머신 이름을 넣은 것만 다르다.
=> 조건부 변수에 포함된다..!
**meta-great-bsp 전체 구성은 아래와 같다.
meta-great-bsp/
|--conf/
| |--layer.conf
| |--machine/
| |--great.conf
|--recipes-kernel/
|--linux/
|--file
|--linux-yocto_5.4.bbappend
위 구조를 보면 qemu.inc 파일이 존재하지 않음을 알 수 있다..!!
bitbake는 자신이 인지한 모든 Layer에서 conf/ 디렉터리 아래 machine/include/qemu.inc 와 같은 구조의 디렉터리 와 파일을 찾게 된다. 따라서 (1) 내용 처럼 기술하면
poky/meta/conf/machine/include/ 디렉터리 아래 있는 qemu.inc 파일을 가져온다.
bitbake는 인클루드 파일을 다른 metadata 파일들과 공유한다.
공유할 때 사용하는 지시어는 inherit과 require가 있는데 차이는 아래와 같다.
inherit은 지정한 인클루드 파일이 없으면 빌드시 에러를 발생시키지 않는다.
require는 지정한 인클루드 파일이 없으면 빌드시 에러를 발생시킨다.
+ 추가적으로
레시피와 클래스 파일은 실행 가능한 메타데이터와 환결설정 등을 갖는 파일을 인클루드 할 수 있다.
하지만 !!! 환경설정파일(.conf)은 실행 가능한 메타데이터를 지원하지 않는다..!
그래서 실행 가능한 메타데이터가 없는 파일만 인클루드 할 수 있다
=> 머신 환경 설정파일인 great.conf 파일이 실행 가능한 메타데이터가 없는 파일만 인클루드 할 수 있다!
특히, 파일을 인클루드할 때 주의할 점은 순환 오류이다.
a.inc / b.inc 인클루드 파일이 만약 서로를 참조하고 인클루드 한다면 순환 오류가 발생한다.
이때 bitbake는 'RecursionError : maximum recursion ... ' 와 같은 error 메시지와 함께 실행을 종료한다.
VI. 타깃 머신에 사용될 Kernel 정의, meta-great-bsp/recipes-kernel/linux/ 디렉터리 아래 linux-yocto_5.4.bbappend 파일을 생성하고 아래와 같이 작업한다.
우리는 Yocto에서 제공한 리눅스 커널과 호환되게 몇가지 변수를 수정해야한다.
그리고 앞서 진행했듯 수정된 내용을 적용하기 위해 레시피 확장 파일(.bbappend)을 만들어야한다.
KBRANCH_great = "v5.4/standard/base"
KMACHINE_great = "qemux86-64"
//SRCREV_machine_great = "35826e154ee014bc64ccfa0d1f12d36b8f8a75929"
COMPATIBLE_MACHINE_great = "great"
LINUX_VERSION_great = "5.4.273"
참고 : //SRCREV.. 내용은 본 교재에서 상세 설명되어있지 않아... 모르겠어서 주석했다.
필자의 경우 환경에서 LINUX_VERSION_great이 교재에는 5.4.219로 되어있지만 error 발생해서 5.4.273으로 진행했다.
위 코드 내용을 보면 변수이름 뒤에 언더스코어(_)를 붙이고 MACHINE 이름(great)을 붙였다.
=> 조건부 변수에 great이 포함되었을 경우 이변수들이 유효하다는 뜻이다.
COMPATIBLE_MACHINE : 변수는 현재 사용중인 커널과 호환되는 머신의 이름이 할당된다. 앞서 great이라고 머신 이름을 지어줬기 때문에 great을 할당해준다.
LINUX_VERSION : 변수는 사용하려는 커널 버전을 기록해준다.
SRCREV : 변수는 커널 소스의 리비전을 가리킨다. git commit hash 값을 가진다..
KMACHINE : 변수는 커널 메타데이터로 불리며, yocto-kernel-cache git repository에 저장된 데이터에서 현재 커널과 매칭된 데이터를 찾는다. 원래는 머신 이름 great을 입력해야하지만 나중에 상세 설명하겠다. Yocto에서 기본제공하는 qemu 머신과 커널 소스를 그대로 사용할 것이기에 qemux86-64 값을 할당했다.
KBRANCH : 변수는 KMACHINE과 마찬가지로 커널 메타데이터와 연관되어있다. yocto-kernel-cache git repository 브랜치 명이라 생각하면 된다.
VII. 새로 생성한 머신 환경 설정 파일 (great.conf)을 bitbake가 인식하려면 MACHINE 변수 값에 머신 이름을 할당해놓아야한다. poky_src/ 디렉터리 아래 이전 글에서 만들어놓은 빌드 환경 구축 스크립트 buildenv.sh 파일을 아래와 같이 작업한다.
function find_top_dir()
{
local TOPDIR=poky
#move into script file path
cd $(dirname ${BASH_SOURCE[0]})
if [ -d $TOPDIR ]; then
echo $(pwd)
else
while [ ! -d $TOPDIR ] && [ $(pwd) != "/" ];
do
cd ..
done
if [ -d $TOPDIR ]; then
echo $(pwd)
else
echo "/dev/null"
fi
fi
}
ROOT=$(find_top_dir)
export TEMPLATECONF=${ROOT}/poky/meta-great/template/
export MACHINE="great"
function build_target(){
source poky/oe-init-build-env build2
}
build_target
MASHINE 변수에 great 값을 할당했다.
VIII. 최종 확인 ( build2/conf/ 디렉터리 삭제 및 재빌드 )
#build2/conf/ 삭제
rm -rf build2/conf
#재빌드
source buildenv.sh
bitbake great-image
위 재빌드 시 Log를 보면 MACHINE에 great 값이 표시되어있을 것이다.
그리고 아래와 같이 qemu 실행 결과를 확인할 수 있다.
#qemu 실행 명령어
runqemu great-image nographic
#qemu 로그 중
yoncho@Desktop_yoncho:~/poky_src$ runqemu great-image nographic
runqemu - INFO - Running MACHINE=great bitbake -e ...
runqemu - INFO - Continuing with the following parameters:
KERNEL: [/home/yoncho/poky_src/build2/tmp/deploy/images/great/bzImage]
MACHINE: [great]
FSTYPE: [ext4]
ROOTFS: [/home/yoncho/poky_src/build2/tmp/deploy/images/great/great-image-great.ext4]
CONFFILE: [/home/yoncho/poky_src/build2/tmp/deploy/images/great/great-image-great.qemuboot.conf]
우리는 오늘 학습을 통해 이미지를 생성하는 레시피를 만들었고 BSP Layer를 통해 타깃 머신에 대한 환경 정보를 설정할 수 있게 되었다.
[5] 최종
이미지 생성 레시피는 계층형 아키텍처 (맨 윗 글 사진) 상 최상위에 위치하는 레시피 중 하나이다.
이미지 생성 레시피의 최종 산출물은 rootfs이다.
=> 이미지 레시피는 어떻게 rootfs을 만들지 정의한 레시피라 볼 수 있다.
Poky가 기본 제공하는 이미지 레시피들이 존재하는 그 경로와 파일은
'meta*/recipes*/images*/*.bb' 이다.
그리고 이렇게 만든 이미지 생성 레시피는 BSP Layer와 함께 사용되는데.
H/W 제어 내용을 포함하는 BSP는 레이어의 conf/디렉터리 아래 machine/ 디렉터리가 존재하는데 그 아래 보면 머신 환경 설정 파일들이 존재한다..!!
MACHINE 변수값에 할당된 머신 이름 뒤에 .conf 를 붙이면 머신 환경 설정파일로 인식된다..!!
여기서 MACHINE 변수는 local.conf 또는 빌드 스크립트 파일에서 제공된다..
지금까지 진행하면서 타깃 머신에 구축할 환경과 이미지 생성을 해보았다.
어떻게 돌아가는지 감이 잡히고 있으며, 추후 시간이 있다면 환경 설정 파일 내용들을 하나하나 분석해보고싶다.
'기술, 나의 공부를 공유합니다. > [Vehicle] Yocto' 카테고리의 다른 글
9. Package Group & Build Env. | 패키지 그룹과 빌드 환경 구축 (0) | 2024.06.28 |
---|---|
8. Depends | 의존성 (0) | 2024.06.27 |
7. Build Optimization | Autotools, Build History, rm-work, externalsrc (0) | 2024.06.26 |
6. Systemd | 초기화 관리자 추가 및 로그 파일 디버깅 (0) | 2024.06.24 |
5. Custom Layer | 레이어 생성을 위해 필요한 과정 (1) | 2024.06.23 |